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:
80
controllers/OIDCLogin.php
Normal file
80
controllers/OIDCLogin.php
Normal 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user