You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IdentityServer4:移除access_token的entity Claim并保留ClaimsPrincipal内该Claim的方法

解决IdentityServer4中Token体积与ClaimsPrincipal获取Claim的矛盾

核心思路

把"entity"声明从Access Token中剥离,仅通过**用户信息端点(UserInfo Endpoint)**返回,既减小Token体积,又能让客户端通过标准流程获取该声明,无需额外调用API。

具体实现(修改ProfileService)

修改GetProfileDataAsync方法,根据请求来源区分是否返回"entity"声明:

public async Task GetProfileDataAsync(IdentityServer4.Models.ProfileDataRequestContext context)
{
    var user = await _userManager.GetUserAsync(context.Subject);
    var principal = await _claimsFactory.CreateAsync(user);            
    // 获取用户所有声明
    var allClaims = principal.Claims.Select(c => new System.Security.Claims.Claim(c.Type, c.Value)).ToList();
    // 分离出entity声明
    var entityClaims = allClaims.Where(x => x.Type == "entity").ToList();
    // 基础声明(排除entity)
    var baseClaims = allClaims.Where(x => x.Type != "entity").ToList();

    // 先添加基础声明到IssuedClaims
    context.IssuedClaims.AddRange(baseClaims);
    // 添加角色声明
    var roleClaims = _roleService.GetRoleClaims(user);
    context.IssuedClaims.AddRange(roleClaims);

    // 判断是否是UserInfo端点的请求,如果是则添加entity声明
    if (context.Callers.Contains("UserInfo"))
    {
        context.IssuedClaims.AddRange(entityClaims);
    }
}

客户端获取"entity"声明的方式

客户端拿到Access Token后,向IdentityServer的/connect/userinfo端点发起GET请求,将Access Token放在Authorization头(格式为Bearer {token}),即可拿到包含"entity"的完整用户声明集合。客户端可将响应解析后注入ClaimsPrincipal,无需额外API调用。

补充说明

  • 确保客户端配置中已包含profile scope(UserInfo端点默认依赖该scope),也可以为"entity"声明单独创建自定义scope,客户端请求该scope即可获取对应声明。
  • 该方案完全遵循OAuth2/OpenID Connect标准流程,不会引入额外复杂度。

内容的提问来源于stack exchange,提问作者user1884330

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 09:15:33