![](/img/trans.png)
[英]Identity Server 4 - Role claims missing in OpenIdConnect handler in MVC client
[英]How to get additional claims on client side in identity server 4?
在我的身份服務器的 Startup.cs 文件中,我的服務器配置如下。 我正在使用 asp.net 身份進行用戶管理。
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryPersistedGrants()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddAspNetIdentity<ApplicationUser>();
services.AddTransient<IProfileService, ProfileService>();
我IdentiyResources
如下所示。 在這里,我想將額外的聲明作為IS_Token
返回,我想將其用於我的應用程序的一些進一步的業務邏輯。
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResource("IS_token", new []{ "IS_token" } ),
};
}
我還增加了在IssuedClaims這種說法我里面IProfileService
如下。
public class ProfileService : IProfileService
{
private readonly IUserClaimsPrincipalFactory<ApplicationUser> _claimsFactory;
private readonly UserManager<ApplicationUser> _userManager;
public ProfileService(UserManager<ApplicationUser> userManager, IUserClaimsPrincipalFactory<ApplicationUser> claimsFactory)
{
_userManager = userManager;
_claimsFactory = claimsFactory;
}
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var sub = context.Subject.GetSubjectId();
var user = await _userManager.FindByIdAsync(sub);
var principal = await _claimsFactory.CreateAsync(user);
var claims = principal.Claims.ToList();
claims = claims.Where(claim => context.RequestedClaimTypes.Contains(claim.Type)).ToList();
claims.Add(new Claim(JwtClaimTypes.GivenName, user.UserName));
claims.Add(new Claim(IdentityServerConstants.StandardScopes.Email, user.Email));
//Get user claims from AspNetUserClaims table
var userClaims = await _userManager.GetClaimsAsync(user);
claims.AddRange(userClaims);
context.IssuedClaims = claims;
}
public async Task IsActiveAsync(IsActiveContext context)
{
var sub = context.Subject.GetSubjectId();
var user = await _userManager.FindByIdAsync(sub);
context.IsActive = user != null;
}
}
我的MVC客戶端配置如下
new Client
{
ClientId = "mvc",
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
RequireConsent = false,
ClientSecrets =
{
new Secret("secret".Sha256())
},
// where to redirect to after login
RedirectUris = { "http://localhost:5002/signin-oidc" },
// where to redirect to after logout
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"IS_token",
"api"
},
AllowOfflineAccess = true
},
在我的 MVC 應用程序中,我在Startup.cs
文件中有以下代碼
services.AddMvc();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ClientId = "mvc";
options.ClientSecret = "secret";
options.ResponseType = "code id_token";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("api");
options.Scope.Add("offline_access");
});
當我在身份服務器中對用戶進行身份驗證並返回到我的安全鏈接時,我得到了以下聲明,但我的用戶聲明中缺少 IS_token。
我的安全頁面的cshtml
<dl>
@foreach (var claim in User.Claims)
{
<dt>@claim.Type</dt>
<dd>@claim.Value</dd>
}
<dt>access token</dt>
<dd>@await ViewContext.HttpContext.GetTokenAsync("access_token")</dd>
<dt>refresh token</dt>
<dd>@await ViewContext.HttpContext.GetTokenAsync("refresh_token")</dd>
</dl>
這是我的受保護頁面的屏幕截圖
正如您在圖像中IS_token
,缺少IS_token
。 我怎樣才能獲得IS_token
聲明???
我需要在身份服務器的客戶端配置中設置AlwaysIncludeUserClaimsInIdToken = true
。 所以我應該如下定義我的客戶。
new Client
{
ClientId = "mvc",
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
RequireConsent = false,
ClientSecrets =
{
new Secret("secret".Sha256())
},
// where to redirect to after login
RedirectUris = { "http://localhost:5002/signin-oidc" },
// where to redirect to after logout
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"IS_token",
"poslink"
},
AlwaysIncludeUserClaimsInIdToken = true,
AllowOfflineAccess = true
},
在您的客戶端配置中,在 AddOpenIdConnect 中,您應該添加:
options.Scope.Add("IS_token");
否則,此范圍的聲明將被您的GetProfileDataAsync
實現過濾掉
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.