[英]Identity Server 4 add custom claims to User
I have set up Identity Server 4 (a while back, so I have forgotten a lot of things) and I am trying to set claims on the current logged in User.我已经设置了 Identity Server 4(不久前,所以我忘记了很多事情)并且我正在尝试对当前登录的用户设置声明。 When I login and use a filter to see what claims they have I can see this:当我登录并使用过滤器查看他们有什么声明时,我可以看到:
You can see from this image that my scopes, claims and roles have been added to the user which is good.您可以从此图像中看到我的范围、声明和角色已添加到用户中,这很好。 But the claims have a type of Role which I think is wrong.但是这些声明有一种我认为是错误的角色。 I want to change that to Claim instead:我想将其更改为声明:
I have searched my application for ClaimTypes.Role
and role
but cannot find where I have set this up.我已经在我的应用程序中搜索了ClaimTypes.Role
和role
,但找不到我在哪里设置的。 Is this something that can be done easily?这是可以轻松完成的事情吗?
I managed to sort this out;我设法解决了这个问题; so basically I already had roles set up.所以基本上我已经设置了角色。 I just didn't understand how I had done it in the past.我只是不明白我过去是怎么做到的。 The main thing to do was set up the ApiResource which I did like this:要做的主要事情是设置我这样做的ApiResource :
new ApiResource(IdentityConstants.ApiResources.IdentityServer, "Identity Server", new[] {JwtClaimTypes.Role, IdentityConstants.ClaimTypes.Permission})
My constants class just has a few static strings set up like this:我的常量 class 只有几个 static 字符串设置如下:
public static class SituIdentityConstants
{
public static class ApiResources
{
public const string Sxp = "sxp";
public const string IdentityServer = "identity-server";
}
public static class ClaimTypes
{
public const string Permission = "permission";
}
}
Once that was done;一旦完成; I updated my seed and included this:我更新了我的种子并包括了这个:
private static void CreateApiResources(ConfigurationDbContext context)
{
var scopes = ListApiScopes();
var resources = ListApiResources();
foreach (var scope in scopes)
if (!context.ApiScopes.Any(m => m.Name.Equals(scope.Name)))
context.ApiScopes.Add(scope.ToEntity());
foreach (var resource in resources)
{
if (context.ApiResources.Any(m => m.Name.Equals(resource.Name))) continue;
var entity = resource.ToEntity();
entity.Scopes = scopes.Select(m => new ApiResourceScope
{
Scope = m.Name
}).ToList();
context.Add(entity);
}
context.SaveChanges();
}
Which created all the API Resources, scopes and any ApiResourceClaims (which is what populates RequestedClaimTypes
in the IProfileService
.它创建了所有 API 资源、范围和任何 ApiResourceClaims(这是在IProfileService
中填充RequestedClaimTypes
的内容。
Btw, for reference, here is my ProfileService :顺便说一句,作为参考,这是我的ProfileService :
public class ProfileService: IProfileService
{
private readonly IMediator _mediator;
private readonly UserManager<User> _userManager;
private readonly RoleManager<Role> _roleManager;
public ProfileService(IMediator mediator, UserManager<User> userManager, RoleManager<Role> roleManager)
{
_mediator = mediator;
_userManager = userManager;
_roleManager = roleManager;
}
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var user = await _userManager.FindByIdAsync(context.Subject.GetSubjectId());
var rolesAttempt = await _mediator.Send(new ListRoles());
if (rolesAttempt.Failure) return;
var roles = rolesAttempt.Result;
var issuedClaims = new List<System.Security.Claims.Claim>();
foreach (var role in roles)
{
if (!user.Roles.Any(m => m.RoleId.Equals(role.Id))) continue;
issuedClaims.Add(new System.Security.Claims.Claim(JwtClaimTypes.Role, role.Name));
var roleClaims = await _roleManager.GetClaimsAsync(new Role {Id = role.Id});
issuedClaims.AddRange(roleClaims.Where(m => context.RequestedClaimTypes.Any(x => x.Equals(m.Type))));
}
context.IssuedClaims = issuedClaims;
}
public async Task IsActiveAsync(IsActiveContext context)
{
var sub = context.Subject.GetSubjectId();
var user = await _userManager.FindByIdAsync(sub);
var active = (user != null && (!user.LockoutEnabled || user.LockoutEnd == null)) ||
(user != null && user.LockoutEnabled && user.LockoutEnd != null &&
DateTime.UtcNow > user.LockoutEnd);
context.IsActive = active;
}
}
I actually found this to be a pain to set up.我实际上发现这是一个痛苦的设置。 I tried the way the documentation states:我尝试了文档所述的方式:
services.AddIdentityServer()
.AddDeveloperSigningCredential()
// Stores clients and resources
.AddConfigurationStore(options => options.ConfigureDbContext = ConfigureDbContext)
// Stores tokens, consents, codes, etc
.AddOperationalStore(options => options.ConfigureDbContext = ConfigureDbContext)
.AddProfileService<ProfileService>()
.AddAspNetIdentity<User>();
But this would not work for me;但这对我不起作用; so instead I did it like this:所以我这样做了:
services.AddIdentityServer()
.AddDeveloperSigningCredential()
// Stores clients and resources
.AddConfigurationStore(options => options.ConfigureDbContext = ConfigureDbContext)
// Stores tokens, consents, codes, etc
.AddOperationalStore(options => options.ConfigureDbContext = ConfigureDbContext)
.AddAspNetIdentity<User>();
services.AddScoped(typeof(IProfileService), typeof(ProfileService));
That's all I needed to do for Identity Server, the RequestedClaimTypes
is now populated both with "role" and "permission".这就是我需要为 Identity Server 做的所有事情, RequestedClaimTypes
现在填充了“角色”和“权限”。 The only other thing I did, was when I created a RoleClaim, I set the claim type to "permission" and it works:我唯一做的另一件事是,当我创建 RoleClaim 时,我将声明类型设置为“permission”并且它可以工作:
{
"nbf": 1611600995,
"exp": 1611604595,
"iss": "https://localhost:44362",
"aud": [
"sxp",
"identity-server"
],
"client_id": "client",
"sub": "949cc454-d7c9-45db-9eae-59e72d3025c1",
"auth_time": 1611600983,
"idp": "local",
"role": "User Manager",
"permission": [
"users:write",
"user:read"
],
"jti": "39C9F31958972704730DA65A8FCDAAEE",
"iat": 1611600995,
"scope": [
"identity:read",
"identity:write",
"sxp:read",
"sxp:write"
],
"amr": [
"pwd"
]
}
Noice.噪音。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.