【问题标题】:Identity Server - how to I include with token additional claims (from external identity provider)身份服务器 - 如何包含令牌附加声明(来自外部身份提供者)
【发布时间】:2020-08-05 14:20:56
【问题描述】:

我很难找到有关如何从身份服务器向我的客户端应用程序发送附加声明的可靠信息。

目前,我正在使用以下内容获取本地声明(我在 ProcessLoginCallbackForOidc 中捕获)并添加到身份验证期间返回的声明中。

这是最好的方法吗?

public class ProfileService : IProfileService
    {
        public Task GetProfileDataAsync(ProfileDataRequestContext context)
        {
            //var sub = context.Subject.GetSubjectId();
            var claims = context.Subject.Claims.ToList();
            if (claims.Count > 0)
            {
                var emailClaim = claims.FirstOrDefault(x => x.Type == "email");
                if (emailClaim == null)
                {
                    var emailAddressClaim = context.Subject.Claims.FirstOrDefault(x => x.Type == "emails");
                    if (emailAddressClaim != null)
                    {
                        claims.Add(new Claim("email", emailAddressClaim.Value));
                    }
                }
            }

            // Set returned claims (System.Security.Claims.Claim) by setting context.IssuedClaims
            context.IssuedClaims = claims;

            return Task.CompletedTask;
        }

        public Task IsActiveAsync(IsActiveContext context)
        {
            context.IsActive = true;
            return Task.CompletedTask;
        }
    }

【问题讨论】:

    标签: oauth identityserver4


    【解决方案1】:

    是的,这是正确的解决方案。 ProfileService 是为用户添加额外声明的扩展点。 它在为用户创建令牌时调用。

    阅读更多here

    编辑: 以下是配置文件服务的示例代码:

    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();
    
            if (claims.Count > 0)
            {
                 var emailClaim = claims.FirstOrDefault(x => x.Type == "email");
                 if (emailClaim == null)
                 {
                     var emailAddressClaim = context.Subject.Claims.FirstOrDefault(x => x.Type == "emails");
                     if (emailAddressClaim != null)
                     {
                         claims.Add(new Claim("email", emailAddressClaim.Value));
                     }
                 }
             }
    
             context.IssuedClaims = claims;
    
             return Task.CompletedTask;   
        }
    
        public async Task IsActiveAsync(IsActiveContext context)
        {
            var sub = context.Subject.GetSubjectId();
            var user = await _userManager.FindByIdAsync(sub);
            context.IsActive = user != null;
        }
    }
    

    【讨论】:

    • 我对这种方法有疑问。当我使用这种方法时,返回的声明比我不使用 ProfileService 时要少。即当使用 profileservice 时,我没有收到我在实施 profileservice 之前的电子邮件声明(在客户端)。在我的 GetProfileDataAsync(上图)上下文中。IssuedClaims 缺少我之前收到的电子邮件和名称声明。为什么会缺少那两个?
    • 这是你的实现问题而不是方法的问题,因为我看到你没有在你的代码中获取用户,我将为配置文件服务添加示例代码
    猜你喜欢
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-09
    相关资源
    最近更新 更多