Aspnetcore.docs: No authentication handler is registered for the scheme 'Identity.Application'.

Created on 26 Jun 2019  Â·  21Comments  Â·  Source: dotnet/AspNetCore.Docs

The second box of code showing 2.0 setup doesn't work. I have used this which isn't exactly as per the sample, since I don't use EF and does use roles, so I would imagine this would work having read this page, but it doesn't. In fact, I have spent more than 2 weeks without successfully getting OAuth working. There's something really wrong with the documentation or the API design.

Note that I am using AddIdentityCore because there is no AddIdentity taking just the single <TUser> and also note that I had to add a DI container registration for my user store to silence an error activating that.

// My code which gives error in title

        services.AddIdentityCore&lt;MyUser&gt;();

        // If you want to tweak Identity cookies, they're no longer part of IdentityOptions.
        services.ConfigureApplicationCookie(options =&gt; options.LoginPath = "/Account/LogIn");
        services.AddAuthentication()
                .AddFacebook(options =&gt;
                {
                    options.AppId = Configuration["auth:facebook:appid"];
                    options.AppSecret = Configuration["auth:facebook:appsecret"];
                });

Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Source - Docs.ms

Most helpful comment

It's really no hassle. I'm pleased to be able to help and especially pleased that you've got it working. I'm sure you will finally sleep well tonight. :)

All 21 comments

does use roles => don't use roles

The error appears with this stack.

System.InvalidOperationException: No authentication handler is registered for the scheme 'Identity.Application'. The registered schemes are: Facebook. Did you forget to call AddAuthentication().Add[SomeAuthHandler]("Identity.Application",...)?
   at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
   at Microsoft.AspNetCore.Authorization.Policy.PolicyEvaluator.AuthenticateAsync(AuthorizationPolicy policy, HttpContext context)
   at Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter.OnAuthorizationAsync(AuthorizationFilterContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
   at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
dbug: Microsoft.AspNetCore.Server.Kestrel[9]

Gah! Its my fault, I found I left code for an authorization policy for IdentityConstants.ApplicationScheme.

Actually I can get similar code using Google to fail with

System.InvalidOperationException: No authenticationScheme was specified, and there was no DefaultSignInScheme found

Using this.

        services.AddIdentityCore<TimesheetsUser>();

        // If you want to tweak Identity cookies, they're no longer part of IdentityOptions.
        services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/LogIn");
        services.AddAuthentication()
                .AddGoogle(googleOptions =>
            {
                this.Configuration.Bind("OAuth2:Providers:Google", googleOptions);

                googleOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub", "string");
            });

This happens on the redirect back to localhost/oauth2/google?etc

With this stack.

Microsoft.AspNetCore.Authentication.AuthenticationService.SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties)
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.HandleRequestAsync()
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

It shouldn't take me 2 weeks to get OAuth setup. I've been coding for 20 years, I feel like this isn't my fault. The code I've added isn't much different to the sample at the top of this page and yet it doesn't work.

AddIdentity also configures authentication schemes and cookies. If you're using AddIdentityCore, you need to do this yourself, as you've taken more direct control of the setup. To emulate the functionality you're missing, the following should work:

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
    options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
    options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddIdentityCookies()
.AddGoogle(...);

as you've taken more direct control of the setup

Unwittingly. Nothing about that method name indicates that I have taken more control. That's the problem with all this. It's a mess.

But thank you, not your fault.

Just for correctness, .AddGoogle(...) cannot be appended to the return of .AddIdentityCookies(...), but it does compile the other way around.

Thanks for reporting back on that. :+1:

My AccountController.ExternalLoginCallback(..) runs and this.SignInManager.GetExternalLoginInfoAsync() returns non-null at last, so thanks for helping me get this far.

I call

externalLoginResult = await this.SignInManager.ExternalLoginSignInAsync(
      externalLoginInfo.LoginProvider, externalLoginInfo.ProviderKey, isPersistent: persistCookieAfterBrowserClose);

