Azure AD中刷新后的id_token无签名,如何验证及解决?
解决Azure AD刷新id_token时缺少签名的问题
首先,你遇到的这个无签名id_token问题,大概率是端点版本不匹配导致的——你用了v2.0的密钥端点(/discovery/v2.0/keys)验证JWT,但刷新请求却发到了v1版本的token端点(/oauth2/token),两者的JWT格式、签名机制存在差异,才会返回不完整的id_token。
一、修正刷新请求的端点
你需要把刷新请求切换到v2.0版本的token端点,和密钥端点保持版本一致。调整后的cURL命令如下:
curl --request POST \ --url https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data 'client_id=your_client_id&refresh_token=your_refresh_token&grant_type=refresh_token&client_secret=your_client_secret&scope=openid profile'
注意几个关键调整:
- 端点路径改为
/oauth2/v2.0/token - scope建议补充
profile(openid是必填项,加上profile能确保返回结构完整的id_token) - 确保所有参数都做了正确的URL编码(比如client_id、client_secret里的特殊字符要转义)
调整后返回的id_token应该会包含完整的JWT三部分(头部、负载、签名),可以正常用v2.0的公钥验证。
二、如果刷新仍有问题的替代方案
要是调整端点后还是无法获取带签名的id_token,可以试试以下两种可行方案:
1. 用静默授权流程获取新id_token
静默授权不需要用户手动登录,通过前端iframe发起授权请求并带上prompt=none参数,就能在用户已登录的情况下自动获取新授权码,进而换取完整的id_token和refresh_token。示例授权请求(前端跳转用):
https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize? client_id=your_client_id &response_type=code &redirect_uri=your_redirect_uri &scope=openid profile &prompt=none &state=your_state_value
后端拿到授权码后,走正常的授权码换token流程即可得到合规的id_token。
2. 改用access_token做授权验证
其实id_token的核心作用是用户身份认证,而接口授权验证更适合用access_token。你可以调整架构逻辑:
- 认证成功后,用access_token作为每个请求的授权凭证
- 通过Azure AD的令牌验证机制(或公钥)验证access_token的有效性
- 当access_token过期时,用refresh_token刷新获取新的access_token和id_token
这种方式更贴合OAuth2的设计规范,也能避开id_token刷新的特殊问题。
三、额外排查点
- 检查你的应用注册所属的端点版本:如果是v2应用,必须全程使用v2系列端点;v1应用则对应v1端点,密钥端点要换成
/discovery/v1.0/keys - 确认refresh_token未过期:Azure AD的refresh_token有效期通常为90天,过期后需要用户重新登录获取新的refresh_token
内容的提问来源于stack exchange,提问作者Nitin
相关产品推荐
相关产品推荐

