简体   繁体   English

Identity Server 4 向用户添加自定义声明

[英]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.Rolerole ,但找不到我在哪里设置的。 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.

相关问题 向身份服务器添加自定义声明4 GrantValidationResult - adding custom claims to identity server 4 GrantValidationResult 身份服务器4并未显示所有用户声明 - identity server 4 does not show all user claims 用户的声明身份 - User's Claims Identity 使用OIDC对SPA,WEBAPI和Identity Server 4进行自定义声明? - Custom claims with SPA, WEBAPI and Identity Server 4 using oidc? 从IdentityA 4中的用户获取WebApi的所有声明 - Getting all the claims from a WebApi for a user in Identity Server 4 声明为空,用户未在 AuthorizationHandlerContext 的 HandleRequirement 中通过 Duende 身份服务器进行身份验证 - Claims is empty and user is not Authenticated in HandleRequirement of AuthorizationHandlerContext with Duende identity server 身份服务器:在 MVC 客户端的混合流中添加对访问令牌的声明 - Identity Server: Add claims to access token in hybrid flow in MVC client 身份服务器 Windows 身份验证声明 - Identity Server Windows Authentication Claims Identity Server 3 + AspNet Identity 中基于角色的声明 - Role based claims in Identity Server 3 + AspNet Identity ASP.net标识自定义用户模型未被角色,声明和登录表使用 - ASP.net Identity custom user model not being used by roles, claims and login table
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM