Fixed OIDC Logout

This commit is contained in:
joancyho 2023-08-29 13:07:21 +08:00
parent e176aae940
commit 6b55104ecb
6 changed files with 78 additions and 0 deletions

View File

@ -274,6 +274,10 @@ OIDC_GROUPS_CLAIM=groups
OIDC_REMOVE_FROM_GROUPS=false OIDC_REMOVE_FROM_GROUPS=false
OIDC_EXTERNAL_ID_CLAIM=sub OIDC_EXTERNAL_ID_CLAIM=sub
# OIDC Logout Feature: Its value should be value of end_session_endpoint from <issuer>/.well-known/openid-configuration
OIDC_END_SESSION_ENDPOINT=null
# Disable default third-party services such as Gravatar and Draw.IO # Disable default third-party services such as Gravatar and Draw.IO
# Service-specific options will override this option # Service-specific options will override this option
DISABLE_EXTERNAL_SERVICES=false DISABLE_EXTERNAL_SERVICES=false

View File

@ -63,4 +63,18 @@ class OidcController extends Controller
return redirect()->intended(); return redirect()->intended();
} }
/**
* OIDC Logout Feature: Start the authorization logout flow via OIDC.
*/
public function logout()
{
try {
return $this->oidcService->logout();
} catch (OidcException $exception) {
$this->showErrorNotification($exception->getMessage());
return redirect('/logout');
}
}
} }

View File

@ -216,6 +216,12 @@ class OidcService
$settings->keys, $settings->keys,
); );
// OIDC Logout Feature: Temporarily save token in session
$access_token_for_logout = $idTokenText;
session()->put("oidctoken", $access_token_for_logout);
$returnClaims = Theme::dispatch(ThemeEvents::OIDC_ID_TOKEN_PRE_VALIDATE, $idToken->getAllClaims(), [ $returnClaims = Theme::dispatch(ThemeEvents::OIDC_ID_TOKEN_PRE_VALIDATE, $idToken->getAllClaims(), [
'access_token' => $accessToken->getToken(), 'access_token' => $accessToken->getToken(),
'expires_in' => $accessToken->getExpires(), 'expires_in' => $accessToken->getExpires(),
@ -283,4 +289,37 @@ class OidcService
{ {
return $this->config()['user_to_groups'] !== false; return $this->config()['user_to_groups'] !== false;
} }
/**
* OIDC Logout Feature: Initiate a logout flow.
*
* @throws OidcException
*
* @return string
*/
public function logout() {
$config = $this->config();
$app_url = env('APP_URL', null);
$end_session_endpoint = $config["end_session_endpoint"];
$oidctoken = session()->get("oidctoken");
session()->invalidate();
if (str_contains($app_url, 'https://')) {
$protocol = 'https://';
} else {
$protocol = 'http://';
}
return redirect($end_session_endpoint.'?id_token_hint='.$oidctoken."&post_logout_redirect_uri=".$protocol.$_SERVER['HTTP_HOST']."/");
}
} }

View File

@ -47,4 +47,9 @@ return [
'groups_claim' => env('OIDC_GROUPS_CLAIM', 'groups'), 'groups_claim' => env('OIDC_GROUPS_CLAIM', 'groups'),
// When syncing groups, remove any groups that no longer match. Otherwise sync only adds new groups. // When syncing groups, remove any groups that no longer match. Otherwise sync only adds new groups.
'remove_from_groups' => env('OIDC_REMOVE_FROM_GROUPS', false), 'remove_from_groups' => env('OIDC_REMOVE_FROM_GROUPS', false),
// OIDC Logout Feature: OAuth2 end_session_endpoint
'end_session_endpoint' => env('OIDC_END_SESSION_ENDPOINT', null),
]; ];

View File

@ -93,8 +93,22 @@
</a> </a>
</li> </li>
<li> <li>
<?php
// OIDC Logout Feature: Use /oidc/logout if authentication method is oidc.
if (config('auth.method') === 'oidc') {
?>
<form action="/oidc/logout"
method="get">
<?php
// OIDC Logout Feature: Use /oidc/logout if authentication method is oidc.
} else {
?>
<form action="{{ url(config('auth.method') === 'saml2' ? '/saml2/logout' : '/logout') }}" <form action="{{ url(config('auth.method') === 'saml2' ? '/saml2/logout' : '/logout') }}"
method="post"> method="post">
<?php
// OIDC Logout Feature: Use /oidc/logout if authentication method is oidc.
}
?>
{{ csrf_field() }} {{ csrf_field() }}
<button class="icon-item" data-shortcut="logout"> <button class="icon-item" data-shortcut="logout">
@icon('logout') @icon('logout')

View File

@ -323,6 +323,8 @@ Route::get('/saml2/acs', [AccessControllers\Saml2Controller::class, 'processAcs'
// OIDC routes // OIDC routes
Route::post('/oidc/login', [AccessControllers\OidcController::class, 'login']); Route::post('/oidc/login', [AccessControllers\OidcController::class, 'login']);
Route::get('/oidc/callback', [AccessControllers\OidcController::class, 'callback']); Route::get('/oidc/callback', [AccessControllers\OidcController::class, 'callback']);
// OIDC Logout Feature: Added to cater OIDC logout
Route::get('/oidc/logout', [AccessControllers\OidcController::class, 'logout']);
// User invitation routes // User invitation routes
Route::get('/register/invite/{token}', [AccessControllers\UserInviteController::class, 'showSetPassword']); Route::get('/register/invite/{token}', [AccessControllers\UserInviteController::class, 'showSetPassword']);