【问题标题】:Claim change in Identity Server's ProfileService is not reflected in Authentication CookieIdentity Server 的 ProfileService 中的声明更改未反映在身份验证 Cookie 中
【发布时间】:2020-08-29 21:43:46
【问题描述】:

使用 ASP.NET Core 3.1 和 Identity Server 4,我从 SPA 开始登录过程。

登录后,我对 IS4 应用身份验证 cookie 有以下声明:

sub                              1
AspNet.Identity.SecurityStamp    RRHNY65RQMUHTXXSIZKT2YORA3QQ2WAC
role                             Admin
preferred_username               info@example.com
name                             info@example.com
email                            info@example.com
email_verified                   true
amr                              pwd
idp                              local
auth_time                        1598736198

为什么name 声明将电子邮件作为其值?

然后我实现了 ProfileService 以将 name 声明替换为实际用户名。

当我检查水疗中心的索赔时,更换已经完成......

但在 IS4 应用程序上,身份验证 Cookie 仍会收到电子邮件为 name 声明。

为什么?

【问题讨论】:

    标签: identityserver4 asp.net-core-3.1 asp.net-core-identity


    【解决方案1】:

    身份令牌中的声明是否正确?

    如果它在 ID 令牌中是正确的,那么您可能在您的 ASP.NET Core 应用程序中实现了一些声明转换。

    【讨论】:

    • 我刚刚用解决方案添加了对我自己的问题的答案。我想我发布的是正确的方法来做到这一点。你怎么看?
    【解决方案2】:

    问题似乎在于 ASP.NET Core 3.1 如何定义声明。

    然后我实现了UserClaimsPrincipalFactory 来更新name 声明:

    public class UserClaimsPrincipalFactory : UserClaimsPrincipalFactory<User> {
    
      public UserClaimsPrincipalFactory(UserManager<User> userManager, IOptions<IdentityOptions> optionsAccessor) : base(userManager, optionsAccessor) { } 
    
      public async override Task<ClaimsPrincipal> CreateAsync(User user) {
    
        ClaimsPrincipal principal = await base.CreateAsync(user);
        ClaimsIdentity identity = (ClaimsIdentity)principal.Identity;
    
        Claim claim = identity.FindFirst("name");
      
        if (claim != null)
          identity.RemoveClaim(claim);
    
        identity.AddClaim(new Claim("name", user.Name));
    
        return principal;
    
      }
    
    }
    

    现在 Authentication Cookie 和 Token 拥有相同的声明。

    使用 IdentityServer4 的 ProfileService 只会更改令牌上的声明:

      public class ProfileService : IProfileService {
        
        private readonly IUserClaimsPrincipalFactory<User> _claimsFactory;
        private readonly UserManager<User> _userManager;
    
        public ProfileService(UserManager<User> userManager, IUserClaimsPrincipalFactory<User> claimsFactory) {
          _userManager = userManager;
          _claimsFactory = claimsFactory;
        }
    
        public async Task GetProfileDataAsync(ProfileDataRequestContext context) {
          // Not doing any change here
          User user = await _userManager.GetUserAsync(context.Subject);
          ClaimsPrincipal principal = await _claimsFactory.CreateAsync(user); 
          context.IssuedClaims = principal.Claims.ToList();
        }
    
        public async Task IsActiveAsync(IsActiveContext context) {
          User user = await _userManager.GetUserAsync(context.Subject);
          context.IsActive = (user != null) && user.Enabled;
        }
        
      }
    

    我想 ProfileService 在不使用 Asp.Net Core Identity 时更有用?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-11
      • 2018-12-29
      • 2021-01-11
      • 2020-11-05
      • 2020-11-09
      • 1970-01-01
      • 2017-10-29
      • 2017-06-26
      相关资源
      最近更新 更多