【发布时间】:2021-03-18 18:32:12
【问题描述】:
我知道这个问题已经被报告了很多,并且有很多关于如何解决这个问题的文章。我已经经历了很多,但仍然无法解决这个问题。
我正在 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 线程上找到的关于这个问题的几乎所有内容。现在不知道下一步该做什么。
【问题讨论】:
-
将 AlwaysIncludeUserClaimsInIdToken = true 添加到您的客户端配置并检查这是否会将声明添加到您的 access_token
-
@mohammadmahdiTalachi 做到了。没有任何区别。
标签: c# asp.net-core identityserver4 openid-connect