如何为已登录用户获取Azure AD访问令牌以查询组身份?
解决Azure App Service PHP网站获取登录用户AD组信息的问题
我之前也碰到过一模一样的场景,你遇到的InvalidAuthenticationToken错误核心原因是:从请求头拿到的“access token”大概率是ID Token(仅用于身份验证)或者是针对App Service自身的访问令牌,而不是针对Microsoft Graph的有效访问令牌——这类令牌的受众(aud字段)不是https://graph.microsoft.com,所以Graph API会拒绝解析它。
下面是具体的解决步骤:
1. 配置App Service认证,获取针对Graph的访问令牌
首先需要让App Service的Easy Auth(内置Azure AD认证)返回能调用Graph API的令牌:
- 登录Azure Portal,找到你的App Service,进入Authentication页面
- 点击Advanced settings,在Allowed token audiences里添加
https://graph.microsoft.com - 保存设置,这样用户登录后,App Service会自动获取针对Graph的访问令牌
2. 给App Service对应的AD应用注册添加Graph权限
Easy Auth依赖一个Azure AD应用注册来处理认证,需要给这个应用添加调用Graph API获取组信息的权限:
- 在App Service的Authentication页面,找到Azure Active Directory提供商的Application (client) ID
- 打开Azure AD的应用注册,搜索并找到这个应用
- 进入API权限页面,点击添加权限,选择Microsoft Graph
- 选择委托权限(因为是以已登录用户的身份调用),添加
GroupMember.Read.All(用于获取用户直接所属组)或者Directory.Read.All(更宽泛的目录访问权限) - 添加完成后,点击授予管理员同意(必须完成这一步,否则权限不会生效)
3. 在PHP代码中获取有效令牌并调用Graph API
App Service提供了一个内置的端点/.auth/me,可以获取当前登录用户的所有身份令牌信息,我们可以从这里拿到针对Graph的访问令牌:
// 调用App Service内置的身份信息端点 $authEndpoint = 'https://' . getenv('WEBSITE_HOSTNAME') . '/.auth/me'; $ch = curl_init($authEndpoint); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); $authResponse = curl_exec($ch); curl_close($ch); $authData = json_decode($authResponse, true); $graphAccessToken = null; // 遍历令牌,找到受众为Graph的有效访问令牌 foreach ($authData[0]['access_token'] as $tokenEntry) { if ($tokenEntry['aud'] === 'https://graph.microsoft.com') { $graphAccessToken = $tokenEntry['access_token']; break; } } if ($graphAccessToken) { // 调用Graph API获取用户所属组 $graphEndpoint = 'https://graph.microsoft.com/v1.0/me/memberOf'; $ch = curl_init($graphEndpoint); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $graphAccessToken, 'Accept: application/json' ]); $groupResponse = curl_exec($ch); curl_close($ch); // 解析并处理组数据 $groups = json_decode($groupResponse, true); print_r($groups); } else { echo "未找到针对Microsoft Graph的有效访问令牌,请检查App Service配置"; }
额外注意事项
- 如果你需要获取嵌套组(用户所属组的子组),可以调用
https://graph.microsoft.com/v1.0/me/transitiveMemberOf - 确保你的App Service运行在支持Easy Auth的定价层(Basic及以上)
- 可以用本地的JWT解析工具查看令牌的
aud字段,确认它是否是https://graph.microsoft.com,以此验证令牌是否有效
内容的提问来源于stack exchange,提问作者Flinsch




