[英]Additional claims set from IProfileService not available in MVC client's OpenIdConnect handler
[英]Identity Server 4 - Role claims missing in OpenIdConnect handler in MVC client
我知道這個問題已經被報告了很多,並且有很多關於如何解決這個問題的文章。 我已經經歷了很多,但仍然無法解決這個問題。
我在 Identity Server 的OnSecurityTokenValidated
回調中對Principal.Identity
設置自定義聲明,如下所示:
public async Task SecurityTokenValidated(SecurityTokenValidatedContext context) {
var identity = context.Principal.Identity as ClaimsIdentity;
foreach(var claim in context.Principal.Claims.Where(x = >x.Type == "adGroupClaimType").ToList()) {
var groupName = Configuration.GetSection("ClaimMappings").GetValue < string > ($ "Prefix_{claim.Value}");
if (!string.IsNullOrWhiteSpace(groupName)) {
identity.AddClaim(new Claim(ClaimTypes.Role, groupName));
}
identity.RemoveClaim(claim);
}
}
以下是我在 Identity Server 中使用的配置:
public static IEnumerable < IdentityResource > IdentityResources = >new List < IdentityResource > {
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResource("roles", new[] {
ClaimTypes.Role
})
};
public static IEnumerable < ApiScope > ApiScopes = >new List < ApiScope > {
new ApiScope("api", "API")
};
public static IEnumerable < Client > Clients = >new List < Client > {
new Client {
ClientId = "mvc-openid",
ClientSecrets = {
new Secret("secret".Sha256())
},
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
RedirectUris = {
"https://localhost:6001/signin-oidc"
},
AllowedScopes = new List < string > {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api",
"roles"
},
RequirePkce = false,
AllowOfflineAccess = true,
AllowAccessTokensViaBrowser = true
}
};
有一個 MVC 客戶端使用 OpenIdConnect 連接到 Identity Server。 代碼如下:
public void ConfigureServices(IServiceCollection services) {
services.AddMvc();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
services.AddAuthentication(options = >{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
}).AddCookie(options = >{
options.ExpireTimeSpan = 15;
options.SlidingExpiration = true;
options.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None;
}).AddOpenIdConnect("oidc", options = >{
options.Authority = "https://localhost:5001";
options.ClientId = "mvc-openid";
options.ClientSecret = "secret";
options.ResponseType = "code id_token token";
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
options.Scope.Add("api");
options.Scope.Add("roles");
options.Scope.Add("offline_access");
options.Events.OnTokenValidated = OnTokenValidated;
options.TokenValidationParameters = new TokenValidationParameters {
NameClaimType = ClaimTypes.Name,
RoleClaimType = ClaimTypes.Role
};
options.ClaimActions.MapUniqueJsonKey(ClaimTypes.Role, ClaimTypes.Role);
});
}
private Task OnTokenValidated(TokenValidatedContext context) {
var t = context.Principal.Claims;
return Task.CompletedTask;
}
當我檢查OnTokenValidated
中的聲明時,我可以看到我從 Identity Server 設置的所有角色聲明都丟失了。 有人可以告訴我哪里出錯了嗎? 我已經嘗試了在 Stack Overflow 線程上找到的關於這個問題的幾乎所有內容。 現在不知道下一步該做什么。
到目前為止,我也只找到了這個解決方案。
options.Events.OnUserInformationReceived = context =>
{
var roleElement = context.User.RootElement.GetProperty("role");
var claims = new List<Claim>();
if (roleElement.ValueKind == System.Text.Json.JsonValueKind.Array)
{
foreach (var r in roleElement.EnumerateArray())
claims.Add(new Claim(JwtClaimTypes.Role, r.GetString()));
}
else
{
claims.Add(new Claim(JwtClaimTypes.Role, roleElement.GetString()));
}
var id = context.Principal.Identity as ClaimsIdentity;
id.AddClaims(claims);
return Task.CompletedTask;
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.