Azure AD B2C中调用revokeSignInSessions需两次才生效问题咨询
问题背景
为处理用户登出场景,尝试通过Graph API的revokeSignInSessions接口撤销Azure AD B2C的刷新令牌,但发现需调用两次接口才能让令牌彻底失效。完整操作流程如下:
获取授权码
GET https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/authorize? client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6 &response_type=code &redirect_uri=https://jwt.ms/ &response_mode=query &scope=offline_access%20https://{tenant-name}/{app-id-uri}/{scope} &state=arbitrary_data_you_can_receive_in_the_response通过授权码获取刷新令牌
POST https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/token Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6&scope=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6%20offline_access&code={code-from-step-1}&client_secret=QHS8i~...使用刷新令牌获取新的访问令牌
POST https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/token Content-Type: application/x-www-form-urlencoded grant_type=refresh_token&client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6&client_secret=QHS8i~...&scope=openid%20offline_access&refresh_token={refresh-token-from-step-2}
调用revokeSignInSessions接口后:
POST https://graph.microsoft.com/v1.0/users/{user_id}/revokeSignInSessions
- 等待5-30分钟后,原刷新令牌仍可用于获取新访问令牌
- 第二次调用该接口后,原刷新令牌及首次撤销后获取的新刷新令牌才彻底失效
refreshTokensValidFromDateTime和signInSessionsValidFromDateTime属性已按预期重置为当前时间,浏览器端用户已被强制重新登录
可能原因分析
刷新令牌轮换机制的边缘场景
Azure AD B2C默认启用刷新令牌轮换,每次使用刷新令牌获取新令牌时会返回新的刷新令牌,旧令牌进入短暂宽限期。revokeSignInSessions可能仅标记了当前活跃的刷新令牌,宽限期内的旧令牌未被立即失效,第二次调用才覆盖所有关联令牌。Graph API与B2C令牌验证逻辑的同步延迟
revokeSignInSessions更新用户属性后,B2C的令牌验证服务可能未实时同步该状态,第一次调用仅触发属性更新,第二次调用才强制刷新验证缓存。多刷新令牌实例未被一次性覆盖
若在撤销前已通过刷新操作生成多个刷新令牌实例,第一次调用可能仅处理了部分令牌,第二次调用才遍历所有关联令牌完成撤销。
验证与解决方案
直接使用Azure AD B2C OAuth2 Revoke端点
针对刷新令牌的撤销,优先使用B2C原生的OAuth2 revoke端点,该端点专门用于撤销指定令牌,避免Graph API会话撤销逻辑的局限性:POST https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/revoke Content-Type: application/x-www-form-urlencoded client_id={client-id}&client_secret={client-secret}&token={refresh-token}&token_type_hint=refresh_token确认接口调用的有效性
每次调用revokeSignInSessions后,检查响应状态码为200 OK,且返回的id与用户ID匹配,确保接口调用成功。调整撤销逻辑的时序
若必须依赖Graph API,可在第一次调用revokeSignInSessions后等待1-2分钟,再执行第二次调用,确保服务端状态同步完成。
结论
该现象更倾向于Azure AD B2C服务端的边缘场景问题,而非操作错误。结合B2C原生的OAuth2 revoke端点与Graph API的会话撤销,可实现更可靠的登出流程。
内容的提问来源于stack exchange,提问作者Phúc Trần

