Files
pics/controllers/OIDCLogin.php
Yorick van Pelt 4412db1679 Add OIDC login support for external identity providers
Adds "Login with <provider>" as an alternative login method using the
jumbojett/openid-connect-php library. OIDC users must already exist in
the database (matched by email). Configurable via OIDC_PROVIDER_URL,
OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, and OIDC_PROVIDER_NAME constants.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 16:10:17 +01:00

81 lines
2.0 KiB
PHP

<?php
/*****************************************************************************
* OIDCLogin.php
* Handles OIDC authentication via Kanidm (or other OIDC providers).
*****************************************************************************/
use Jumbojett\OpenIDConnectClient;
class OIDCLogin
{
public function __construct()
{
if (empty(OIDC_PROVIDER_URL))
{
header('Location: ' . BASEURL . '/login/');
exit;
}
// Already logged in? Redirect home.
if (Registry::get('user')->isLoggedIn())
{
header('Location: ' . BASEURL . '/');
exit;
}
// Store redirect URL in session before OIDC flow.
if (isset($_GET['redirect']))
$_SESSION['oidc_redirect_url'] = base64_decode($_GET['redirect']);
$oidc = new OpenIDConnectClient(OIDC_PROVIDER_URL, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET);
$oidc->setRedirectURL(BASEURL . '/oidclogin/');
$oidc->addScope(['openid', 'email']);
try
{
$oidc->authenticate();
}
catch (\Exception $e)
{
$_SESSION['login_msg'] = ['', 'OIDC authentication failed: ' . $e->getMessage(), 'danger'];
header('Location: ' . BASEURL . '/login/');
exit;
}
$email = $oidc->requestUserInfo('email');
if (empty($email))
{
$_SESSION['login_msg'] = ['', 'No email address received from OIDC provider.', 'danger'];
header('Location: ' . BASEURL . '/login/');
exit;
}
$user = Member::fromEmailAddress($email);
if ($user === null || $user === false)
{
$_SESSION['login_msg'] = ['', 'No account found for this email address. Please contact an administrator.', 'danger'];
header('Location: ' . BASEURL . '/login/');
exit;
}
$_SESSION['user_id'] = $user->getUserId();
if (!empty($_SESSION['oidc_redirect_url']))
{
$redirect = $_SESSION['oidc_redirect_url'];
unset($_SESSION['oidc_redirect_url']);
header('Location: ' . $redirect);
}
elseif (!empty($_SESSION['login_url']))
{
$redirect = $_SESSION['login_url'];
unset($_SESSION['login_url']);
header('Location: ' . $redirect);
}
else
header('Location: ' . BASEURL . '/');
exit;
}
}