简体   繁体   English

ASP.NET Core 2.0身份验证不起作用

[英]ASP.NET Core 2.0 Authentication NOT Working

I'm trying to implement authentication using Identity into my ASP.NET Core 2.0 project and it doesn't seem to be working. 我正在尝试在我的ASP.NET Core 2.0项目中使用身份验证来实现身份验证,但似乎无法正常工作。 The last project I implement Identity into was an ASP.NET MVC 5 project, and things have changed substantially. 我将身份实现到的最后一个项目是ASP.NET MVC 5项目,事情发生了很大变化。 I've skipped Core 1.0 and 1.1, so I have no knowledge of how it was done under those, though from what I'm reading it's supposed to be mostly similar. 我已经跳过了Core 1.0和1.1,所以我不知道在这些内核下它是如何完成的,尽管从我所阅读的内容来看,它应该与大多数相似。

I can't get it work for me though. 我不能让它对我有用。 When I say it's not working, I mean that I'm not being redirected to a login page even though I'm not authorized. 当我说它不起作用时,我的意思是即使我未被授权,也不会被重定向到登录页面。

The only customization I've done is to implement my own user store and my own extension to add identity without the need for a role, since I'm not going to be using roles. 我唯一要做的自定义是实现我自己的用户存储和自己的扩展以添加身份而不需要角色,因为我不会使用角色。 I could use some direction on what I'm messing up because from my point of view everything is now way too complicated. 我可以对我要弄乱的东西使用一些方向,因为从我的角度来看,现在一切都太复杂了。 Here's the code I've got so far: 这是到目前为止我得到的代码:

Startup.cs 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 ServiceCollectionExtensions.cs

I just looked at the source for the built in AddIdentity<TUser, TRole> and omitted the role related stuff, so there shouldn't be an issue with it here, though maybe... 我只是查看了内置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);
    }
}

I thought I had to add the Authorize filter like in MVC 5, but I can't seem to do it globally. 我以为我必须像在MVC 5中一样添加Authorize过滤器,但是我似乎无法在全球范围内这样做。 When I apply it to the default controller, I get the following exception: 将其应用于默认控制器时,会出现以下异常:

No authenticationScheme was specified, and there was no DefaultChallengeScheme found. 没有指定authenticationScheme,也没有找到DefaultChallengeScheme。

But I thought I was setting the scheme in my custom AddIdentity method? 但是我以为是在自定义的AddIdentity方法中设置方案? I could use some guidance and I appreciate any being sent my way. 我可以使用一些指导,对于任何发送给我的方式,我都表示感谢。

I figured it out, and it was me overlooking something when I was making my own AddIdentity extension. 我想通了,在制作自己的AddIdentity扩展时就是忽略了某些东西。 I was supposed to pass in the IdentityConstants.ApplicationScheme as a parameter to AddCookie before passing in the options. 我应该传递选项之前IdentityConstants.ApplicationScheme作为参数传递给AddCookie I was double checking the Identity source and saw I was missing that. 我仔细检查了身份来源,发现我错过了。 As soon as I added it, everything worked. 一旦添加它,一切就正常了。 So: 所以:

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

This was ultimately a problem of my own making... 最终这是我自己造成的问题。

I had the same issue as you. 我和你有同样的问题。 I had to implement custom auth based on FormsAuthentication cookie, which does not exist in .net core, we have some ASP.Net systems that use FormsAuthentication and we need interop. 我必须基于FormsAuthentication cookie实现自定义身份验证,而.net核心中不存在该cookie,我们有一些使用FormsAuthentication ASP.Net系统,并且需要互操作。 The way that I solved it was to subclass AuthorizeFilter and then override OnAuthorizationAsync(AuthorizationFilterContext context) . 我解决该问题的方法是将AuthorizeFilter子类化,然后override OnAuthorizationAsync(AuthorizationFilterContext context) This is what I cam up with: 这就是我的想法:

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);
    }

}

Then you have to go register that in Startup.cs in ConfigureServices ie 然后,您必须在ConfigureServices Startup.cs中注册它,即

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

This will be default make ALL your Controllers need authorization. 这将是默认设置,使您的所有控制器都需要授权。 If you need anonymous login, go add [AllowAnonymous] to your Controller 如果您需要匿名登录,请在您的控制器中添加[AllowAnonymous]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM