Simple keycloak adapter.
- PHP 8.1 or higher
- composer
composer require drago-ex/keycloak
extensions:
keycloak: Drago\Keycloak\DI\KeycloakExtension
keycloak:
# https://github.com/stevenmaguire/oauth2-keycloak
authServerUrl: keycloak-server-url
realm: keycloak-realm
clientId: keycloak-client-id
clientSecret: keycloak-client-secret
redirectUri: https://example.com/callback-url
# optional
# version: 21.0.1
# encryptionAlgorithm: 'RS256'
# encryptionKeyPath: '../key.pem'
# encryptionKey: 'contents_of_key_or_certificate'
# https://github.com/guzzle/guzzle
# guzzleHttp:
use Drago\Keycloak\KeycloakAdapter
public function __construct(
private Keycloak $keycloak,
private KeycloakSessions $keycloakSessions,
) {
parent::__construct();
}
// simple login
protected function startup(): void
{
parent::startup();
if (!$this->getUser()->isLoggedIn()) {
$keycloakUser = $this->keycloakSessions
->getItems()->resourceOwner;
$this->getUser()->login($keycloakUser->getName(), $keycloakUser->getId());
$this->redirect('redirect');
}
}
// own authenticator, check attributes from keycloak, backlink
protected function startup(): void
{
parent::startup();
if (!$this->getUser()->isLoggedIn()) {
$keycloakUser = $this->keycloakSessions
->getItems()->resourceOwner;
try {
if ($keycloakUser) {
$user = $this->getUser();
// own authenticator
$user->setAuthenticator($this->authRepository);
// user login
$user->login($keycloakUser->getName(), $keycloakUser->getId());
// backlink, redirecting back to the page after login
$this->restoreRequest($this->backlink);
$this->redirect(':Backend:Admin:');
}
// check attributes from keylocker
} catch (AuthenticationException $e) {
if ($e->getCode() === 1) {
$this->template->userLoginError = true;
$this->getUserLogout();
$redirect = $this->keycloak->getLogoutUrl();
header('refresh:6; url=' . $redirect);
}
}
}
}
private function getUserLogout(): void
{
$this->getUser()->logout();
$this->keycloakSessions->remove();
}
<body n:ifset="$userLoginError">
<h1 class="text-danger text-center mt-5">
{_'The user does not have the required attributes set in keycloak.'}
</h1>
</body>
<body n:if="$user->loggedIn">
...
</body>
// state, accessToken and resource owner
$this->keycloakSessions->getItems();
$this->keycloakSessions->remove();
$this->redirectUrl($this->keycloak->getLogoutUrl());