IdentityServer4刷新令牌时身份声明丢失问题咨询
问题分析与解答
一、IdentityServer4中ProfileService接收的Claims Identity构造逻辑
IdentityServer4处理令牌刷新请求时,不会触发完整的Asp.Net Core登录流程,而是直接从关联的用户会话数据中提取核心身份信息构造Subject:
- 刷新请求验证通过后,IdentityServer会读取与该刷新令牌绑定的用户会话,仅提取
sub(用户唯一标识)这类核心声明来初始化Subject。 - 这个
Subject的Claims集合,只包含IdentityServer认定为用户基础身份的数据,也就是首次登录时存入自身会话的核心声明,并非经过IClaimsTransformation转换后的完整集合。
二、ProfileService无法获取IClaimsTransformation声明的原因
IClaimsTransformation和IdentityServer的令牌生成流程属于两个独立的执行链路:
IClaimsTransformation是Asp.Net Core Authentication中间件的一部分,仅在完整登录请求(比如首次调用SignInAsync)或访问Asp.Net Core授权保护资源时,才会对当前请求的Principal做转换。- 令牌刷新请求属于IdentityServer的令牌端点操作,处理时不会走完整的Asp.Net Core身份验证管道,自然不会执行
IClaimsTransformation的TransformAsync方法。你在TransformAsync中看到的声明,是其他请求场景下的结果,和刷新令牌流程无关。
另外,你通过HttpContext.SignInAsync(issuer)添加的AdditionalClaims,如果未配置为持久化到IdentityServer用户会话,刷新时也无法被读取。默认情况下,这些额外声明仅在首次生成身份令牌时被包含,若未标记为会话持久化内容,刷新流程不会主动加载。
三、可行的解决方法
在ProfileService中主动加载声明
不要依赖IClaimsTransformation,直接在自定义ProfileService的GetProfileDataAsync方法中,从数据源(如数据库、用户存储)加载所需声明并添加到输出集合:public class CustomProfileService : DefaultProfileService { private readonly IUserRepository _userRepository; public CustomProfileService(IUserRepository userRepository, ILogger<DefaultProfileService> logger) : base(logger) { _userRepository = userRepository; } public override async Task GetProfileDataAsync(ProfileDataRequestContext context) { await base.GetProfileDataAsync(context); // 根据用户ID加载额外声明 var userId = context.Subject.GetSubjectId(); var additionalClaims = await _userRepository.GetUserAdditionalClaims(userId); context.IssuedClaims.AddRange(additionalClaims); } }将声明持久化到用户会话
若希望首次登录的声明在刷新时复用,可在登录时通过AuthenticationProperties标记声明需要持久化:var authProps = new AuthenticationProperties { IsPersistent = true }; // 也可手动指定要持久化的声明类型 authProps.StoreTokens(new[] { new AuthenticationToken { Name = "custom_claims", Value = JsonConvert.SerializeObject(additionalLocalClaims) } }); await HttpContext.SignInAsync(issuer, authProps);不过这种方式不如ProfileService主动加载可靠,会话存储的声明存在过期或丢失风险。
内容的提问来源于stack exchange,提问作者Merijn
相关产品推荐
相关产品推荐

