]> BookStack Code Mirror - bookstack/commitdiff
Fixed OIDC Logout
authorjoancyho <redacted>
Tue, 29 Aug 2023 05:07:21 +0000 (13:07 +0800)
committerjoancyho <redacted>
Tue, 29 Aug 2023 05:07:21 +0000 (13:07 +0800)
.env.example.complete
app/Access/Controllers/OidcController.php
app/Access/Oidc/OidcService.php
app/Config/oidc.php
resources/views/common/header.blade.php
routes/web.php

index 96a3b448ff4de913254ae3883a8557ffab83d2d9..e89dc551591774023feea1f96d49c1dda70e3247 100644 (file)
@@ -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 <issuer>/.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
index e8c94493425f4a81d0b29dc65adc3385d47c9c46..083e83e35773131a199b0d34fb815247d10065bf 100644 (file)
@@ -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');
+        }
+    }
+
 }
index 6d13fe8f1691ac8ef6dddd64e733a5def0e56ffd..bd4964c574fc3d8b721c1af33c62a4aa97f1f374 100644 (file)
@@ -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']."/");
+
+
+    }
+
+
+
 }
index 1f73fb688662e8b72ea69700af2f1d4fa7138e31..a624e034c9381c527117f89ef416249b412feffb 100644 (file)
@@ -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),
+
 ];
+
index 97a411d84541684150f5b81bd4e6b6c8e9a8825f..8c05dc7ce9f9156af9de18ae119edf6d22b86435 100644 (file)
                             </a>
                         </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') }}"
                                   method="post">
+<?php
+// OIDC Logout Feature: Use /oidc/logout if authentication method is oidc.
+}
+?>
                                 {{ csrf_field() }}
                                 <button class="icon-item" data-shortcut="logout">
                                     @icon('logout')
index c7fc92fc77da3bf5819dcc75cd558ce02756700d..338572bf60864e83aa5a325f06cf1d09791c0457 100644 (file)
@@ -323,6 +323,8 @@ 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']);
 
 // User invitation routes
 Route::get('/register/invite/{token}', [AccessControllers\UserInviteController::class, 'showSetPassword']);