IdentityServer4 端点如何同时验证客户端身份与用户凭证?

方案结论
不建议同时传递两个access token,使用IdentityServer 4内置的令牌声明嵌入方案即可满足你的需求,实现成本更低、安全性也更高。
具体实现步骤
1. IdentityServer 4 端配置调整
你的场景本质是需要在同一个访问令牌中同时携带客户端身份信息和用户身份信息,IS4默认支持该能力:
- 首先确保你的PKCE SPA客户端在IS4中拥有固定的唯一
ClientId,比如命名为official_frontend_spa,作为你前端站点的唯一身份标识 - 配置API资源时,显式要求将
client_id(客户端ID)、sub(用户唯一标识)以及你需要的其他用户/客户端声明嵌入到发给API的访问令牌中,示例配置如下:
new ApiResource("your_api_service", "你的API服务") { Scopes = { "api_access" }, // 显式指定要包含到令牌中的声明 UserClaims = { "client_id", "sub", "name", "role" } }
完成配置后,用户登录后SPA拿到的access token里会同时包含用户身份声明和客户端身份声明。
2. API端点验证逻辑调整
你需要在目标API端点增加两层校验即可:
- 第一层:正常校验access token的合法性,包括签名有效性、过期时间、受众(aud)是否匹配你的API服务
- 第二层:从令牌解析出的声明中做两个校验:
- 校验
client_id声明的值是否等于你预设的前端站点客户端ID(如official_frontend_spa),确认调用方确实是你的前端站点 - 校验
sub(或其他用户身份声明)存在且为合法用户ID,确认请求对应真实有效的用户身份
- 校验
为什么不推荐双token方案
- PKCE SPA属于公开客户端,本身无法安全存储静态密钥,如果单独申请客户端身份的token,会大幅增加凭据泄露的风险
- 双token需要额外处理存储、传输、校验逻辑,会提升不必要的维护成本
- 单token携带全量声明的方案已经覆盖你的需求,安全系数和实现效率都更高
备选方案(特殊场景可选)
如果后续有更复杂的身份代理需求,比如需要第三方客户端代表用户调用API,你可以采用RFC 8693定义的令牌交换(Token Exchange)规范,IdentityServer 4也支持该扩展,但当前场景下不需要用到。
内容的提问来源于stack exchange,提问作者No1Lives4Ever
相关产品推荐
相关产品推荐

