You need to enable JavaScript to run this app. 基于IdentityServer4的.Net Core后台应用用户模拟Token获取问题
优惠活动
大模型
产品
解决方案
定价
更多

基于IdentityServer4的.Net Core后台应用用户模拟Token获取问题

问题根因

你当前使用的ClientCredentials(客户端凭证)授权模式,设计目标就是无用户参与的服务间通信场景,签发的访问令牌天然只包含客户端本身的身份声明,不会携带任何终端用户的身份信息。因此服务端拿到这个令牌做权限校验时,只能识别出后台服务的身份,无法定位到任务对应的终端用户。

适配场景的实现路径

要实现后台任务代表关联用户发起API调用的效果,IdentityServer4 对应两种可落地的实现方案,可根据自身安全等级要求选择:

方案一:OAuth 2.0 On-Behalf-Of(OBO,代表用户)委托流程(生产环境优先推荐)

这个流程是OAuth标准专门为“无用户实时交互的服务端,代表已认证过的用户调用下游API”设计的,安全性最高,完全匹配你的后台任务场景。

核心流程逻辑

  • 用户在初始的交互式前端登录环节,会获得一个绑定了自身完整身份、指向你的后台服务的短有效期访问令牌
  • 后台服务在接收用户提交的任务时,将这个用户的原始访问令牌、任务关联的用户标识一起持久化存储
  • 后台任务异步执行需要调用业务API时,取出对应任务关联的用户原始令牌,向IdentityServer发起令牌委托请求
  • IdentityServer 校验原始令牌有效性、确认请求的后台服务具备委托调用权限后,会签发新的访问令牌——这个令牌会完整携带原始用户的身份声明(用户ID、角色、权限等),同时将受众标记为你指定的业务API,可直接通过API的身份校验。

服务端客户端配置调整

将原来的客户端配置改造为允许OBO委托授权:

new Client
{
    ClientId = "background-service",
    ClientSecrets = { new Secret("your-encrypted-secret".Sha256()) },
    // 替换原有的ClientCredentials授权类型,开启代表用户的JWT Bearer委托授权
    AllowedGrantTypes = GrantTypes.JwtBearer,
    // 保留原有可访问的API作用域
    AllowedScopes = { "api1" },
    // 配置允许从原始用户令牌中复制需要的用户声明到新令牌
    ClientClaimsPrefix = "",
    Claims = new List<ClientClaim>
    {
        new ClientClaim("sub", "*"),
        new ClientClaim("name", "*"),
        new ClientClaim("role", "*")
    }
}

后台服务端的客户端代码调整

替换原有的客户端凭证令牌请求逻辑,使用IdentityModel提供的JWT Bearer请求方法:

var identityServerClient = new HttpClient();
// 拉取IdentityServer的公开发现文档,逻辑和原有实现一致
var disco = await identityServerClient.GetDiscoveryDocumentAsync("https://localhost:5001");

// 发起代表用户的令牌委托请求
var oboTokenResponse = await identityServerClient.RequestJwtBearerTokenAsync(new JwtBearerTokenRequest
{
    Address = disco.TokenEndpoint,
    ClientId = "background-service",
    ClientSecret = "your-encrypted-secret",
    Scope = "api1",
    // 关键:填入当前待处理数据对应的用户原始访问令牌
    Assertion = "任务关联的用户原始访问令牌"
});

// 新生成的令牌自动携带完整用户声明,后续API调用逻辑和原有一致
var apiClient = new HttpClient();
apiClient.SetBearerToken(oboTokenResponse.AccessToken);

方案二:高信任场景下的客户端声明透传(仅适合完全可控的内网环境)

如果你的后台服务和IdentityServer属于同一个完全可信的内网边界,不需要引入原始用户令牌的存储开销,可以直接在客户端认证通过后,由后台服务传入需要关联的用户标识,由IdentityServer自动将对应用户的声明注入到生成的令牌中。

风险提示

这个方案的安全等级较低:如果后台服务被攻破,攻击者可以直接模拟任意用户身份发起请求,仅建议在内部封闭系统中使用,不要将相关服务暴露在公网环境。

实现要点

  • 服务端保持原有的ClientCredentials授权类型配置
  • 自定义IdentityServer的令牌签发事件,当收到后台服务的客户端凭证请求时,读取请求中携带的target_user_id参数,从用户存储中查询对应用户的所有身份声明,注入到最终签发的访问令牌中
  • 后台服务发起客户端凭证请求时,在请求参数中传入当前处理任务对应的target_user_id即可。
常见踩坑提示
  • 不要为了简化流程使用资源所有者密码模式(ResourceOwnerPassword):这种模式要求后台服务存储用户的明文账号密码,一旦服务被攻破会导致全量用户凭据泄露,风险远高于OBO流程
  • 严格控制令牌有效期:原始的用户访问令牌不要设置过长的过期时间,后台任务执行过程中如果遇到令牌过期,需要配套实现基于刷新令牌的续期逻辑,不要将长期有效的用户凭据持久化存储在后台服务中
  • 严格收敛权限范围:给后台服务的委托权限,只开放它实际需要调用的API作用域,避免权限过度授予带来的安全风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.30 12:15:07