Asp 核心 2.1 Jwt + 身份。 userManager store 没有实现 IUserRoleStore
Asp Core 2.1 Jwt + Identity. userManager store does not implement IUserRoleStore
我正在尝试在 ASP Net Core 2.1
中使用 Jwt 身份验证和身份验证
在我的 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 does not implement IUserRoleStore
Microsoft.AspNetCore.Identity.UserManager.GetUserRoleStore()
我找到它是因为 AddIdentityCore
:如果我使用
AddIdentity<User, IdentityRole>
相反它起作用了,但是 [Authorize]
不起作用
有没有人遇到过类似的情况,或者为什么会发生?
当您使用 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)
因为这个定义的顺序(AddIdentity
是afterAddAuthentication
),默认是从Jwt变成Identity,所以当你使用 [Authorize]
,身份验证过程现在期望使用 Identity 而不是 Jwt。
要解决这个问题,最简单的选择是调换 AddIdentity
和 AddAuthentication
的顺序,因此 JwtBearer 调用最后,因此 "wins"。您还需要更明确地设置 DefaultAuthenticateScheme
和 DefaultChallengeScheme
:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(...);
另一种选择是在 [Authorize]
属性中明确指出 您要使用哪个 身份验证方案,如以下两行之一:
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Authorize(AuthenticationSchemes = IdentityConstants.ApplicationScheme)]
似乎第一个选项最适合您的用例,但很高兴知道第二个选项存在,如果您在进一步使用 Identity 时需要它(还有更多 - 例如使用策略)。
我正在尝试在 ASP Net Core 2.1
中使用 Jwt 身份验证和身份验证在我的 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 does not implement IUserRoleStore
Microsoft.AspNetCore.Identity.UserManager.GetUserRoleStore()
我找到它是因为 AddIdentityCore
:如果我使用
AddIdentity<User, IdentityRole>
相反它起作用了,但是 [Authorize]
不起作用
有没有人遇到过类似的情况,或者为什么会发生?
当您使用 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)
因为这个定义的顺序(AddIdentity
是afterAddAuthentication
),默认是从Jwt变成Identity,所以当你使用 [Authorize]
,身份验证过程现在期望使用 Identity 而不是 Jwt。
要解决这个问题,最简单的选择是调换 AddIdentity
和 AddAuthentication
的顺序,因此 JwtBearer 调用最后,因此 "wins"。您还需要更明确地设置 DefaultAuthenticateScheme
和 DefaultChallengeScheme
:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(...);
另一种选择是在 [Authorize]
属性中明确指出 您要使用哪个 身份验证方案,如以下两行之一:
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Authorize(AuthenticationSchemes = IdentityConstants.ApplicationScheme)]
似乎第一个选项最适合您的用例,但很高兴知道第二个选项存在,如果您在进一步使用 Identity 时需要它(还有更多 - 例如使用策略)。