From dd10d1a7c5e70f5750315cfcea06f17ced3713eb Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Fri, 10 Apr 2026 16:27:49 +0200 Subject: [PATCH] fix: when the token has expired, only redirect to the login flow when the request comes from a 'navigation' context Signed-off-by: Julien Veyssier --- lib/Service/RequestClassificationService.php | 41 ++++++++++++++++++++ lib/Service/TokenService.php | 24 ++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 lib/Service/RequestClassificationService.php diff --git a/lib/Service/RequestClassificationService.php b/lib/Service/RequestClassificationService.php new file mode 100644 index 0000000..a5aa0a3 --- /dev/null +++ b/lib/Service/RequestClassificationService.php @@ -0,0 +1,41 @@ +getMethod()) !== 'GET') { + return false; + } + + $accept = strtolower($request->getHeader('Accept')); + if ($accept !== '' && strpos($accept, 'text/html') === false) { + return false; + } + + if ($request->getHeader('X-Requested-With') === 'XMLHttpRequest') { + return false; + } + + $secFetchMode = strtolower($request->getHeader('Sec-Fetch-Mode')); + if ($secFetchMode !== '' && $secFetchMode !== 'navigate') { + return false; + } + + $secFetchDest = strtolower($request->getHeader('Sec-Fetch-Dest')); + if ($secFetchDest !== '' && $secFetchDest !== 'document') { + return false; + } + + return true; + } +} diff --git a/lib/Service/TokenService.php b/lib/Service/TokenService.php index 46ff7f4..479eb3e 100644 --- a/lib/Service/TokenService.php +++ b/lib/Service/TokenService.php @@ -212,10 +212,34 @@ public function reauthenticate() { return; } + $accept = $this->request->getHeader('Accept'); + $xRequestedWith = $this->request->getHeader('X-Requested-With'); + $secFetchMode = $this->request->getHeader('Sec-Fetch-Mode'); + $secFetchDest = $this->request->getHeader('Sec-Fetch-Dest'); + if (!RequestClassificationService::isTopLevelHtmlNavigation($this->request)) { + $this->userSession->logout(); + $this->logger->debug('[TokenService] reauthenticate skipped: request is not a top-level HTML navigation', [ + 'request_uri' => $this->request->getRequestUri(), + 'accept' => $accept, + 'x_requested_with' => $xRequestedWith, + 'sec_fetch_mode' => $secFetchMode, + 'sec_fetch_dest' => $secFetchDest, + ]); + return; + } + // Logout the user and redirect to the oidc login flow to gather a fresh token $this->userSession->logout(); $redirectUrl = $this->urlGenerator->getAbsoluteURL('/index.php/apps/user_oidc/login/' . strval($token->getProviderId())) . '?redirectUrl=' . urlencode($this->request->getRequestUri()); + $this->logger->debug('[TokenService] reauthenticate redirect', [ + 'redirect_url' => $redirectUrl, + 'request_uri' => $this->request->getRequestUri(), + 'accept' => $accept, + 'x_requested_with' => $xRequestedWith, + 'sec_fetch_mode' => $secFetchMode, + 'sec_fetch_dest' => $secFetchDest, + ]); header('Location: ' . $redirectUrl); exit(); }