問題描述
我正在嘗試在 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)
由于這是定義的順序(AddIdentity
是after 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.
要解決這個問題,最簡單的選擇是切換 AddIdentity
和 AddAuthentication
的順序,這樣 JwtBearer 調用就排在最后,因此獲勝".您還需要更明確地設置 DefaultAuthenticateScheme
和 DefaultChallengeScheme
:
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的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!