ASP.NET 核心 2.0 身份验证不工作

ASP.NET Core 2.0 Authentication NOT Working

我正在尝试在我的 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<TUser, TRole> 的源代码并省略了与角色相关的内容,所以这里应该没有问题,但也许...

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 中一样添加授权过滤器,但我似乎无法在全局范围内这样做。当我将它应用到默认控制器时,出现以下异常:

No authenticationScheme was specified, and there was no DefaultChallengeScheme found.

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

我遇到了和你一样的问题。我必须基于 FormsAuthentication cookie 实现自定义身份验证,这在 .net 核心中不存在,我们有一些使用 FormsAuthentication 的 ASP.Net 系统,我们需要互操作。我解决它的方法是继承 AuthorizeFilter 然后 override OnAuthorizationAsync(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.csConfigureServices 中注册,即

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

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

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

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

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