首页新闻找找看学习计划

IdentityServer4的IdentityResource怎么自定义数据项?

0
悬赏园豆:10 [已解决问题] 解决于 2020-03-04 20:47

IdentityServer4的用户资源(IdentityResource)能不能自定义数据项?
就是自带的JwtClaimTypes里面没有想项目??

我想在里面增加一个内部编号和部门,怎么实现?
JwtClaimTypes里面就那几十个可选内容,如果直接这样写

new IdentityResource("User","用户数据",new List<string> {
    JwtClaimTypes.Name,
    JwtClaimTypes.Role,
    "UserNumber",
    "Department"
}),

后两个就没办法识别,怎么和表中的数据对应起来?

用户认证用的就是.net 自带的 Identity 重写的ApplicationUser方法,里面直接加的项

    public class ApplicationUser : IdentityUser
    {
        public string UserNumber { get; set; }
        public int DepartmentId { get; set; }
        public Department Department { get; set; }
    }
随缘py的主页 随缘py | 初学一级 | 园豆:146
提问于:2019-12-20 00:43
< >
分享
最佳答案
0

我尝试实现过 Is4 密码模式 自定义用户验证,可以覆盖你的需求。我直接贴代码了。
这里包含自定义验证和设置claims

public class MyResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
    private MyUserContext _userContext;
    public MyResourceOwnerPasswordValidator(MyUserContext userContext)
    {
        _userContext = userContext;
    }

    public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
    {
        var user = _userContext.Users.SingleOrDefault(u =>
            string.Equals(u.Name, context.UserName, StringComparison.CurrentCultureIgnoreCase)
              && string.Equals(u.Password, context.Password, StringComparison.CurrentCultureIgnoreCase));
        if (user == null)
        {
            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "invalid custom credential");
        }
        else
        {
            //调用此方法以后内部会进行过滤,只将用户请求的Claim加入到 context.IssuedClaims 集合中 这样我们的请求方便能正常获取到所需Claim

            //验证通过返回结果 
            //subjectId 为用户唯一标识 一般为用户id
            //authenticationMethod 描述自定义授权类型的认证方法 
            //authTime 授权时间
            //claims 需要返回的用户身份信息单元 此处应该根据我们从数据库读取到的用户信息 添加Claims 如果是从数据库中读取角色信息,那么我们应该在此处添加 此处只返回必要的Claim
            context.Result = new GrantValidationResult(
                user.Id.ToString(),
                OidcConstants.AuthenticationMethods.Password, DateTime.UtcNow, user.Claims());
        }
        await Task.CompletedTask;
    }
}

public class MyUser
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Account { get; set; }
    public string Password { get; set; }
    public int Age { get; set; }
    public int Sex { get; set; }
    public string Phone { get; set; }
    public string Introduce { get; set; }
    public DateTime CreateTime { get; set; }

    public List<Claim> Claims()
    {
        return new List<Claim> {
                new Claim("name",Name),
                new Claim("account",Account),
                new Claim("age",Age.ToString()),
                new Claim("sex",Sex.ToString()),
                new Claim("phone",Phone),
                new Claim("introduce",Introduce),
                new Claim("createtime",CreateTime.ToString("yyyy-MM-dd HH:mm")),
            };
    }
}
收获园豆:10
xiaogui340 | 菜鸟二级 |园豆:423 | 2019-12-23 19:17

注入方法

      services.AddIdentityServer()
            .AddResourceOwnerValidator<MyResourceOwnerPasswordValidator>()

还有个 IProfileService 接口可以自定义,用来对 claim 作过滤的

xiaogui340 | 园豆:423 (菜鸟二级) | 2019-12-23 19:21

是吧信息存到AspNetUserClaims里,传送Claim里面的信息?
不能把信息直接写到AspNetUser表中?

随缘py | 园豆:146 (初学一级) | 2019-12-25 11:14

@随缘py: 不太理解你的 把信息写到AspNetUser表中 这句话的意思。
逻辑上 在Validator里面 从数据库中获取用户信息,验证通过后,把自定义的 claim 加进Result里面,最终会封装到 token 里面。

对于IdentityResource也是可以自定义的。
下面就是定义了一个Name为 myuser,包含 name sex introduce 三个claim的 IdentityResource

public class MyUserIdentityResource : IdentityResource
{
    public MyUserIdentityResource()
        : base("MyUser", new[] { "name", "sex", "introduce" })
    {

    }
}
xiaogui340 | 园豆:423 (菜鸟二级) | 2019-12-25 14:16
其他回答(1)
0

可以是直接定义类似Key value 的形式。IdentityServer自己支持的

初夏的阳光丶 | 园豆:509 (小虾三级) | 2019-12-23 14:33

怎么实现?
自己想不出来~~

支持(0) 反对(0) 随缘py | 园豆:146 (初学一级) | 2019-12-23 17:07
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册