身份服务器配置文件服务中的声明更改未反映在身份验证 Cookie 中

Claim change in Identity Server's ProfileService is not reflected in Authentication Cookie

使用 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 声明的那样。

为什么?

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

如果它在 ID-token 中是正确的,那么您可能在 ASP.NET 核心应用程序中实施了一些声明转换。

问题似乎出在 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;

  }

}

现在身份验证 Cookie 和令牌具有相同的声明。

使用 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 时更有用?