我正在尝试使用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]
不起作用
有没有人遇到类似的情况,或者为什么会发生这种情况?
使用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
在AddAuthentication
之后),默认值是从Jwt更改为Identity,因此当您使用[Authorize]
时,身份验证过程现在期望使用Identity而不是Jwt。
要解决这个问题,最简单的选择是切换AddIdentity
和AddAuthentication
的顺序,因此JwtBearer调用最后一次,因此“获胜”。你还需要更明确地设置DefaultAuthenticateScheme
和DefaultChallengeScheme
:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(...);
另一个选择是在[Authorize]
属性中显式,调用您要使用的身份验证方案,如以下两行之一:
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Authorize(AuthenticationSchemes = IdentityConstants.ApplicationScheme)]
似乎第一个选项最适合您的用例,但是如果您需要进一步使用Identity,那么最好知道第二个选项是否存在(还有更多 - 例如使用策略)。