@@ -162,12 +162,26 @@ public function login(int $providerId, ?string $redirectUrl = null) {
162162 return $ this ->buildErrorTemplateResponse ($ message , Http::STATUS_NOT_FOUND , ['reason ' => 'provider unreachable ' ]);
163163 }
164164
165- $ state = $ this ->random ->generate (32 , ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER );
166- $ this ->session ->set (self ::STATE , $ state );
167- $ this ->session ->set (self ::REDIRECT_AFTER_LOGIN , $ redirectUrl );
165+ // $state = $this->random->generate(32, ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER);
166+ // $this->session->set(self::STATE, $state);
167+ // $this->session->set(self::REDIRECT_AFTER_LOGIN, $redirectUrl);
168168
169- $ nonce = $ this ->random ->generate (32 , ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER );
170- $ this ->session ->set (self ::NONCE , $ nonce );
169+ // $nonce = $this->random->generate(32, ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER);
170+ // $this->session->set(self::NONCE, $nonce);
171+
172+ // check if oidc state is present in session data
173+ if ($ this ->session ->exists (self ::STATE )) {
174+ $ state = $ this ->session ->get (self ::STATE );
175+ $ nonce = $ this ->session ->get (self ::NONCE );
176+ } else {
177+ $ state = $ this ->random ->generate (32 , ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER );
178+ $ this ->session ->set (self ::STATE , $ state );
179+ $ this ->session ->set (self ::REDIRECT_AFTER_LOGIN , $ redirectUrl );
180+
181+ $ nonce = $ this ->random ->generate (32 , ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_UPPER );
182+ $ this ->session ->set (self ::NONCE , $ nonce );
183+ $ this ->session ->set (self ::PROVIDERID , $ providerId );
184+ }
171185
172186 $ oidcSystemConfig = $ this ->config ->getSystemValue ('user_oidc ' , []);
173187 $ isPkceSupported = in_array ('S256 ' , $ discovery ['code_challenge_methods_supported ' ] ?? [], true );
@@ -179,7 +193,7 @@ public function login(int $providerId, ?string $redirectUrl = null) {
179193 $ this ->session ->set (self ::CODE_VERIFIER , $ code_verifier );
180194 }
181195
182- $ this ->session ->set (self ::PROVIDERID , $ providerId );
196+ // $this->session->set(self::PROVIDERID, $providerId);
183197 $ this ->session ->close ();
184198
185199 // get attribute mapping settings
@@ -528,6 +542,10 @@ public function code(string $state = '', string $code = '', string $scope = '',
528542 $ this ->userSession ->createRememberMeToken ($ user );
529543 }
530544
545+ // remove code login session values
546+ $ this ->session ->remove (self ::STATE );
547+ $ this ->session ->remove (self ::NONCE );
548+
531549 // store all token information for potential token exchange requests
532550 $ tokenData = array_merge (
533551 $ data ,
@@ -543,7 +561,8 @@ public function code(string $state = '', string $code = '', string $scope = '',
543561 try {
544562 $ authToken = $ this ->authTokenProvider ->getToken ($ this ->session ->getId ());
545563 $ this ->sessionMapper ->createSession (
546- $ idTokenPayload ->sid ?? 'fallback-sid ' ,
564+ //$idTokenPayload->sid ?? 'fallback-sid',
565+ $ idTokenPayload ->{'urn:telekom.com:session_token ' } ?? 'fallback-sid ' ,
547566 $ idTokenPayload ->sub ?? 'fallback-sub ' ,
548567 $ idTokenPayload ->iss ?? 'fallback-iss ' ,
549568 $ authToken ->getId (),
@@ -618,7 +637,9 @@ public function singleLogoutService() {
618637 }
619638
620639 // cleanup related oidc session
621- $ this ->sessionMapper ->deleteFromNcSessionId ($ this ->session ->getId ());
640+ // it is not a good idea to remove the session early as some IDM send a backchannel logout also to the initiating system.
641+ // This will falsely fail if already deleted. So rely always on backchannel cleanup or make this an option?
642+ // $this->sessionMapper->deleteFromNcSessionId($this->session->getId());
622643
623644 $ this ->userSession ->logout ();
624645
@@ -706,7 +727,9 @@ public function backChannelLogout(string $providerIdentifier, string $logout_tok
706727 }
707728
708729 $ sub = $ logoutTokenPayload ->sub ;
709- if ($ oidcSession ->getSub () !== $ sub ) {
730+ // if ($oidcSession->getSub() !== $sub) {
731+ // handle sub only if it is available; session is enough to identify a logout
732+ if (isset ($ logoutTokenPayload ->sub ) && ($ oidcSession ->getSub () !== $ sub )) {
710733 return $ this ->getBackchannelLogoutErrorResponse (
711734 'invalid SUB ' ,
712735 'The sub does not match the one from the login ID token ' ,
@@ -731,17 +754,19 @@ public function backChannelLogout(string $providerIdentifier, string $logout_tok
731754 $ userId = $ authToken ->getUID ();
732755 $ this ->authTokenProvider ->invalidateTokenById ($ userId , $ authToken ->getId ());
733756 } catch (InvalidTokenException $ e ) {
734- return $ this ->getBackchannelLogoutErrorResponse (
735- 'nc session not found ' ,
736- 'The authentication session was not found in Nextcloud ' ,
737- ['nc_auth_session_not_found ' => $ authTokenId ]
738- );
757+ // it is not a problem if the auth token is already deleted, so no error
758+ // return $this->getBackchannelLogoutErrorResponse(
759+ // 'nc session not found',
760+ // 'The authentication session was not found in Nextcloud',
761+ // ['nc_auth_session_not_found' => $authTokenId]
762+ // );
739763 }
740764
741765 // cleanup
742766 $ this ->sessionMapper ->delete ($ oidcSession );
743767
744- return new JSONResponse ([], Http::STATUS_OK );
768+ // return new JSONResponse([], Http::STATUS_OK);
769+ return new JSONResponse ();
745770 }
746771
747772 /**
@@ -775,4 +800,20 @@ private function toCodeChallenge(string $data): string {
775800 $ s = str_replace ('/ ' , '_ ' , $ s ); // 63rd char of encoding
776801 return $ s ;
777802 }
803+
804+ /**
805+ * Backward compatible function for MagentaCLOUD to smoothly transition to new config
806+ *
807+ * @PublicPage
808+ * @NoCSRFRequired
809+ * @BruteForceProtection(action=userOidcBackchannelLogout)
810+ *
811+ * @param string $logout_token
812+ * @return JSONResponse
813+ * @throws Exception
814+ * @throws \JsonException
815+ */
816+ public function telekomBackChannelLogout (string $ logout_token = '' ) {
817+ return $ this ->backChannelLogout ('Telekom ' , $ logout_token );
818+ }
778819}
0 commit comments