Asp Core 2.1 Jwt + 身份.userManager 存储没有实现 IUserRoleStore

时间:2023-03-29
本文介绍了Asp Core 2.1 Jwt + 身份.userManager 存储没有实现 IUserRoleStore的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

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

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

在我的 Startup.cs 我有:

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

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

然后在 SecurityService.cs 中我尝试使用此语句获取角色

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

var roles = await _userManager.GetRolesAsync(user);

并抛出以下异常:

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

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

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

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?

推荐答案

当您使用 AddIdentity 时,该调用会配置默认身份验证方案,如下所示 (来源):

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

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

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

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

由于这是定义的顺序(AddIdentityafter AddAuthentication),默认是从Jwt变成Identity,这样当您使用 [Authorize],身份验证过程现在期望使用 Identity 而不是 Jwt.

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.

要解决这个问题,最简单的选择是切换 AddIdentityAddAuthentication 的顺序,这样 JwtBearer 调用就排在最后,因此获胜".您还需要更明确地设置 DefaultAuthenticateSchemeDefaultChallengeScheme:

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

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

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

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

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

这篇关于Asp Core 2.1 Jwt + 身份.userManager 存储没有实现 IUserRoleStore的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:ASP.NET 核心 JWT 身份验证总是抛出 401 未授权 下一篇:使用 Jwt-Dotnet 生成有效令牌

相关文章