SAML2.0认证后调用Graph API:令牌获取及用户组信息查询
当Azure AD返回的SAML断言中因用户组过多而不包含组信息,转而提供Graph API地址时,你需要获取OAuth 2.0访问令牌来调用该API——注意,SAML断言本身不能直接用于调用Graph API,需要转换为针对Azure AD Graph API的专用访问令牌。下面是两种可靠的实现方式:
方法一:用SAML断言直接交换访问令牌
这种方式利用你的Web应用已获取的SAML断言,直接向Azure AD令牌端点请求访问令牌:
准备请求参数
向Azure AD的令牌端点(https://login.microsoftonline.com/{tenant-id}/oauth2/token)发送POST请求,参数如下:grant_type:设置为urn:ietf:params:oauth:grant-type:saml2-bearer(对应SAML 2.0断言)assertion:将你的SAML断言去除所有换行符后,进行Base64编码client_id:你的Web应用在Azure AD中注册的客户端IDresource:固定为https://graph.windows.net(Azure AD Graph API的资源标识符)client_secret:如果你的Web应用是机密客户端(绝大多数Web应用都是),需要添加这个参数,值为应用注册时生成的客户端密钥
处理响应
成功请求后,你会收到包含access_token的JSON响应,这个令牌就是调用目标Graph API所需的身份凭据。
方法二:使用On-Behalf-Of(OBO)流程
如果你的Web应用已经从SAML断言中解析出用户的ID令牌(JWT格式),可以使用OBO流程来获取访问令牌,这种方式更适合需要链式调用API的场景:
前提准备
- 确保你的Web应用在Azure AD的应用注册中已启用OBO流程
- 已为应用授予Azure AD Graph API的相关权限(比如
Directory.Read.All或Group.Read.All),并且完成了管理员同意(针对租户级权限)
构造请求
向Azure AD的v2.0令牌端点(https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token)发送POST请求,参数如下:grant_type:urn:ietf:params:oauth:grant-type:jwt-bearerclient_id:你的Web应用客户端IDclient_secret:你的Web应用客户端密钥assertion:用户的ID令牌(JWT)scope:根据需求指定权限,比如https://graph.windows.net/user.read https://graph.windows.net/group.read.allrequested_token_use:on_behalf_of
关键注意事项
- 权限配置:必须确保你的Web应用拥有调用Graph API的权限,否则会返回权限不足的错误
- 断言有效性:SAML断言或ID令牌必须在有效期内,且签名有效
- API调用方式:拿到访问令牌后,将其放在请求的
Authorization头部,格式为Bearer {access_token},再调用目标Graph API
另外补充一点:微软现在推荐使用Microsoft Graph API替代Azure AD Graph API,对应的获取用户组的端点是https://graph.microsoft.com/v1.0/users/{user-id}/memberOf,如果你的场景允许,建议迁移到这个新API,后续维护和功能支持会更完善。
内容的提问来源于stack exchange,提问作者Abhishek Agarwal

