keycloak
All checks were successful
Deploy / deploy-staging (push) Successful in 46s
Deploy / deploy-production (push) Has been skipped

This commit is contained in:
2026-06-08 02:45:36 +02:00
parent 6d398323ae
commit 1ae7b98378
14 changed files with 1036 additions and 4 deletions

View File

@@ -0,0 +1,82 @@
<?php
declare(strict_types=1);
require_once dirname(__DIR__, 3) . '/src/App/bootstrap.php';
use App\ConfigLoader;
use App\KeycloakAuth;
session_start();
$projectRoot = dirname(__DIR__, 3);
$auth = new KeycloakAuth(ConfigLoader::load($projectRoot, 'keycloak'));
$state = (string) ($_GET['state'] ?? '');
$expectedState = (string) ($_SESSION['keycloak_oauth_state'] ?? '');
$code = (string) ($_GET['code'] ?? '');
$title = 'Keycloak Callback';
$message = 'Anmeldung wird verarbeitet.';
$redirectTarget = '/';
if ($state === '' || $expectedState === '' || !hash_equals($expectedState, $state)) {
http_response_code(400);
$message = 'State-Pruefung fehlgeschlagen. Bitte den Login erneut starten.';
} elseif ($code === '') {
http_response_code(400);
$message = 'Kein Authorization Code von Keycloak erhalten.';
} else {
unset($_SESSION['keycloak_oauth_state']);
$tokenExchange = $auth->exchangeAuthorizationCode($code);
if (($tokenExchange['success'] ?? false) !== true) {
http_response_code(502);
$message = (string) ($tokenExchange['error'] ?? 'Token-Austausch mit Keycloak fehlgeschlagen.');
} else {
/** @var array<string, mixed> $tokenPayload */
$tokenPayload = $tokenExchange['data'];
$accessToken = (string) ($tokenPayload['access_token'] ?? '');
if ($accessToken === '') {
http_response_code(502);
$message = 'Keycloak hat kein Access Token geliefert.';
} else {
$userInfo = $auth->fetchUserInfo($accessToken);
if (($userInfo['success'] ?? false) !== true) {
http_response_code(502);
$message = (string) ($userInfo['error'] ?? 'Userinfo-Abruf fehlgeschlagen.');
} else {
/** @var array<string, mixed> $userPayload */
$userPayload = $userInfo['data'];
$auth->establishSession($tokenPayload, $userPayload);
header('Location: ' . $redirectTarget, true, 302);
exit;
}
}
}
}
?><!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?= htmlspecialchars($title, ENT_QUOTES) ?></title>
<link rel="stylesheet" href="/assets/auth/login.css">
</head>
<body>
<main class="login-shell">
<section class="login-panel">
<div class="login-panel-top">
<p class="login-kicker">Kusche.Berlin</p>
<h1><?= htmlspecialchars($title, ENT_QUOTES) ?></h1>
<p class="login-copy"><?= htmlspecialchars($message, ENT_QUOTES) ?></p>
</div>
<div class="login-actions">
<a class="login-button login-button-secondary" href="/auth/login">Zurueck zum Login</a>
</div>
</section>
</main>
</body>
</html>