Search code examples
c#asp.netasp.net-coreasp.net-identityasp.net-core-identity

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. The last project I implement Identity into was an ASP.NET MVC 5 project, and things have changed substantially. 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.

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

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

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...

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. When I apply it to the default controller, I get the following exception:

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

But I thought I was setting the scheme in my custom AddIdentity method? I could use some guidance and I appreciate any being sent my way.


Solution

  • I figured it out, and it was me overlooking something when I was making my own AddIdentity extension. I was supposed to pass in the IdentityConstants.ApplicationScheme as a parameter to AddCookie before passing in the options. 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...