如何在Azure AD OAuth2流程中传递PatientId至令牌响应JSON
Azure AD OAuth2流透传PatientId到令牌响应的实现方案
原生Azure AD v2.0端点默认不支持直接向令牌响应根节点追加自定义字段,也不会自动透传授权阶段的自定义参数到令牌颁发环节,可根据改造成本选择以下两种可落地方案:
方案1:代理令牌端点(改造成本最低,推荐)
不需要调整Azure AD高级配置,通过一层轻量代理完成参数透传和响应拼接,步骤如下:
- 授权请求阶段绑定参数
构造跳转至AAD/v2.0/authorize的请求时,将防CSRF令牌与PatientId拼接后做签名,放入标准state参数中,避免参数被篡改:// state构造示例 var csrfToken = Guid.NewGuid().ToString("N"); var payload = JsonSerializer.Serialize(new { csrf = csrfToken, pid = "123456" }); var base64Payload = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(payload)); // 用应用私钥对payload做HMAC签名 var signature = ComputeHmac256(base64Payload, appSecret); var stateValue = $"{base64Payload}.{signature}"; - 授权回调阶段建立映射
AAD授权完成重定向回你的回调地址时,会携带authorization code与之前传入的state:- 校验state的签名合法性,解析出其中的PatientId
- 以
code为键、PatientId为值存入分布式缓存(内存/Redis均可),过期时间设置为10分钟(与AAD授权码有效期保持一致)
- 代理令牌请求拼接响应
不要将AAD原生~/v2.0/token地址直接提供给第三方,替换为你自己托管的代理端点:- 代理收到第三方的令牌请求后,原样转发至AAD原生令牌端点
- 拿到AAD返回的标准令牌响应后,从当前请求中取出
code参数,查询缓存得到对应的PatientId - 将
"patient": "<查询到的PatientId>"字段追加到响应JSON根节点,返回给第三方 - 删除缓存中该code对应的记录,避免重复使用
方案2:使用Azure AD自定义身份验证扩展(无代理,原生端点支持)
如果不想额外维护代理层,可以使用Azure AD原生的令牌颁发事件扩展实现:
- 首先在Azure AD对应应用注册中启用「自定义身份验证扩展-令牌颁发起始事件」,配置你自己托管的扩展API地址
- 构造
/authorize请求时,将PatientId作为自定义查询参数传入,在自定义策略中将该参数声明为流级别的持久化变量,全程绑定到当前认证上下文 - AAD生成令牌响应前,会主动向你配置的扩展API发送POST请求,携带当前认证流的全量上下文(包括你传入的PatientId、用户身份信息、令牌内容)
- 扩展API校验请求合法性后,提取PatientId,按照Azure AD扩展协议要求返回指令,要求AAD在最终令牌响应的根节点追加
patient字段即可
注意事项
- 绝对不要 传递未签名的PatientId,必须做签名校验,防止恶意用户篡改参数越权访问其他患者数据
state参数的核心作用是CSRF防护,不要为了传PatientId省略CSRF令牌的生成与校验逻辑- 授权码与PatientId的映射缓存必须设置短过期时间,授权码使用后立即删除对应缓存记录,避免数据泄露
内容的提问来源于stack exchange,提问作者eric_the_animal
相关产品推荐
相关产品推荐

