C# 如何在identity server 4中获取客户端的附加声明?
在我的identity server的Startup.cs文件中,我将服务器配置如下。我正在使用asp.net标识进行用户管理C# 如何在identity server 4中获取客户端的附加声明?,c#,asp.net,asp.net-core,asp.net-identity,identityserver4,C#,Asp.net,Asp.net Core,Asp.net Identity,Identityserver4,在我的identity server的Startup.cs文件中,我将服务器配置如下。我正在使用asp.net标识进行用户管理 services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryPersistedGrants() .AddInMemoryIdentityResources(Config.GetIdenti
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryPersistedGrants()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddAspNetIdentity<ApplicationUser>();
services.AddTransient<IProfileService, ProfileService>();
我还在我的IProfileService
中的IssuedClaims中添加此索赔,如下所示
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;
}
}
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
},
当我在identity server中验证用户身份并返回到我的安全链接时,我得到了以下声明,但我的用户声明中缺少IS_令牌
我的安全页面的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>
@foreach(User.Claims中的var声明)
{
@索赔.类型
@索赔价值
}
访问令牌
@等待ViewContext.HttpContext.GetTokenAsync(“访问令牌”)
刷新令牌
@等待ViewContext.HttpContext.GetTokenAsync(“刷新令牌”)
这是我的安全页面的屏幕截图
正如您在图像
中所看到的,令牌丢失。如何获取IS_token
claim???我需要在identity server的客户端配置中设置AlwaysIncludeUserClaimsInIdToken=true
。所以我应该定义我的客户如下
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;
}
}
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
},
新客户端
{
ClientId=“mvc”,
ClientName=“MVC客户端”,
AllowedGrantTypes=GrantTypes.HybridAndClientCredentials,
RequireSent=false,
客户秘密=
{
新密码(“Secret.Sha256())
},
//登录后重定向到哪里
重定向URI={”http://localhost:5002/signin-oidc“},
//注销后重定向到何处
PostLogoutRedirectUris={”http://localhost:5002/signout-回调oidc“},
AllowedScopes=新列表
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
“是您的代币”,
“poslink”
},
AlwaysIncludeUserClaimsInIdToken=真,
AllowOfflineAccess=true
},
在客户端配置的AddOpenIdConnect中,您应该添加:
options.Scope.Add(“IS_标记”)代码>
否则,此作用域的声明将被GetProfileDataAsync
的实现过滤掉,这对您没有帮助,因为ID令牌不是刷新令牌或访问令牌。
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
},