Laravel+Vue3集成Azure认证:API验证用Access Token还是ID Token?
针对Azure AD认证下Laravel API验证的最佳实践
先澄清一个关键误区
Azure AD颁发的Access Token绝大多数场景下是JWT格式,如果你拿到的不是,大概率是前端请求配置错误:
- 确认msal请求的
scope包含你的Laravel API对应的Azure AD应用程序ID URI(格式如api://{你的API应用ID}/access_as_user),别只请求openid/profile这类仅用于ID Token的scope - 检查Azure AD里API应用的「公开API」设置,是否已正确定义权限范围,且前端应用已被授予该范围的访问权限
用jwt.io解码拿到的Access Token,就能确认是否为JWT格式。
正确的Laravel API验证方案
别用普通JWT库硬套ID Token的验证逻辑,推荐两种方案:
方案一:遵循OIDC规范手动验证
直接按照Azure AD的OIDC验证流程实现,步骤如下:
- 从Azure AD的元数据端点(
https://login.microsoftonline.com/{租户ID}/v2.0/.well-known/openid-configuration)获取公钥和验证配置 - 自定义Laravel中间件,提取请求头里的
Authorization: Bearer {access-token} - 验证令牌的核心字段:
- 签名:用Azure AD的公钥验证(避免本地硬编码公钥,定期从元数据更新)
- 受众(
aud):必须匹配你的API应用ID - 颁发者(
iss):必须和元数据里的issuer一致 - 有效期:确保令牌未过期
- 授权方(
azp):必须是你的前端应用ID
方案二:用第三方包简化实现
可以用firebase/php-jwt包快速搭建验证逻辑,示例中间件代码:
public function handle(Request $request, Closure $next) { $token = $request->bearerToken(); if (!$token) { return response()->json(['message' => 'Unauthorized'], 401); } // 缓存元数据和公钥,避免每次请求调用外部接口 $config = Cache::remember('azure_ad_oidc_config', 3600, function () { return Http::get('https://login.microsoftonline.com/{租户ID}/v2.0/.well-known/openid-configuration')->json(); }); $jwks = Cache::remember('azure_ad_jwks', 3600, function () use ($config) { return Http::get($config['jwks_uri'])->json(); }); try { $decoded = \Firebase\JWT\JWT::decode( $token, $jwks, ['RS256'] ); // 核心验证逻辑 if ($decoded->aud !== '{你的API应用ID}' || $decoded->iss !== $config['issuer']) { return response()->json(['message' => 'Invalid token audience or issuer'], 401); } // 将用户信息挂载到请求,后续业务逻辑可直接调用 $request->attributes->set('azure_user', $decoded); } catch (\Exception $e) { return response()->json(['message' => 'Invalid token'], 401); } return $next($request); }
提前安装依赖:composer require firebase/php-jwt
为什么不能用ID Token验证API?
微软明确不推荐这种做法,核心原因:
- ID Token的受众是前端应用,不是API,用它验证API会打破权限边界
- ID Token仅包含用户身份信息,没有API权限相关声明,无法做细粒度的访问控制
- 从安全角度,ID Token的设计用途是身份认证,而非资源授权
额外优化建议
- 前端用msal专门为API请求获取Access Token,不要复用ID Token
- 缓存Azure AD的元数据和公钥,提升验证性能
- 实现Access Token自动刷新逻辑,过期时用Refresh Token获取新令牌
- 在Azure AD中配置API的权限范围,结合Laravel实现基于角色/权限的访问控制(验证令牌里的
roles或scp字段)
内容的提问来源于stack exchange,提问作者basil3
相关产品推荐
相关产品推荐

