You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Linux PHP Web应用后端AD鉴权403问题及权限验证需求

问题分析与解决方案

一、后端调用/.auth/me返回403的原因

后端PHP调用/.auth/me报403,核心原因是后端请求没带对会话Cookie。前端JS能跑通是因为浏览器自动帮你带了AppServiceAuthSession Cookie,但PHP发起的curl请求默认不会继承这个Cookie,身份验证模块自然不认,直接返回403。另外,Azure App Service的内置auth模块对后端请求的校验逻辑和前端不一样,后端得主动把身份凭证带上才行。

二、后端实现用户权限校验的两种可行方法

方法1:修复/.auth/me的后端调用

要让PHP能成功调用/.auth/me,手动把AppServiceAuthSession Cookie传进去就行,代码示例:

// 先从当前请求里拿auth会话的Cookie
$authCookie = $_COOKIE['AppServiceAuthSession'] ?? '';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://' . $_SERVER['HTTP_HOST'] . '/.auth/me');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 关键:带上身份Cookie
curl_setopt($ch, CURLOPT_COOKIE, 'AppServiceAuthSession=' . $authCookie);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode === 200) {
    $userData = json_decode($response, true);
    // 从返回的用户数据里提取UPN或者ObjectID,后面调用Graph API要用
    $userUpn = '';
    foreach ($userData[0]['user_claims'] as $claim) {
        if ($claim['typ'] === 'upn') {
            $userUpn = $claim['val'];
            break;
        }
    }
} else {
    http_response_code(403);
    exit('无权访问');
}

注意:如果你的Web App开了HTTPS,curl请求一定要用HTTPS,别搞混合内容。

方法2:用应用服务主体通过Graph API查用户组

既然你已经配好了能访问Graph API的应用服务主体,这方法比调用/.auth/me更可靠,具体步骤:

  1. 先拿应用服务主体的Graph令牌:
$tenantId = '你的租户ID';
$clientId = '应用服务主体的ID';
$clientSecret = '应用服务主体的密钥';

$tokenUrl = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token";
$postData = [
    'grant_type' => 'client_credentials',
    'client_id' => $clientId,
    'client_secret' => $clientSecret,
    'scope' => 'https://graph.microsoft.com/.default'
];

$ch = curl_init($tokenUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$tokenResponse = json_decode(curl_exec($ch), true);
curl_close($ch);

$graphToken = $tokenResponse['access_token'] ?? '';
  1. 调用Graph API检查用户是否在目标组里:
    先从/.auth/me或者前端传过来的参数里拿到用户的Azure AD ObjectID,然后调用checkMemberGroups接口:
$userId = '用户的Azure AD Object ID';
$targetGroupId = '你要校验的组ID';

$graphUrl = "https://graph.microsoft.com/v1.0/users/$userId/checkMemberGroups";
$postData = json_encode(['groupIds' => [$targetGroupId]]);

$ch = curl_init($graphUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $graphToken,
    'Content-Type: application/json'
]);

$groupCheckResponse = json_decode(curl_exec($ch), true);
curl_close($ch);

// 看返回结果里有没有目标组ID,有就是有权限
if (in_array($targetGroupId, $groupCheckResponse['value'] ?? [])) {
    // 放行,显示管理员页面
} else {
    http_response_code(403);
    exit('无管理员权限');
}

三、踩坑提醒

  • 应用服务主体必须要有Directory.Read.All的应用权限(不是委托权限),不然调用Graph API会报错,得去Azure AD的应用注册里配置好权限并授予管理员同意。
  • 别把客户端密钥硬写在代码里,丢去Azure App Service的配置项(Configuration > Application settings)里存,用getenv('CLIENT_SECRET')取就行,安全多了。
  • 如果之前开IP限制导致应用访问不了自己,现在关了之后要是Graph API还有IP问题,可以去应用注册的企业应用里加信任IP范围,或者把Web App的出站IP加进允许列表。

内容的提问来源于stack exchange,提问作者kithril

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 04:57:08