【问题标题】:ASP.NET Core 2.0 Authentication NOT WorkingASP.NET Core 2.0 身份验证不起作用
【发布时间】:2017-11-09 00:30:34
【问题描述】:

我正在尝试在我的 ASP.NET Core 2.0 项目中使用 Identity 实现身份验证,但它似乎不起作用。我实现 Identity 的最后一个项目是 ASP.NET MVC 5 项目,情况发生了很大变化。我跳过了 Core 1.0 和 1.1,所以我不知道它是如何在这些下完成的,尽管从我所读的内容来看,它应该大多相似。

但我无法让它为我工作。当我说它不起作用时,我的意思是即使我没有被授权,我也没有被重定向到登录页面。

我所做的唯一定制是实现我自己的用户存储和我自己的扩展来添加身份而不需要角色,因为我不会使用角色。我可以对我搞砸的事情使用一些方向,因为从我的角度来看,现在一切都太复杂了。这是我目前得到的代码:

Startup.cs

public void ConfigureServices(
    IServiceCollection services) {
    services.AddDbContext<CustomDbContext>();
    services.AddTransient<IUserStore<GlobalUser>, CustomUserStore<GlobalUser>>();
    services.AddIdentity<GlobalUser>();
    services.AddMvc();
}

public void Configure(
    IApplicationBuilder app,
    IHostingEnvironment env) {
    if (env.IsDevelopment()) {
        app.UseDeveloperExceptionPage();
    } else {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseStaticFiles();
    app.UseAuthentication();
    app.UseMvc();
}

ServiceCollectionExtensions.cs

我只是查看了内置 AddIdentity&lt;TUser, TRole&gt; 的源代码并省略了与角色相关的内容,所以这里应该没有问题,尽管可能......

public static class ServiceCollectionExtensions {
    public static IdentityBuilder AddIdentity<TUser>(
        this IServiceCollection services,
        Action<IdentityOptions> optionsAction = null)
        where TUser : class {
        services.AddAuthentication(
            o => {
                o.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
                o.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
                o.DefaultSignInScheme = IdentityConstants.ApplicationScheme;
            }).AddCookie(
            o => {
                o.LoginPath = new PathString("/Login");
                o.Events = new CookieAuthenticationEvents {
                    OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync
                };
            });

        services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
        services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
        services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();
        services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();
        services.TryAddScoped<IdentityErrorDescriber>();
        services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();
        services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser>>();
        services.TryAddScoped<UserManager<TUser>, AspNetUserManager<TUser>>();
        services.TryAddScoped<SignInManager<TUser>, SignInManager<TUser>>();

        if (optionsAction != null) {
            services.Configure(optionsAction);
        }

        return new IdentityBuilder(typeof(TUser), services);
    }
}

我以为我必须像在 MVC 5 中一样添加授权过滤器,但我似乎无法在全局范围内这样做。当我将它应用到默认控制器时,我得到以下异常:

没有指定 authenticationScheme,也没有 找到了 DefaultChallengeScheme。

但我以为我是在自定义 AddIdentity 方法中设置方案?我可以使用一些指导,我很感激任何被发送到我的方式。

【问题讨论】:

  • 您是否将方案作为控制器中 Authorize 属性的一部分传入?像这样:[Authorize(AuthenticationSchemes = IdentityConstants.ApplicationScheme)],或者类似的东西?我不知道IdentityConstants.ApplicationScheme 是不是你需要的枚举。
  • 所以,我按照您的建议将“Identity.Application”硬编码为方案,现在异常更改为No authentication handler is configured to authenticate for the scheme: Identity.Application。我很难接受这些计划。告诉 ASP.NET 我想要使用 Identity 进行 cookie 身份验证的正确方法是什么?

标签: c# asp.net asp.net-core asp.net-identity asp.net-core-identity


【解决方案1】:

我想通了,是我在制作自己的 AddIdentity 扩展时忽略了一些东西。我应该将IdentityConstants.ApplicationScheme 作为参数传递给AddCookie 传递选项之前。我仔细检查了身份来源,发现我错过了。我添加后,一切正常。所以:

//           ▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼ this is what was missing
}).AddCookie(IdentityConstants.ApplicationScheme,
o => {

这最终是我自己制造的问题......

【讨论】:

    【解决方案2】:

    我和你有同样的问题。我必须基于FormsAuthentication cookie 实现自定义身份验证,这在.net 核心中不存在,我们有一些使用FormsAuthentication 的ASP.Net 系统,我们需要互操作。我解决它的方法是子类AuthorizeFilter,然后是overrideOnAuthorizationAsync(AuthorizationFilterContext context)。这是我想出来的:

    public class AuthFilter : AuthorizeFilter
    {
    
        public override Task OnAuthorizationAsync(AuthorizationFilterContext context)
        {
            if (context.Filters.Any(item => item is IAsyncAuthorizationFilter && item != this || item is IAllowAnonymousFilter))
            {
                return Task.FromResult(0);
            }
    
            if (!context.HttpContext.User.Identity.IsAuthenticated)
            {
                context.Result = new UnauthorizedResult();
                return Task.FromResult(0);
            }
    
            return base.OnAuthorizationAsync(context);
        }
    
    }
    

    然后您必须在Startup.cs 中注册ConfigureServices

    services.AddMvc(options =>
    {
        options.Filters.Add(new AuthFilter(
            new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build()));
    });
    

    这将默认使您的所有控制器都需要授权。如果您需要匿名登录,请添加 [AllowAnonymous] 到您的控制器

    【讨论】:

    • 由于我的所有控制器都继承自 ControllerBase 类,因此我已将属性应用到它,但它现在抛出了其他关于未找到该方案的注册处理程序的异常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-21
    • 2018-06-23
    • 2018-01-30
    • 2023-04-11
    • 1970-01-01
    • 2018-01-24
    • 2018-08-15
    相关资源
    最近更新 更多