Asp Core 2.1 Jwt + Identity。 userManager存储未实现IUserRoleStore

问题描述 投票:2回答:1

我正在尝试使用ASP Net Core 2.1中的Jwt auth和Identity

在我的Startup.cs中,我有:

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

然后在SecurityService.cs中我试图通过使用此语句来获取角色

var roles = await _userManager.GetRolesAsync(user);

它抛出以下异常:

NotSupportedException:Store未实现IUserRoleStore Microsoft.AspNetCore.Identity.UserManager.GetUserRoleStore()

我发现它是因为AddIdentityCore:如果我使用AddIdentity<User, IdentityRole>而不是它的工作,但然后[Authorize]不起作用

有没有人遇到类似的情况,或者为什么会发生这种情况?

c# asp.net-core jwt asp.net-core-identity
1个回答
3
投票

使用AddIdentity<TUser, TRole>时,该调用配置默认的身份验证方案,如下所示(source):

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

Startup.ConfigureServices中,您有以下内容,它还设置了默认的身份验证方案:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

由于这是定义的顺序(AddIdentityAddAuthentication之后),默认值是从Jwt更改为Identity,因此当您使用[Authorize]时,身份验证过程现在期望使用Identity而不是Jwt。

要解决这个问题,最简单的选择是切换AddIdentityAddAuthentication的顺序,因此JwtBearer调用最后一次,因此“获胜”。你还需要更明确地设置DefaultAuthenticateSchemeDefaultChallengeScheme

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

另一个选择是在[Authorize]属性中显式,调用您要使用的身份验证方案,如以下两行之一:

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

似乎第一个选项最适合您的用例,但是如果您需要进一步使用Identity,那么最好知道第二个选项是否存在(还有更多 - 例如使用策略)。

© www.soinside.com 2019 - 2024. All rights reserved.