1
0
forked from Public/pics

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>
This commit is contained in:
2026-02-14 16:08:45 +01:00
parent b0ee3081a6
commit 65d5cb62e5
5 changed files with 102 additions and 1 deletions

80
controllers/OIDCLogin.php Normal file
View File

@@ -0,0 +1,80 @@
<?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;
}
}