@@ -272,6 +272,10 @@ public function authenticate($request): UserEntityInterface
272272
273273 $ accessToken = $ request_token ->access_token ;
274274 $ userInfo = $ this ->getUserInfo ($ accessToken );
275+
276+ // Store id_token in session for logout
277+ $ this ->session ->oidc_id_token = $ request_token ->id_token ;
278+
275279 return $ this ->setUserAttributes ($ userInfo );
276280 }
277281
@@ -360,6 +364,40 @@ public function getSessionInitiator($target): bool|string
360364 return $ this ->getProvider ()->authorization_endpoint . '? ' . http_build_query ($ params );
361365 }
362366
367+ /**
368+ * Perform cleanup at logout time.
369+ *
370+ * @param string $url URL to redirect user to after logging out.
371+ *
372+ * @return string Redirect URL (modified for OpenIDConnect logout).
373+ */
374+ public function logout ($ url )
375+ {
376+ $ redirectUrl = $ url ;
377+
378+ // Retrieve id_token from session
379+ $ idToken = $ this ->session ->oidc_id_token ?? null ;
380+ if ($ idToken === null ) {
381+ $ this ->logWarning ('No id_token found in session data ' );
382+ } else {
383+ // Get end_session_endpoint from provider
384+ $ provider = $ this ->getProvider ();
385+ if (empty ($ provider ->end_session_endpoint )) {
386+ $ this ->logWarning ('No end_session_endpoint found in provider metadata ' );
387+ } else {
388+ $ logoutUrl = $ provider ->end_session_endpoint ;
389+ $ params = [
390+ 'id_token_hint ' => $ idToken ,
391+ 'post_logout_redirect_uri ' => $ url ,
392+ ];
393+ $ redirectUrl = $ logoutUrl . '? ' . http_build_query ($ params );
394+ }
395+ }
396+
397+ // Send back the redirect URL (possibly modified):
398+ return $ redirectUrl ;
399+ }
400+
363401 /**
364402 * Obtain an access token from a code.
365403 *
0 commit comments