Azure B2C 对接 Laravel Socialite 无法获取 ID 令牌问题咨询
问题根因
你使用的通用Azure AD Socialite Provider原生适配普通Azure AD场景,未兼容Azure B2C的特殊规则,仅修改授权地址不足以覆盖全流程,异常对应原因如下:
- 你仅重写了
getAuthUrl授权地址,未同步修改getTokenUrl令牌请求地址,仍默认请求login.microsoftonline.com域名,同时未携带B2C要求的用户流(Policy)参数,导致Socialite自动拿授权码换令牌的逻辑失效 - 通用Azure Provider拿到令牌后默认请求Microsoft Graph接口拉取用户信息,但Azure B2C签发的访问令牌仅适用于你自己的业务API,无Graph接口调用权限,因此触发报错
userFromToken方法默认依赖Graph接口校验令牌、拉取用户数据,你传入的是B2C签发的ID令牌,不符合通用Provider的校验逻辑,因此无法识别
解决方案
不要直接修改第三方扩展的Provider源码,自行实现适配B2C的自定义Socialite Provider即可,步骤如下:
1. 新增配置项
在config/services.php中新增B2C专属配置:
'azure-b2c' => [ 'client_id' => env('AZURE_B2C_CLIENT_ID'), 'client_secret' => env('AZURE_B2C_CLIENT_SECRET'), 'redirect' => env('AZURE_B2C_REDIRECT_URI'), 'tenant' => env('AZURE_B2C_TENANT'), // B2C租户名称,如xxx.onmicrosoft.com的前缀 'policy' => env('AZURE_B2C_POLICY'), // 提前配置好的用户流ID,如B2C_1_signup_signin ],
2. 实现自定义Provider
新建app/Socialite/Providers/AzureB2cProvider.php文件,内容如下:
<?php namespace App\Socialite\Providers; use Laravel\Socialite\Two\AbstractProvider; use Laravel\Socialite\Two\ProviderInterface; use Laravel\Socialite\Two\User; class AzureB2cProvider extends AbstractProvider implements ProviderInterface { protected $scopeSeparator = ' '; // 按需配置所需scope,必须包含openid protected $scopes = ['openid', 'profile', 'email', 'offline_access']; protected function getAuthUrl($state) { return $this->buildAuthUrlFromBase( "https://{$this->config['tenant']}.b2clogin.com/{$this->config['tenant']}.onmicrosoft.com/{$this->config['policy']}/oauth2/v2.0/authorize", $state ); } protected function getTokenUrl() { return "https://{$this->config['tenant']}.b2clogin.com/{$this->config['tenant']}.onmicrosoft.com/{$this->config['policy']}/oauth2/v2.0/token"; } protected function getUserByToken($token) { // 直接解析B2C签发的ID令牌获取用户信息,无需调用Graph接口 $tokenParts = explode('.', $token); $payload = base64_decode(str_replace(['-', '_'], ['+', '/'], $tokenParts[1])); return json_decode($payload, true); } protected function mapUserToObject(array $user) { // 按需映射字段,和B2C用户流返回的声明保持一致 return (new User)->setRaw($user)->map([ 'id' => $user['sub'], 'name' => $user['name'] ?? null, 'email' => $user['emails'][0] ?? $user['email'] ?? null, ]); } }
3. 注册自定义Provider
在app/Providers/AppServiceProvider.php的boot方法中注册自定义驱动:
use Laravel\Socialite\Facades\Socialite; public function boot() { Socialite::extend('azure-b2c', function ($app) { $config = $app['config']['services.azure-b2c']; return new \App\Socialite\Providers\AzureB2cProvider( $app['request'], $config['client_id'], $config['client_secret'], $config['redirect'], $config ); }); }
4. 调用方式
生成授权链接
return Socialite::driver('azure-b2c')->redirect();
回调处理
$user = Socialite::driver('azure-b2c')->stateless()->user(); // 直接获取用户信息:$user->id、$user->email、$user->name
注意:提前在Azure B2C后台的用户流配置中,开启你需要返回的用户声明(如邮箱、姓名等),否则解析出来的对应字段会为空。
内容的提问来源于stack exchange,提问作者Giuseppe
相关产品推荐
相关产品推荐

