【问题标题】:Asp Core 2.1 Jwt + Identity. userManager store does not implement IUserRoleStoreAsp Core 2.1 Jwt + 身份。 userManager store 没有实现 IUserRoleStore
【发布时间】:2019-02-11 20:59:52
【问题描述】:

我正在尝试在 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:存储未实现 IUserRoleStore
Microsoft.AspNetCore.Identity.UserManager.GetUserRoleStore()

我发现它是因为AddIdentityCore: 如果我使用 AddIdentity&lt;User, IdentityRole&gt; 反而有效,但随后 [Authorize] 无效

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

【问题讨论】:

  • AddIdentityCore 没有注册与角色相关的东西,所以这是有道理的。当您说 [Authorize] 不起作用时,具体是什么意思?
  • @KirkLarkin 和 AddIdentityCore 它让我可以访问端点,但我没有重定向到登录页面
  • 只是为了确认 - 该端点正在使用 JWT 身份验证?
  • @KirkLarkin 是的,我在 startup.cs 中设置这个 - AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(...)

标签: c# asp.net-core jwt asp.net-core-identity


【解决方案1】:

当您使用AddIdentity&lt;TUser, TRole&gt; 时,该调用会配置默认身份验证方案,如下所示 (source):

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

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

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

因为这是定义的顺序(AddIdentity之后 AddAuthentication),所以默认是从Jwt变成Identity,所以当你使用[Authorize]时,认证过程是现在希望使用 Identity 而不是 Jwt。

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2020-02-27
    • 2023-03-28
    • 2017-12-06
    • 2023-04-01
    • 2017-09-11
    • 1970-01-01
    • 2015-01-21
    • 2019-03-10
    • 2016-07-31
    相关资源
    最近更新 更多