From 6b55104ecb0dfe8da154161c689d2a937d0ae0e3 Mon Sep 17 00:00:00 2001 From: joancyho Date: Tue, 29 Aug 2023 13:07:21 +0800 Subject: [PATCH 1/7] Fixed OIDC Logout --- .env.example.complete | 4 +++ app/Access/Controllers/OidcController.php | 14 ++++++++ app/Access/Oidc/OidcService.php | 39 +++++++++++++++++++++++ app/Config/oidc.php | 5 +++ resources/views/common/header.blade.php | 14 ++++++++ routes/web.php | 2 ++ 6 files changed, 78 insertions(+) diff --git a/.env.example.complete b/.env.example.complete index 96a3b448f..e89dc5515 100644 --- a/.env.example.complete +++ b/.env.example.complete @@ -274,6 +274,10 @@ OIDC_GROUPS_CLAIM=groups OIDC_REMOVE_FROM_GROUPS=false OIDC_EXTERNAL_ID_CLAIM=sub +# OIDC Logout Feature: Its value should be value of end_session_endpoint from /.well-known/openid-configuration +OIDC_END_SESSION_ENDPOINT=null + + # Disable default third-party services such as Gravatar and Draw.IO # Service-specific options will override this option DISABLE_EXTERNAL_SERVICES=false diff --git a/app/Access/Controllers/OidcController.php b/app/Access/Controllers/OidcController.php index e8c944934..083e83e35 100644 --- a/app/Access/Controllers/OidcController.php +++ b/app/Access/Controllers/OidcController.php @@ -63,4 +63,18 @@ class OidcController extends Controller 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'); + } + } + } diff --git a/app/Access/Oidc/OidcService.php b/app/Access/Oidc/OidcService.php index 6d13fe8f1..bd4964c57 100644 --- a/app/Access/Oidc/OidcService.php +++ b/app/Access/Oidc/OidcService.php @@ -216,6 +216,12 @@ class OidcService $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(), [ 'access_token' => $accessToken->getToken(), 'expires_in' => $accessToken->getExpires(), @@ -283,4 +289,37 @@ class OidcService { 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']."/"); + + + } + + + } diff --git a/app/Config/oidc.php b/app/Config/oidc.php index 1f73fb688..a624e034c 100644 --- a/app/Config/oidc.php +++ b/app/Config/oidc.php @@ -47,4 +47,9 @@ return [ 'groups_claim' => env('OIDC_GROUPS_CLAIM', '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), + + // OIDC Logout Feature: OAuth2 end_session_endpoint + 'end_session_endpoint' => env('OIDC_END_SESSION_ENDPOINT', null), + ]; + diff --git a/resources/views/common/header.blade.php b/resources/views/common/header.blade.php index 97a411d84..8c05dc7ce 100644 --- a/resources/views/common/header.blade.php +++ b/resources/views/common/header.blade.php @@ -93,8 +93,22 @@
  • + +
    + + {{ csrf_field() }}

  • - - - - - - {{ csrf_field() }} - - + @php + $logoutPath = match (config('auth.method')) { + 'saml2' => '/saml2/logout', + 'oidc' => '/oidc/logout', + default => '/logout', + } + @endphp +
    + {{ csrf_field() }} + +
  • \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index a02b19ca3..8fc90ee54 100644 --- a/routes/web.php +++ b/routes/web.php @@ -332,8 +332,7 @@ Route::get('/saml2/acs', [AccessControllers\Saml2Controller::class, 'processAcs' // OIDC routes Route::post('/oidc/login', [AccessControllers\OidcController::class, 'login']); Route::get('/oidc/callback', [AccessControllers\OidcController::class, 'callback']); -// OIDC Logout Feature: Added to cater OIDC logout -Route::get('/oidc/logout', [AccessControllers\OidcController::class, 'logout']); +Route::post('/oidc/logout', [AccessControllers\OidcController::class, 'logout']); // User invitation routes Route::get('/register/invite/{token}', [AccessControllers\UserInviteController::class, 'showSetPassword']); From f32cfb4292f7e3b723b5f99aab17d0f3989c93b7 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Wed, 6 Dec 2023 16:41:50 +0000 Subject: [PATCH 4/7] OIDC RP Logout: Added autodiscovery support and test cases --- app/Access/Controllers/LoginController.php | 22 ++----- app/Access/LoginService.php | 12 ++-- app/Access/Oidc/OidcProviderSettings.php | 5 ++ app/Access/Oidc/OidcService.php | 19 ++++-- app/Config/oidc.php | 3 +- tests/Auth/OidcTest.php | 77 ++++++++++++++++++++++ 6 files changed, 112 insertions(+), 26 deletions(-) diff --git a/app/Access/Controllers/LoginController.php b/app/Access/Controllers/LoginController.php index 904736656..ce872ba88 100644 --- a/app/Access/Controllers/LoginController.php +++ b/app/Access/Controllers/LoginController.php @@ -10,27 +10,19 @@ use BookStack\Facades\Activity; use BookStack\Http\Controller; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Auth; use Illuminate\Validation\ValidationException; class LoginController extends Controller { use ThrottlesLogins; - protected SocialDriverManager $socialDriverManager; - protected LoginService $loginService; - - /** - * Create a new controller instance. - */ - public function __construct(SocialDriverManager $driverManager, LoginService $loginService) - { + public function __construct( + protected SocialDriverManager $socialDriverManager, + protected LoginService $loginService, + ) { $this->middleware('guest', ['only' => ['getLogin', 'login']]); $this->middleware('guard:standard,ldap', ['only' => ['login']]); $this->middleware('guard:standard,ldap,oidc', ['only' => ['logout']]); - - $this->socialDriverManager = $driverManager; - $this->loginService = $loginService; } /** @@ -52,7 +44,7 @@ class LoginController extends Controller // Store the previous location for redirect after login $this->updateIntendedFromPrevious(); - if (!$preventInitiation && $this->shouldAutoInitiate()) { + if (!$preventInitiation && $this->loginService->shouldAutoInitiate()) { return view('auth.login-initiate', [ 'authMethod' => $authMethod, ]); @@ -194,7 +186,7 @@ class LoginController extends Controller { // Store the previous location for redirect after login $previous = url()->previous(''); - $isPreviousFromInstance = (strpos($previous, url('/')) === 0); + $isPreviousFromInstance = str_starts_with($previous, url('/')); if (!$previous || !setting('app-public') || !$isPreviousFromInstance) { return; } @@ -205,7 +197,7 @@ class LoginController extends Controller ]; foreach ($ignorePrefixList as $ignorePrefix) { - if (strpos($previous, url($ignorePrefix)) === 0) { + if (str_starts_with($previous, url($ignorePrefix))) { return; } } diff --git a/app/Access/LoginService.php b/app/Access/LoginService.php index f0f6ad4d3..cc48e0f9b 100644 --- a/app/Access/LoginService.php +++ b/app/Access/LoginService.php @@ -176,14 +176,18 @@ class LoginService } /** - * Check if login auto-initiate should be valid based upon authentication config. + * Check if login auto-initiate should be active based upon authentication config. */ - protected function shouldAutoInitiate(): bool + public function shouldAutoInitiate(): bool { + $autoRedirect = config('auth.auto_initiate'); + if (!$autoRedirect) { + return false; + } + $socialDrivers = $this->socialDriverManager->getActive(); $authMethod = config('auth.method'); - $autoRedirect = config('auth.auto_initiate'); - return $autoRedirect && count($socialDrivers) === 0 && in_array($authMethod, ['oidc', 'saml2']); + return count($socialDrivers) === 0 && in_array($authMethod, ['oidc', 'saml2']); } } diff --git a/app/Access/Oidc/OidcProviderSettings.php b/app/Access/Oidc/OidcProviderSettings.php index fa3f579b1..bea6a523e 100644 --- a/app/Access/Oidc/OidcProviderSettings.php +++ b/app/Access/Oidc/OidcProviderSettings.php @@ -21,6 +21,7 @@ class OidcProviderSettings public ?string $redirectUri; public ?string $authorizationEndpoint; public ?string $tokenEndpoint; + public ?string $endSessionEndpoint; /** * @var string[]|array[] @@ -132,6 +133,10 @@ class OidcProviderSettings $discoveredSettings['keys'] = $this->filterKeys($keys); } + if (!empty($result['end_session_endpoint'])) { + $discoveredSettings['endSessionEndpoint'] = $result['end_session_endpoint']; + } + return $discoveredSettings; } diff --git a/app/Access/Oidc/OidcService.php b/app/Access/Oidc/OidcService.php index be869b179..3f9cd41b4 100644 --- a/app/Access/Oidc/OidcService.php +++ b/app/Access/Oidc/OidcService.php @@ -84,6 +84,7 @@ class OidcService 'redirectUri' => url('/oidc/callback'), 'authorizationEndpoint' => $config['authorization_endpoint'], 'tokenEndpoint' => $config['token_endpoint'], + 'endSessionEndpoint' => $config['end_session_endpoint'], ]); // Use keys if configured @@ -100,6 +101,11 @@ class OidcService } } + // Prevent use of RP-initiated logout if specifically disabled + if ($config['end_session_endpoint'] === false) { + $settings->endSessionEndpoint = null; + } + $settings->validate(); return $settings; @@ -291,20 +297,23 @@ class OidcService * Start the RP-initiated logout flow if active, otherwise start a standard logout flow. * Returns a post-app-logout redirect URL. * Reference: https://openid.net/specs/openid-connect-rpinitiated-1_0.html + * @throws OidcException */ public function logout(): string { - $endSessionEndpoint = $this->config()["end_session_endpoint"]; - - // TODO - Add autodiscovery and false/null config value support. - $oidcToken = session()->pull("oidc_id_token"); $defaultLogoutUrl = url($this->loginService->logout()); + $oidcSettings = $this->getProviderSettings(); + + if (!$oidcSettings->endSessionEndpoint) { + return $defaultLogoutUrl; + } + $endpointParams = [ 'id_token_hint' => $oidcToken, 'post_logout_redirect_uri' => $defaultLogoutUrl, ]; - return $endSessionEndpoint . '?' . http_build_query($endpointParams); + return $oidcSettings->endSessionEndpoint . '?' . http_build_query($endpointParams); } } diff --git a/app/Config/oidc.php b/app/Config/oidc.php index 5f61063f6..ed9302d10 100644 --- a/app/Config/oidc.php +++ b/app/Config/oidc.php @@ -36,10 +36,9 @@ return [ 'authorization_endpoint' => env('OIDC_AUTH_ENDPOINT', null), 'token_endpoint' => env('OIDC_TOKEN_ENDPOINT', null), - // OIDC RP-Initiated Logout endpoint + // OIDC RP-Initiated Logout endpoint URL. // A null value gets the URL from discovery, if active. // A false value force-disables RP-Initiated Logout. - // A string value forces the given URL to be used. 'end_session_endpoint' => env('OIDC_END_SESSION_ENDPOINT', null), // Add extra scopes, upon those required, to the OIDC authentication request diff --git a/tests/Auth/OidcTest.php b/tests/Auth/OidcTest.php index 204a3bb5f..d10582d8c 100644 --- a/tests/Auth/OidcTest.php +++ b/tests/Auth/OidcTest.php @@ -44,6 +44,7 @@ class OidcTest extends TestCase 'oidc.groups_claim' => 'group', 'oidc.remove_from_groups' => false, 'oidc.external_id_claim' => 'sub', + 'oidc.end_session_endpoint' => null, ]); } @@ -478,6 +479,81 @@ class OidcTest extends TestCase $this->assertTrue($user->hasRole($roleA->id)); } + public function test_oidc_logout_form_active_when_oidc_active() + { + $this->runLogin(); + + $resp = $this->get('/'); + $this->withHtml($resp)->assertElementExists('header form[action$="/oidc/logout"] button'); + } + public function test_logout_with_autodiscovery() + { + $this->withAutodiscovery(); + + $transactions = $this->mockHttpClient([ + $this->getAutoDiscoveryResponse(), + $this->getJwksResponse(), + ]); + + $resp = $this->asEditor()->post('/oidc/logout'); + $resp->assertRedirect('https://auth.example.com/oidc/logout?post_logout_redirect_uri=' . urlencode(url('/'))); + + $this->assertEquals(2, $transactions->requestCount()); + } + + public function test_logout_with_autodiscovery_but_oidc_logout_disabled() + { + $this->withAutodiscovery(); + config()->set(['oidc.end_session_endpoint' => false]); + + $this->mockHttpClient([ + $this->getAutoDiscoveryResponse(), + $this->getJwksResponse(), + ]); + + $resp = $this->asEditor()->post('/oidc/logout'); + $resp->assertRedirect('/'); + } + + public function test_logout_without_autodiscovery_but_with_endpoint_configured() + { + config()->set(['oidc.end_session_endpoint' => 'https://example.com/logout']); + + $resp = $this->asEditor()->post('/oidc/logout'); + $resp->assertRedirect('https://example.com/logout?post_logout_redirect_uri=' . urlencode(url('/'))); + } + + public function test_logout_with_autodiscovery_and_auto_initiate_returns_to_auto_prevented_login() + { + $this->withAutodiscovery(); + config()->set([ + 'auth.auto_initiate' => true, + 'services.google.client_id' => false, + 'services.github.client_id' => false, + ]); + + $this->mockHttpClient([ + $this->getAutoDiscoveryResponse(), + $this->getJwksResponse(), + ]); + + $resp = $this->asEditor()->post('/oidc/logout'); + + $redirectUrl = url('/login?prevent_auto_init=true'); + $resp->assertRedirect('https://auth.example.com/oidc/logout?post_logout_redirect_uri=' . urlencode($redirectUrl)); + } + + public function test_logout_redirect_contains_id_token_hint_if_existing() + { + config()->set(['oidc.end_session_endpoint' => 'https://example.com/logout']); + + $this->runLogin(); + + $resp = $this->asEditor()->post('/oidc/logout'); + $query = 'id_token_hint=' . urlencode(OidcJwtHelper::idToken()) . '&post_logout_redirect_uri=' . urlencode(url('/')); + $resp->assertRedirect('https://example.com/logout?' . $query); + } + public function test_oidc_id_token_pre_validate_theme_event_without_return() { $args = []; @@ -563,6 +639,7 @@ class OidcTest extends TestCase 'authorization_endpoint' => OidcJwtHelper::defaultIssuer() . '/oidc/authorize', 'jwks_uri' => OidcJwtHelper::defaultIssuer() . '/oidc/keys', 'issuer' => OidcJwtHelper::defaultIssuer(), + 'end_session_endpoint' => OidcJwtHelper::defaultIssuer() . '/oidc/logout', ], $responseOverrides))); } From a72e0fee707ff0c8d226fef263eba41a49689833 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Wed, 6 Dec 2023 16:57:15 +0000 Subject: [PATCH 5/7] Tests: Fixed debug test to work with social class changes --- tests/DebugViewTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/DebugViewTest.php b/tests/DebugViewTest.php index 43de9f175..34de6b802 100644 --- a/tests/DebugViewTest.php +++ b/tests/DebugViewTest.php @@ -2,7 +2,7 @@ namespace Tests; -use BookStack\Access\SocialAuthService; +use BookStack\Access\SocialDriverManager; use Illuminate\Testing\TestResponse; class DebugViewTest extends TestCase @@ -46,8 +46,8 @@ class DebugViewTest extends TestCase protected function getDebugViewForException(\Exception $exception): TestResponse { // Fake an error via social auth service used on login page - $mockService = $this->mock(SocialAuthService::class); - $mockService->shouldReceive('getActiveDrivers')->andThrow($exception); + $mockService = $this->mock(SocialDriverManager::class); + $mockService->shouldReceive('getActive')->andThrow($exception); return $this->get('/login'); } From 81d256aebd6e7bca7b86369abd5e79b3a6679f33 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Thu, 7 Dec 2023 17:45:17 +0000 Subject: [PATCH 6/7] OIDC RP Logout: Fixed issues during testing - Disabled by default due to strict rejection by auth systems. - Fixed issue when autoloading logout URL, but not provided in autodiscovery response. - Added proper handling for if the logout URL contains a query string already. - Added extra tests to cover. - Forced config endpoint to be used, if set as a string, instead of autodiscovery endpoint. --- app/Access/Oidc/OidcService.php | 9 ++++-- app/Config/oidc.php | 5 ++-- tests/Auth/OidcTest.php | 53 +++++++++++++++++++++++++++++++-- 3 files changed, 60 insertions(+), 7 deletions(-) diff --git a/app/Access/Oidc/OidcService.php b/app/Access/Oidc/OidcService.php index 3f9cd41b4..f1e5b25af 100644 --- a/app/Access/Oidc/OidcService.php +++ b/app/Access/Oidc/OidcService.php @@ -84,7 +84,7 @@ class OidcService 'redirectUri' => url('/oidc/callback'), 'authorizationEndpoint' => $config['authorization_endpoint'], 'tokenEndpoint' => $config['token_endpoint'], - 'endSessionEndpoint' => $config['end_session_endpoint'], + 'endSessionEndpoint' => is_string($config['end_session_endpoint']) ? $config['end_session_endpoint'] : null, ]); // Use keys if configured @@ -102,8 +102,11 @@ class OidcService } // Prevent use of RP-initiated logout if specifically disabled + // Or force use of a URL if specifically set. if ($config['end_session_endpoint'] === false) { $settings->endSessionEndpoint = null; + } else if (is_string($config['end_session_endpoint'])) { + $settings->endSessionEndpoint = $config['end_session_endpoint']; } $settings->validate(); @@ -314,6 +317,8 @@ class OidcService 'post_logout_redirect_uri' => $defaultLogoutUrl, ]; - return $oidcSettings->endSessionEndpoint . '?' . http_build_query($endpointParams); + $joiner = str_contains($oidcSettings->endSessionEndpoint, '?') ? '&' : '?'; + + return $oidcSettings->endSessionEndpoint . $joiner . http_build_query($endpointParams); } } diff --git a/app/Config/oidc.php b/app/Config/oidc.php index ed9302d10..7f8f40d41 100644 --- a/app/Config/oidc.php +++ b/app/Config/oidc.php @@ -37,9 +37,10 @@ return [ 'token_endpoint' => env('OIDC_TOKEN_ENDPOINT', null), // OIDC RP-Initiated Logout endpoint URL. - // A null value gets the URL from discovery, if active. // A false value force-disables RP-Initiated Logout. - 'end_session_endpoint' => env('OIDC_END_SESSION_ENDPOINT', null), + // A true value gets the URL from discovery, if active. + // A string value is used as the URL. + 'end_session_endpoint' => env('OIDC_END_SESSION_ENDPOINT', false), // Add extra scopes, upon those required, to the OIDC authentication request // Multiple values can be provided comma seperated. diff --git a/tests/Auth/OidcTest.php b/tests/Auth/OidcTest.php index d10582d8c..dbf26f1bd 100644 --- a/tests/Auth/OidcTest.php +++ b/tests/Auth/OidcTest.php @@ -44,7 +44,7 @@ class OidcTest extends TestCase 'oidc.groups_claim' => 'group', 'oidc.remove_from_groups' => false, 'oidc.external_id_claim' => 'sub', - 'oidc.end_session_endpoint' => null, + 'oidc.end_session_endpoint' => false, ]); } @@ -486,8 +486,9 @@ class OidcTest extends TestCase $resp = $this->get('/'); $this->withHtml($resp)->assertElementExists('header form[action$="/oidc/logout"] button'); } - public function test_logout_with_autodiscovery() + public function test_logout_with_autodiscovery_with_oidc_logout_enabled() { + config()->set(['oidc.end_session_endpoint' => true]); $this->withAutodiscovery(); $transactions = $this->mockHttpClient([ @@ -499,9 +500,10 @@ class OidcTest extends TestCase $resp->assertRedirect('https://auth.example.com/oidc/logout?post_logout_redirect_uri=' . urlencode(url('/'))); $this->assertEquals(2, $transactions->requestCount()); + $this->assertFalse(auth()->check()); } - public function test_logout_with_autodiscovery_but_oidc_logout_disabled() + public function test_logout_with_autodiscovery_with_oidc_logout_disabled() { $this->withAutodiscovery(); config()->set(['oidc.end_session_endpoint' => false]); @@ -513,6 +515,7 @@ class OidcTest extends TestCase $resp = $this->asEditor()->post('/oidc/logout'); $resp->assertRedirect('/'); + $this->assertFalse(auth()->check()); } public function test_logout_without_autodiscovery_but_with_endpoint_configured() @@ -521,6 +524,16 @@ class OidcTest extends TestCase $resp = $this->asEditor()->post('/oidc/logout'); $resp->assertRedirect('https://example.com/logout?post_logout_redirect_uri=' . urlencode(url('/'))); + $this->assertFalse(auth()->check()); + } + + public function test_logout_without_autodiscovery_with_configured_endpoint_adds_to_query_if_existing() + { + config()->set(['oidc.end_session_endpoint' => 'https://example.com/logout?a=b']); + + $resp = $this->asEditor()->post('/oidc/logout'); + $resp->assertRedirect('https://example.com/logout?a=b&post_logout_redirect_uri=' . urlencode(url('/'))); + $this->assertFalse(auth()->check()); } public function test_logout_with_autodiscovery_and_auto_initiate_returns_to_auto_prevented_login() @@ -530,6 +543,7 @@ class OidcTest extends TestCase 'auth.auto_initiate' => true, 'services.google.client_id' => false, 'services.github.client_id' => false, + 'oidc.end_session_endpoint' => true, ]); $this->mockHttpClient([ @@ -541,6 +555,39 @@ class OidcTest extends TestCase $redirectUrl = url('/login?prevent_auto_init=true'); $resp->assertRedirect('https://auth.example.com/oidc/logout?post_logout_redirect_uri=' . urlencode($redirectUrl)); + $this->assertFalse(auth()->check()); + } + + public function test_logout_endpoint_url_overrides_autodiscovery_endpoint() + { + config()->set(['oidc.end_session_endpoint' => 'https://a.example.com']); + $this->withAutodiscovery(); + + $transactions = $this->mockHttpClient([ + $this->getAutoDiscoveryResponse(), + $this->getJwksResponse(), + ]); + + $resp = $this->asEditor()->post('/oidc/logout'); + $resp->assertRedirect('https://a.example.com?post_logout_redirect_uri=' . urlencode(url('/'))); + + $this->assertEquals(2, $transactions->requestCount()); + $this->assertFalse(auth()->check()); + } + + public function test_logout_with_autodiscovery_does_not_use_rp_logout_if_no_url_via_autodiscovery() + { + config()->set(['oidc.end_session_endpoint' => true]); + $this->withAutodiscovery(); + + $this->mockHttpClient([ + $this->getAutoDiscoveryResponse(['end_session_endpoint' => null]), + $this->getJwksResponse(), + ]); + + $resp = $this->asEditor()->post('/oidc/logout'); + $resp->assertRedirect('/'); + $this->assertFalse(auth()->check()); } public function test_logout_redirect_contains_id_token_hint_if_existing() From 7312300d53af9d1328242121b332aaed19fbcaa0 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Thu, 7 Dec 2023 17:59:48 +0000 Subject: [PATCH 7/7] OIDC: Update example env option to reflect correct default --- .env.example.complete | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example.complete b/.env.example.complete index 57d24eb5d..e8520a24c 100644 --- a/.env.example.complete +++ b/.env.example.complete @@ -273,7 +273,7 @@ OIDC_USER_TO_GROUPS=false OIDC_GROUPS_CLAIM=groups OIDC_REMOVE_FROM_GROUPS=false OIDC_EXTERNAL_ID_CLAIM=sub -OIDC_END_SESSION_ENDPOINT=null +OIDC_END_SESSION_ENDPOINT=false # Disable default third-party services such as Gravatar and Draw.IO # Service-specific options will override this option