微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决Identity Server 4 向用户添加自定义声明

我已经设置了 Identity Server 4(不久前,所以我忘记了很多事情)并且我正在尝试对当前登录用户设置声明。 当我登录并使用过滤器查看他们的声明时,我可以看到:

enter image description here

您可以从这张图片中看到,我的范围、声明和角色已添加用户中,这很好。 但是声明有一种角色,我认为这是错误的。我想将其改为声明

enter image description here

我在我的应用程序中搜索ClaimTypes.Rolerole,但找不到我在哪里设置它。 这是可以轻松完成的事情吗?

解决方法

我设法解决了这个问题;所以基本上我已经设置了角色。我只是不明白我过去是怎么做到的。主要要做的是设置 ApiResource,我是这样做的:

new ApiResource(IdentityConstants.ApiResources.IdentityServer,"Identity Server",new[] {JwtClaimTypes.Role,IdentityConstants.ClaimTypes.Permission})

我的常量类只有一些静态字符串设置如下:

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";
    }
}

一旦完成;我更新了我的种子并包含了这个:

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();
}

它创建了所有 API 资源、范围和任何 ApiResourceClaims(这是在 RequestedClaimTypes 中填充 IProfileService 的内容。

顺便说一句,作为参考,这是我的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;
    }
}

我实际上发现这设置起来很麻烦。我尝试了文档说明的方式:

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>();

但这对我不起作用;所以我是这样做的:

services.AddIdentityServer()
    .AddDeveloperSigningCredential()
    // Stores clients and resources
    .AddConfigurationStore(options => options.ConfigureDbContext = ConfigureDbContext)
    // Stores tokens,etc
    .AddOperationalStore(options => options.ConfigureDbContext = ConfigureDbContext)
    .AddAspNetIdentity<User>();

services.AddScoped(typeof(IProfileService),typeof(ProfileService));

这就是我需要为 Identity Server 做的所有事情,RequestedClaimTypes 现在填充了“角色”和“权限”。我做的另一件事是,当我创建一个 RoleClaim 时,我将声明类型设置为“权限”并且它有效:

{
    "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"
    ]
}

噪音。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。