[英]Claims is empty and user is not Authenticated in HandleRequirement of AuthorizationHandlerContext with Duende identity server
[英]Custom claim not accessible in AuthorizationHandlerContext Identity server 4 JWT
我有一個將聲明添加到令牌的配置文件服務
檔案服務
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var sub = context.Subject.GetSubjectId();
var user = await _userManager.FindByIdAsync(sub);
var claims = new List<Claim>();
var userClaims = await _userManager.GetClaimsAsync(user);
foreach (var userClaim in userClaims)
{
claims.Add(new Claim(userClaim.Type, userClaim.Value));
}
context.IssuedClaims.AddRange(claims);
}
JWT 令牌
{
"nbf": 1608909669,
"exp": 1608996069,
"iss": "https://localhost:5001",
"aud": "https://localhost:5001/resources",
"client_id": "Local",
"sub": "307f4f24-71a5-4aee-8505-f87b58a1eb2e",
"auth_time": 1608908167,
"idp": "local",
"IdentityServer": [
"Read",
"Create",
"Update",
"Delete"
],
"Product": [
"Read",
"Create",
"Update",
"Delete"
],
"jti": "87FA14C0153AD10D0E16A721720D19DB",
"sid": "C739A377659C364AA29040FEE2FB4FA2",
"iat": 1608909669,
"scope": [
"openid",
"profile",
"email"
],
"amr": [
"pwd"
]
}
只能在AuthorizationHandlerContext中獲得以下聲明
啟動.cs
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
// base-address of your identityserver
options.Authority = configuration.GetSection("IdentityServer:OAuth:AuthorizationUrl").Value;
// name of the API resource
options.ApiName = AuthorizePolicy.apiScope;
});
app.UseAuthentication();
為什么我無法訪問IdentityServer, Product
聲明。 我正在使用 Identity server 4 最新版本
更新 1
在帳戶 controller 的登錄過程中添加以下代碼
var principal = await _claimsFactory.CreateAsync(user);
var claims = principal.Claims.ToList();
var isuser = new IdentityServerUser(user.Id)
{
DisplayName = user.UserName,
AdditionalClaims = claims
};
await HttpContext.SignInAsync(isuser, props);
現在用戶包含所有其他聲明,但如果我刪除其中一個聲明 JWT 令牌被刷新,但是,用戶身份仍然包含舊值,要刷新身份我需要再次顯式登錄用戶,這是不合適的,我該如何解決這個問題?
默認情況下,自定義聲明不會包含在用戶中,相反,您需要手動 map 您關心的傳入聲明。
通常,您會添加以下內容:
public void ConfigureServices(IServiceCollection services)
{
// By default, Microsoft has some legacy claim mapping that converts
// standard JWT claims into proprietary ones. This removes those mappings.
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();
然后在 AddOpenIDConnect 選項中,設置:
options.ClaimActions.MapUniqueJsonKey("website", "website");
options.ClaimActions.MapUniqueJsonKey("gender", "gender");
options.ClaimActions.MapUniqueJsonKey("birthdate", "birthdate");
或者
options.ClaimActions.MapAllExcept("iss", "nbf", "exp", "aud", "nonce");
相同的配置可能如下所示:
}).AddOpenIdConnect(options =>
{
options.Authority = "https://localhost:6001";
options.ClientId = "authcodeflowclient";
options.ClientSecret = "mysecret";
options.ResponseType = "code";
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("email");
options.Scope.Add("employee_info");
options.ClaimActions.MapUniqueJsonKey("employment_start", "employment_start");
options.ClaimActions.MapUniqueJsonKey("seniority", "seniority");
options.ClaimActions.MapUniqueJsonKey("contractor", "contractor");
options.ClaimActions.MapUniqueJsonKey("employee", "employee");
options.ClaimActions.MapUniqueJsonKey("management", "management");
options.ClaimActions.MapUniqueJsonKey(JwtClaimTypes.Role, JwtClaimTypes.Role);
options.SaveTokens = true;
options.SignedOutRedirectUri = "/";
options.GetClaimsFromUserInfoEndpoint = true;
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = JwtClaimTypes.Name,
RoleClaimType = JwtClaimTypes.Role,
};
options.Prompt = "consent";
});
如果您不想處理令牌並在那里添加聲明,那么另一種方法是在您的授權策略中查找其他用戶詳細信息。 有關更多詳細信息,請參閱有關自定義授權策略的此頁面。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.