我目前正在为会议室预订系统 (MRBS) 中的用户登录实施 Azure AD 身份验证https://github.com/meeting-room-booking-system/mrbs-code/tree/main。我已按照提供的文档进行操作,并将身份验证逻辑 https://github.com/meeting-room-booking-system/mrbs-code/blob/main/AUTHENTICATION#L969 集成到我的代码库中。然而,我在调试流程和代码时遇到了一些错误和困难。
我已在 config.inc.php 中配置了必要的参数,包括 Azure AD 客户端 ID、客户端密钥、重定向 URI 和租户 ID。但是,当我尝试使用 Azure AD 进行身份验证时,我没有按预期重定向到 Azure AD 登录页面。
我怀疑身份验证逻辑可能存在错误,或者身份验证后处理回调存在问题。此外,我不确定如何正确处理错误并调试过程。
有人可以帮我理解这段代码中的身份验证流程可能出了什么问题吗?如何在 PHP 中正确处理错误并调试 Azure AD 身份验证过程?
我的目的是我想通过电子邮件 ID 启用 MRBS 中的登录过程(用户可以使用其组织电子邮件 ID (microsoft) 登录)
我正在使用 MRBS 项目提供的 AuthAzuread 类,该类使用 Azure AD 处理身份验证流程。
<?php
namespace MRBS\Auth;
/*
* Authentication scheme that uses Azure AD for user authentication.
* Main file: https://github.com/meeting-room-booking-system/mrbs-code/tree/main
*
* For Authentication documentation: https://github.com/meeting-room-booking-system/mrbs-code/blob/main/AUTHENTICATION
*
* To use this authentication scheme, set the following in config.inc.php:
*
* $auth["type"] = "azuread";
* $auth["azuread_client_id"] = "YOUR_AZUREAD_CLIENT_ID";
* $auth["azuread_client_secret"] = "YOUR_AZUREAD_CLIENT_SECRET";
* $auth["azuread_redirect_uri"] = "https://your-mrbs-url.com/login.php"; // Redirect URI configured in Azure AD
* $auth["azuread_tenant_id"] = "YOUR_AZUREAD_TENANT_ID";
*
*/
use MRBS\User;
class AuthAzuread extends Auth
{
private $auth;
public function __construct($auth)
{
$this->auth = $auth;
// Check if azuread_tenant_id, azuread_client_id, and azuread_client_secret are provided
if (!isset($this->auth['azuread_tenant_id'])) {
throw new \Exception("Azure AD Tenant ID is missing.");
}
if (!isset($this->auth['azuread_client_id'])) {
throw new \Exception("Azure AD Client ID is missing.");
}
if (!isset($this->auth['azuread_client_secret'])) {
throw new \Exception("Azure AD Client Secret is missing.");
}
}
public function validateUser(?string $user, ?string $pass)
{
// Encode the redirect URI
$redirectUri = urlencode($this->auth["azuread_redirect_uri"]);
// Redirect users to Azure AD sign-in page
$azureADSignInUrl = "https://login.microsoftonline.com/{$this->auth['azuread_tenant_id']}/oauth2/v2.0/authorize?" . http_build_query([
"client_id" => $this->auth["azuread_client_id"],
"response_type" => "code",
"redirect_uri" => $redirectUri, // Include the encoded redirect URI
"scope" => "openid profile email",
]);
header("Location: $azureADSignInUrl");
exit;
}
public function handleCallback()
{
if (isset($_GET['code'])) {
$authorizationCode = $_GET['code'];
// Exchange authorization code for access token
$tokenEndpoint = "https://login.microsoftonline.com/{$this->auth['azuread_tenant_id']}/oauth2/v2.0/token";
$tokenParams = [
"grant_type" => "authorization_code",
"client_id" => $this->auth["azuread_client_id"],
"client_secret" => $this->auth["azuread_client_secret"],
"scope" => "openid profile email",
"redirect_uri" => $this->auth["azuread_redirect_uri"],
"code" => $authorizationCode,
];
$tokenData = $this->getToken($tokenEndpoint, $tokenParams);
if (isset($tokenData['access_token'])) {
$accessToken = $tokenData['access_token'];
$userInfo = $this->getUserInfo($accessToken);
if ($userInfo) {
return new User($userInfo['email'], $userInfo['name']);
} else {
throw new \Exception('Failed to retrieve user information from Microsoft Graph API');
}
} elseif (isset($tokenData['error'])) {
// Token request failed with error response
$error = $tokenData['error'];
$errorDescription = isset($tokenData['error_description']) ? $tokenData['error_description'] : '';
throw new \Exception("Token request failed with error: $error. Description: $errorDescription");
} else {
throw new \Exception('Failed to obtain access token from Azure AD');
}
}
return null;
}
private function getToken($tokenEndpoint, $tokenParams)
{
// Send POST request to token endpoint with client secret
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $tokenEndpoint);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($tokenParams));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
private function getUserInfo($accessToken)
{
// Make a request to Microsoft Graph API using the access token
$graphApiEndpoint = 'https://graph.microsoft.com/v1.0/me';
$headers = [
'Authorization: Bearer ' . $accessToken,
'Accept: application/json'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $graphApiEndpoint);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$userInfo = json_decode($response, true);
// Check if user info retrieval was successful
if (isset($userInfo['mail']) && isset($userInfo['displayName'])) {
return [
'email' => $userInfo['mail'],
'name' => $userInfo['displayName']
];
} else {
// User info retrieval failed
throw new \Exception('Failed to retrieve user information from Microsoft Graph API');
}
}
}
?>
我想知道这个问题是否已解决,因为我也想将 MRBS 与 AzureAD 一起使用...非常感谢您的更新!
一月。