我尝试编写登录脚本,我想使用 Microsoft OAuth2.0 和 Azure Active Directory(或 Mirosoft entra ID)登录。身份验证有效,我得到了 Autorizecode,但访问令牌没有从 success.php 端发送回我的 OAuth2.0 提供程序。我尝试了很多事情,例如调试、新代码......,但没有任何效果。顺便说一下,授权码在上面路径的success.php中给出。当然,出于安全原因,所有数据都会更改。
index.php
<?php
//TODO: Azure Synchronisation
session_start();
//* Überprüfen, ob der Benutzer authentifiziert ist
if (isset($_SESSION['token']))
{
header('Location: http://localhost/success.php'); //! Der Benutzer ist bereits authentifiziert
exit();
}
else
{
header('Location: https://login.microsoftonline.com/a502008d-5bd7-4ad1-b8e0-668da72219a8/oauth2/v2.0/authorize?client_id=XXXXXXXXX&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%2Fsuccess.php&response_mode=query&scope=openid+email+offline_access+profile+User.Read&state=12345&code_challenge=XXXXXXXXXXXXXX&code_challenge_method=S256'); //! Der Benutzer ist bereits authentifiziert
exit();
}
//* Überprüfen, ob der Benutzer bereits mit einem Office-Dienst verbunden ist
if (isset($_SERVER['AUTH_USER']))
{
sleep(1);
header('Location: http://localhost/success.php'); //! Der Benutzer ist bereits angemeldet
exit();
}
require_once($_SERVER['DOCUMENT_ROOT'].'/Assets/Configs/server.php'); //*Einbinden von server.php
$windowsUser = isset($_SERVER['AUTH_USER']) ? $_SERVER['AUTH_USER'] : null; //*Variable für Authentifizierung
require_once __DIR__.'/vendor/autoload.php'; //* Datei autoload.php einbinden
use \League\OAuth2\Client\Provider\GenericProvider; //* Composer (PHP-Bibliothek)
if($windowsUser)
{
$clientId = 'XXXXXXXXXXXXXXXXX'; //* Anwendungs-ID (Client)
$clientSecret = 'XXXXXXXXXXXXXXXXX'; //* Geheime Clientschlüssel
$tenantId = 'XXXXXXXXXXXXXXXXX'; //* Verzeichnis-ID (Mandant)
//* Konfigurationsinformationen für OAuth2-Provider
$provider = new GenericProvider([
'clientId' => $clientId,
'clientSecret' => $clientSecret,
'redirectUri' => 'http://localhost/success.php', //* UmleitungsURI
'urlAuthorize' => "https://login.microsoftonline.com/XXXXXXXXXXXXXXXXX/oauth2/v2.0/authorize?client_id=XXXXXXXXXXXXXXXXX&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%2Fsuccess.php&response_mode=query&scope=openid+email+offline_access+profile+User.Read&state=12345&code_challenge=XXXXXXXXXXXXXXXXX&code_challenge_method=S256",
'urlAccessToken' => "https://login.microsoftonline.com/XXXXXXXXXXXXXXXXX/oauth2/v2.0/token",
'urlResourceOwnerDetails' => '',
'scopes' => ['openid', 'email', 'offline_access', 'profile', 'User.Read'], //* Berechtigungen
'codeChallengeMethod' => 'S256',
]);
if (isset($_GET['code'])) {
$authorization_code = $_GET['code']; // Autorisierungscode aus GET-Parametern auslesen
try {
// Autorisierungscode verwenden, um Zugriffstoken zu erhalten
$accessToken = $provider->getAccessToken('authorization_code', [
'code' => $authorization_code,
]);
// JSON-Antwort in ein assoziatives Array umwandeln
$response = json_decode($accessToken->getBody(), true);
// Zugriffstoken speichern
$_SESSION['token'] = $accessToken->getToken();
$_SESSION['id_token'] = $accessToken->getValues()['id_token'];
$accessTokenValue = $accessToken->getToken();
$_SESSION['accesstoken'] = $accessTokenValue;
// Weiterleitung zur Erfolgsseite
header('Location: http://localhost/success.php');
exit();
} catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
echo "Fehler beim Abrufen des Zugriffstokens: " . $e->getMessage();
}
} else {
// Benutzer muss sich einloggen und wird dann zu Azure AD weitergeleitet
$authUrl = $provider->getAuthorizationUrl(); // Autorisierungs-URL abrufen
header('Location: ' . $authUrl); // Weiterleitung zur Autorisierungs-URL
exit();
}
}
?>
成功.php
<!DOCTYPE html>
<html lang="DE">
<?php
session_start();
$username = $_SESSION['user'];
$Erfolg ='Sie haben sich erfolgreich angemeldet';
?>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="Css.css">
<title>
Erfolg
</title>
</head>
<body>
<header>
<div id="Überschrift">
<h1>ITH Bolting Technology - Login</h1>
<?php
echo "Benutzer: ";
echo($username);
?>
</div>
</header>
<main>
<h3>
<?php
echo($Erfolg);
// Überprüfen, ob die Anzahl der Benutzer in der Session vorhanden ist
if(isset($_GET['code'])) {
$authorization_code = $_GET['code'];
echo "Autorisierungscode: " . $authorization_code;
} else {
echo "Autorisierungscode nicht gefunden.";
}
if (isset($_SESSION['user_count'])) {
echo "<p>Anzahl der Benutzer aus Azure AD: " . $_SESSION['user_count'] . "</p>";
} else {
echo "<p>Es wurden keine Benutzer abgerufen.</p>";
}
if(isset($_SESSION['accessToken']))
{
echo "Access Token: " . $_SESSION['accesstoken'];
}
else
{
echo "Es wurde kein Accesstoken gefunden";
}
?>
</h3>
</main>
</body>
</html>
我使用下面的 PHP 代码成功从 Azure Active Directory 检索了 访问令牌。
代码:
index.php:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Microsoft OAuth Example</title>
</head>
<body>
<h1>Welcome to Microsoft</h1>
<a href="auth.php">Login with Microsoft</a>
</body>
</html>
callback.php :
<?php
require_once 'vendor/autoload.php';
use GuzzleHttp\Client;
$tokenUrl = 'https://login.microsoftonline.com/<tenant_ID>/oauth2/v2.0/token';
$clientId = '<client_ID>';
$clientSecret = '<client_secret>';
$redirectUri = 'http://localhost:8000/callback.php';
if (isset($_GET['code'])) {
$code = $_GET['code'];
$client = new Client([
'verify' => false,
]);
$tokenParams = [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => $clientId,
'client_secret' => $clientSecret,
'code' => $code,
'redirect_uri' => $redirectUri,
]
];
try {
$tokenResponse = $client->post($tokenUrl, $tokenParams);
if ($tokenResponse->getStatusCode() === 200) {
$tokenData = json_decode($tokenResponse->getBody(), true);
$accessToken = $tokenData['access_token'];
echo "Access Token: $accessToken";
} else {
echo 'Error exchanging authorization code for access token: Unexpected response';
http_response_code(500);
}
} catch (Exception $e) {
echo 'Error exchanging authorization code for access token: ' . $e->getMessage();
http_response_code(500);
}
} else {
echo 'Authorization code not found.';
http_response_code(400);
}
?>
auth.php:
<?php
require_once 'vendor/autoload.php';
use GuzzleHttp\Client;
$authUrl = 'https://login.microsoftonline.com/<tenant_ID>/oauth2/v2.0/authorize';
$clientId = '<client_ID>';
$redirectUri = 'http://localhost:8000/callback.php';
$scope = urlencode('openid profile offline_access');
$authorizationUrl = "$authUrl?client_id=$clientId&redirect_uri=$redirectUri&response_type=code&scope=$scope";
header("Location: $authorizationUrl");
exit;
?>
我将以下URL添加到Azure应用程序Web中的身份验证:
http://localhost:8000/callback.php
我向应用程序的API权限授予了openid、profile和offline_access,如下所示:
输出:
PHP代码运行成功如下图:
C:\Users\xxxxxxxx\Documents\xxxxxxxx>php -S localhost:8000
[Tue Feb 20 14:35:05 2024] PHP 8.3.0 Development Server (http://localhost:8000) started
下面是浏览器中出现的输出。我点击了用 Microsoft 登录,如下所示:
重定向到登录页面后,我点击我的Azure帐户进行登录,如下所示:
我成功检索了访问令牌,如下所示。
VS代码终端输出:
C:\Users\xxxxxxxx\Documents\xxxxxxxx>php -S localhost:8000
[Tue Feb 20 14:30:19 2024] PHP 8.3.0 Development Server (http://localhost:8000) started
[Tue Feb 20 14:30:22 2024] [::1]:53800 Accepted
[Tue Feb 20 14:30:22 2024] [::1]:53800 [200]: GET /
[Tue Feb 20 14:30:22 2024] [::1]:53800 Closing
[Tue Feb 20 14:30:22 2024] [::1]:53801 Accepted
[Tue Feb 20 14:30:24 2024] [::1]:53802 Accepted
[Tue Feb 20 14:30:24 2024] [::1]:53801 [302]: GET /auth.php
[Tue Feb 20 14:30:24 2024] [::1]:53801 Closing
[Tue Feb 20 14:30:36 2024] [::1]:53802 [200]: GET /callback.php?code=0.ARoAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&session_state=34dd503axxxxxxxxxxxxxxxx
[Tue Feb 20 14:30:36 2024] [::1]:53802 Closing
[Tue Feb 20 14:30:36 2024] [::1]:53814 Accepted