如何在基于 PHP 的 MRBS Web 应用程序中实现 Azure 组织 AD 身份验证?

问题描述 投票:0回答:1

我目前正在为会议室预订系统 (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');
        }
    }
}
?>
php authentication oauth-2.0 azure-active-directory openid-connect
1个回答
0
投票

我想知道这个问题是否已解决,因为我也想将 MRBS 与 AzureAD 一起使用...非常感谢您的更新!

一月。

© www.soinside.com 2019 - 2024. All rights reserved.