@@ -161,12 +161,26 @@ public function login(int $providerId, ?string $redirectUrl = null) {
161161 return $ this ->buildErrorTemplateResponse ($ message , Http::STATUS_NOT_FOUND , ['reason ' => 'provider unreachable ' ]);
162162 }
163163
164- $ state = $ this ->random ->generate (32 , ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER );
165- $ this ->session ->set (self ::STATE , $ state );
166- $ this ->session ->set (self ::REDIRECT_AFTER_LOGIN , $ redirectUrl );
164+ // $state = $this->random->generate(32, ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER);
165+ // $this->session->set(self::STATE, $state);
166+ // $this->session->set(self::REDIRECT_AFTER_LOGIN, $redirectUrl);
167167
168- $ nonce = $ this ->random ->generate (32 , ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER );
169- $ this ->session ->set (self ::NONCE , $ nonce );
168+ // $nonce = $this->random->generate(32, ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER);
169+ // $this->session->set(self::NONCE, $nonce);
170+
171+ // check if oidc state is present in session data
172+ if ($ this ->session ->exists (self ::STATE )) {
173+ $ state = $ this ->session ->get (self ::STATE );
174+ $ nonce = $ this ->session ->get (self ::NONCE );
175+ } else {
176+ $ state = $ this ->random ->generate (32 , ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER );
177+ $ this ->session ->set (self ::STATE , $ state );
178+ $ this ->session ->set (self ::REDIRECT_AFTER_LOGIN , $ redirectUrl );
179+
180+ $ nonce = $ this ->random ->generate (32 , ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER );
181+ $ this ->session ->set (self ::NONCE , $ nonce );
182+ $ this ->session ->set (self ::PROVIDERID , $ providerId );
183+ }
170184
171185 $ oidcSystemConfig = $ this ->config ->getSystemValue ('user_oidc ' , []);
172186 $ isPkceSupported = in_array ('S256 ' , $ discovery ['code_challenge_methods_supported ' ] ?? [], true );
@@ -178,7 +192,7 @@ public function login(int $providerId, ?string $redirectUrl = null) {
178192 $ this ->session ->set (self ::CODE_VERIFIER , $ code_verifier );
179193 }
180194
181- $ this ->session ->set (self ::PROVIDERID , $ providerId );
195+ // $this->session->set(self::PROVIDERID, $providerId);
182196 $ this ->session ->close ();
183197
184198 // get attribute mapping settings
@@ -507,6 +521,10 @@ public function code(string $state = '', string $code = '', string $scope = '',
507521 $ this ->userSession ->createRememberMeToken ($ user );
508522 }
509523
524+ // remove code login session values
525+ $ this ->session ->remove (self ::STATE );
526+ $ this ->session ->remove (self ::NONCE );
527+
510528 // store all token information for potential token exchange requests
511529 $ tokenData = array_merge (
512530 $ data ,
@@ -522,7 +540,8 @@ public function code(string $state = '', string $code = '', string $scope = '',
522540 try {
523541 $ authToken = $ this ->authTokenProvider ->getToken ($ this ->session ->getId ());
524542 $ this ->sessionMapper ->createSession (
525- $ idTokenPayload ->sid ?? 'fallback-sid ' ,
543+ //$idTokenPayload->sid ?? 'fallback-sid',
544+ $ idTokenPayload ->{'urn:telekom.com:session_token ' } ?? 'fallback-sid ' ,
526545 $ idTokenPayload ->sub ?? 'fallback-sub ' ,
527546 $ idTokenPayload ->iss ?? 'fallback-iss ' ,
528547 $ authToken ->getId (),
@@ -597,7 +616,9 @@ public function singleLogoutService() {
597616 }
598617
599618 // cleanup related oidc session
600- $ this ->sessionMapper ->deleteFromNcSessionId ($ this ->session ->getId ());
619+ // it is not a good idea to remove the session early as some IDM send a backchannel logout also to the initiating system.
620+ // This will falsely fail if already deleted. So rely always on backchannel cleanup or make this an option?
621+ // $this->sessionMapper->deleteFromNcSessionId($this->session->getId());
601622
602623 $ this ->userSession ->logout ();
603624
@@ -685,7 +706,9 @@ public function backChannelLogout(string $providerIdentifier, string $logout_tok
685706 }
686707
687708 $ sub = $ logoutTokenPayload ->sub ;
688- if ($ oidcSession ->getSub () !== $ sub ) {
709+ // if ($oidcSession->getSub() !== $sub) {
710+ // handle sub only if it is available; session is enough to identify a logout
711+ if (isset ($ logoutTokenPayload ->sub ) && ($ oidcSession ->getSub () !== $ sub )) {
689712 return $ this ->getBackchannelLogoutErrorResponse (
690713 'invalid SUB ' ,
691714 'The sub does not match the one from the login ID token ' ,
@@ -710,17 +733,19 @@ public function backChannelLogout(string $providerIdentifier, string $logout_tok
710733 $ userId = $ authToken ->getUID ();
711734 $ this ->authTokenProvider ->invalidateTokenById ($ userId , $ authToken ->getId ());
712735 } catch (InvalidTokenException $ e ) {
713- return $ this ->getBackchannelLogoutErrorResponse (
714- 'nc session not found ' ,
715- 'The authentication session was not found in Nextcloud ' ,
716- ['nc_auth_session_not_found ' => $ authTokenId ]
717- );
736+ // it is not a problem if the auth token is already deleted, so no error
737+ // return $this->getBackchannelLogoutErrorResponse(
738+ // 'nc session not found',
739+ // 'The authentication session was not found in Nextcloud',
740+ // ['nc_auth_session_not_found' => $authTokenId]
741+ // );
718742 }
719743
720744 // cleanup
721745 $ this ->sessionMapper ->delete ($ oidcSession );
722746
723- return new JSONResponse ([], Http::STATUS_OK );
747+ // return new JSONResponse([], Http::STATUS_OK);
748+ return new JSONResponse ();
724749 }
725750
726751 /**
@@ -754,4 +779,20 @@ private function toCodeChallenge(string $data): string {
754779 $ s = str_replace ('/ ' , '_ ' , $ s ); // 63rd char of encoding
755780 return $ s ;
756781 }
782+
783+ /**
784+ * Backward compatible function for MagentaCLOUD to smoothly transition to new config
785+ *
786+ * @PublicPage
787+ * @NoCSRFRequired
788+ * @BruteForceProtection(action=userOidcBackchannelLogout)
789+ *
790+ * @param string $logout_token
791+ * @return JSONResponse
792+ * @throws Exception
793+ * @throws \JsonException
794+ */
795+ public function telekomBackChannelLogout (string $ logout_token = '' ) {
796+ return $ this ->backChannelLogout ('Telekom ' , $ logout_token );
797+ }
757798}
0 commit comments