From 5a2ffd1c870b28f49f5f68b984175fff313a4e0a Mon Sep 17 00:00:00 2001 From: memurats Date: Wed, 29 Oct 2025 20:13:20 +0100 Subject: [PATCH 1/2] backchannel logout fix --- lib/Controller/LoginController.php | 66 ++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/lib/Controller/LoginController.php b/lib/Controller/LoginController.php index da786660..99a01280 100644 --- a/lib/Controller/LoginController.php +++ b/lib/Controller/LoginController.php @@ -171,12 +171,26 @@ public function login(int $providerId, ?string $redirectUrl = null) { return $this->buildErrorTemplateResponse($message, Http::STATUS_NOT_FOUND, ['reason' => 'provider unreachable']); } - $state = $this->random->generate(32, ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER); - $this->session->set(self::STATE, $state); - $this->session->set(self::REDIRECT_AFTER_LOGIN, $redirectUrl); + // $state = $this->random->generate(32, ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER); + // $this->session->set(self::STATE, $state); + // $this->session->set(self::REDIRECT_AFTER_LOGIN, $redirectUrl); - $nonce = $this->random->generate(32, ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER); - $this->session->set(self::NONCE, $nonce); + // $nonce = $this->random->generate(32, ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER); + // $this->session->set(self::NONCE, $nonce); + + // check if oidc state is present in session data + if ($this->session->exists(self::STATE)) { + $state = $this->session->get(self::STATE); + $nonce = $this->session->get(self::NONCE); + } else { + $state = $this->random->generate(32, ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER); + $this->session->set(self::STATE, $state); + $this->session->set(self::REDIRECT_AFTER_LOGIN, $redirectUrl); + + $nonce = $this->random->generate(32, ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER); + $this->session->set(self::NONCE, $nonce); + $this->session->set(self::PROVIDERID, $providerId); + } $oidcSystemConfig = $this->config->getSystemValue('user_oidc', []); $isPkceSupported = in_array('S256', $discovery['code_challenge_methods_supported'] ?? [], true); @@ -188,7 +202,7 @@ public function login(int $providerId, ?string $redirectUrl = null) { $this->session->set(self::CODE_VERIFIER, $code_verifier); } - $this->session->set(self::PROVIDERID, $providerId); + // $this->session->set(self::PROVIDERID, $providerId); $this->session->close(); // get attribute mapping settings @@ -601,16 +615,20 @@ public function code(string $state = '', string $code = '', string $scope = '', $this->eventDispatcher->dispatchTyped(new UserLoggedInEvent($user, $user->getUID(), null, false)); } - $storeLoginTokenEnabled = $this->appConfig->getValueString(Application::APP_ID, 'store_login_token', '0') === '1'; - if ($storeLoginTokenEnabled) { + // $storeLoginTokenEnabled = $this->appConfig->getValueString(Application::APP_ID, 'store_login_token', '0') === '1'; + // if ($storeLoginTokenEnabled) { // store all token information for potential token exchange requests - $tokenData = array_merge( - $data, - ['provider_id' => $providerId], - ); - $this->tokenService->storeToken($tokenData); - } - $this->config->setUserValue($user->getUID(), Application::APP_ID, 'had_token_once', '1'); + // $tokenData = array_merge( + // $data, + // ['provider_id' => $providerId], + // ); + // $this->tokenService->storeToken($tokenData); + // } + // $this->config->setUserValue($user->getUID(), Application::APP_ID, 'had_token_once', '1'); + + // remove code login session values + $this->session->remove(self::STATE); + $this->session->remove(self::NONCE); // Set last password confirm to the future as we don't have passwords to confirm against with SSO $this->session->set('last-password-confirm', strtotime('+4 year', time())); @@ -619,7 +637,7 @@ public function code(string $state = '', string $code = '', string $scope = '', try { $authToken = $this->authTokenProvider->getToken($this->session->getId()); $this->sessionMapper->createOrUpdateSession( - $idTokenPayload->sid ?? 'fallback-sid', + $idTokenPayload->{'urn:telekom.com:session_token'} ?? 'fallback-sid', $idTokenPayload->sub ?? 'fallback-sub', $idTokenPayload->iss ?? 'fallback-iss', $authToken->getId(), @@ -901,6 +919,22 @@ private function getBackchannelLogoutErrorResponse( ); } + /** + * Backward compatible function for MagentaCLOUD to smoothly transition to new config + * + * @PublicPage + * @NoCSRFRequired + * @BruteForceProtection(action=userOidcBackchannelLogout) + * + * @param string $logout_token + * @return JSONResponse + * @throws Exception + * @throws \JsonException + */ + public function telekomBackChannelLogout(string $logout_token = '') { + return $this->backChannelLogout('Telekom', $logout_token); + } + private function toCodeChallenge(string $data): string { // Basically one big work around for the base64url decode being weird $h = pack('H*', hash('sha256', $data)); From 1424e83b977a4c74d972bcd9203335fd31aeddbd Mon Sep 17 00:00:00 2001 From: Mauro Mura Date: Fri, 5 Dec 2025 10:51:51 +0100 Subject: [PATCH 2/2] Clean up LoginController by removing unused comments Removed commented-out code related to login token storage. --- lib/Controller/LoginController.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/lib/Controller/LoginController.php b/lib/Controller/LoginController.php index 99a01280..83ba4d30 100644 --- a/lib/Controller/LoginController.php +++ b/lib/Controller/LoginController.php @@ -615,17 +615,6 @@ public function code(string $state = '', string $code = '', string $scope = '', $this->eventDispatcher->dispatchTyped(new UserLoggedInEvent($user, $user->getUID(), null, false)); } - // $storeLoginTokenEnabled = $this->appConfig->getValueString(Application::APP_ID, 'store_login_token', '0') === '1'; - // if ($storeLoginTokenEnabled) { - // store all token information for potential token exchange requests - // $tokenData = array_merge( - // $data, - // ['provider_id' => $providerId], - // ); - // $this->tokenService->storeToken($tokenData); - // } - // $this->config->setUserValue($user->getUID(), Application::APP_ID, 'had_token_once', '1'); - // remove code login session values $this->session->remove(self::STATE); $this->session->remove(self::NONCE);