Which fails, so I setup some the new user/login and call it again, which succeeds and I redirect. Good. However, on the next page request, this.HttpContext.User doesn't have a my expected principal.

And calling

var authenticateResult = await this.HttpContext.AuthenticateAsync();

Results in

InvalidOperationException: No service for type 'Microsoft.AspNetCore.Identity.ISecurityStampValidator' has been registered

I'm clearly still missing some piece of this puzzle.

How are you registering SignInManager with DI?

I was using .AddUserStore and .AddSignInManager extensions but I decided to take everything out and return to basics/the docs and start over. So I have resolved any DI errors the more traditional way, i.e.

            services.AddTransient<IUserStore<MyUser>, MyUserStore>();
            services.AddTransient(typeof(UserManager<MyUser>));
            services.AddTransient(typeof(SignInManager<MyUser>));

The call to AddSignInManager adds additional services - most notably, an ISecurityStampValidator implementation. You can see this in the source.

Sorry, I've again tried helping myself. Thanks for your patience.

Everything is working, I see the cookie being passed up by the browser after signing-in via Google, Cosmos DB has new accounts setup, all good except that this.HttpContext.User has an "empty" principal.

From what I have read, I think app.UseAuthentication() is supposed to just read this off the cookie into the principal using authOptions.DefaultAuthenticateScheme which is IdentityConstants.ApplicationScheme.

Interestingly, when I call this.HttpContext.AuthenticateAsync() it returns a result with the principal I'd expect in the .User so some last little thing is missing in my setup.

Here's my MVC setup.

        services.AddMvc(mvcOptions =>
        {
            if (!this.HostingEnvironment.IsDevelopment())
            {
                mvcOptions.Filters.Add(new RequireHttpsAttribute());
            }

            var policy = new AuthorizationPolicyBuilder()
                             .RequireAuthenticatedUser()
                             .Build();

            mvcOptions.Filters.Add(new AuthorizeFilter(policy));

        }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

My login routes have [AllowAnonymous] and a test route with [Authorize] does hit a breakpoint within, but this.User has no claims.

I'm able to request and hit

Thanks again.

It's no problem at all. I'm more than happy to try and help.

You're right in that DefaultAuthenticateScheme is the real driver for getting that HttpContext.User populated correctly. The call to HttpContext.AuthenticateAsync() uses the same value so, as you suggest, I'd expect it to be working if that is.

If you can convert what you have into a GitHub repo, I'd be happy to take a look at the full picture.

Capture

Rather worryingly, with a global filter in place and the attribute, and cookies cleared and the VS debugging session restarted, I'm still able to access routes I don't think I should. See image.

@serpent5 Kirk, thank you. If you'll agree that I should not be able to hit that breakpoint, then I can't trust this codebase anymore and I'll have to start over from a whole new app.

That depends. Do you have AllowAnonymous on the controller there? If so, that actually overrides the Authorize you have on the action itself. See the warning at the bottom of this docs page.

I guess I'm relieved, there's still hope in these 71,851 lines of code. I thought filters were applied in order of "proximity" to the action!

Yeah, they are - it's just that authorisation stuff gets special treatment there.

Kirk, thank you so much. I lifted all that stuff into a new project so I could, as a last resort, stick it in a repo for you, and thought I'd just try asking on SO to save you any hassle. Thanks.

https://stackoverflow.com/questions/56842367/controller-user-has-no-claims-even-though-identity-applicaton-cookie-is-sent

Answer: app.UseAuthentication() must be above app.UseMvc(...)

It's really no hassle. I'm pleased to be able to help and especially pleased that you've got it working. I'm sure you will finally sleep well tonight. :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AnthonyMastrean picture AnthonyMastrean  Â·  3Comments

sonichanxiao picture sonichanxiao  Â·  3Comments

neman picture neman  Â·  3Comments

fabich picture fabich  Â·  3Comments

Rick-Anderson picture Rick-Anderson  Â·  3Comments