Asp Core 2.1 Jwt + Identity. userManager store does not implement IUserRoleStore

馋奶兔 提交于 2019-12-20 03:39:12

问题


I am trying to work with Jwt auth and Identity in ASP Net Core 2.1

In my Startup.cs I have:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.RequireHttpsMetadata = false;
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = AuthOptions.ISSUER,
            ValidateAudience = true,
            ValidAudience = AuthOptions.AUDIENCE,
            ValidateLifetime = true,
            IssuerSigningKey = AuthOptions.GetSymmetricSecurityKey(),
            ValidateIssuerSigningKey = true,
        };
    });

var builder = services.AddIdentityCore<User>(options =>
{
    // Password settings
    ...
    // Lockout settings
    ...
    // User settings
    options.User.RequireUniqueEmail = true;
}).AddEntityFrameworkStores<ApplicationDbContext>();

builder = new IdentityBuilder(builder.UserType, typeof(IdentityRole), builder.Services);

Then in SecurityService.cs I am trying to get roles by using this statement

var roles = await _userManager.GetRolesAsync(user);

And its throwing the following exception:

NotSupportedException: Store does not implement IUserRoleStore
Microsoft.AspNetCore.Identity.UserManager.GetUserRoleStore()

I found it because of AddIdentityCore: If I use AddIdentity<User, IdentityRole> instead it works, but then [Authorize] doesn't work

Does anybody faced similar situation, or why it can happen?


回答1:


When you use AddIdentity<TUser, TRole>, that call configures the default authentication scheme, like so (source):

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

In your Startup.ConfigureServices, you have the following, which also sets the default authentication scheme:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

Because of the order this is defined (AddIdentity is after AddAuthentication), the default is changing from Jwt to Identity, so that when you use [Authorize], the authentication process is now expecting to use Identity rather than Jwt.

To resolve this, the simplest option is to switch the order of AddIdentity and AddAuthentication, so the JwtBearer call comes last and therefore "wins". You'll also need to be more explicit and set both DefaultAuthenticateScheme and DefaultChallengeScheme:

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(...);

Another option is to be explicit in the [Authorize] attribute, calling out which authentication scheme you want to use, like either of the following two lines:

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Authorize(AuthenticationSchemes = IdentityConstants.ApplicationScheme)]

It seems the first option would be most appropriate for your use-case, but it's good to know that this second option exists should you need it as you go further with Identity (there are more - e.g. using policies).



来源:https://stackoverflow.com/questions/52206742/asp-core-2-1-jwt-identity-usermanager-store-does-not-implement-iuserrolestore

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!