From ed81a2301d1c2f1f07e248e75590d287eacdb010 Mon Sep 17 00:00:00 2001 From: Ronald Marfoldi Date: Tue, 16 Sep 2025 10:02:16 +0200 Subject: [PATCH 1/4] Log trace for authorization exception --- .../Process/OAuth2/GrantAccessByOAuth2TokenProcess.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Domain/Process/OAuth2/GrantAccessByOAuth2TokenProcess.php b/src/Domain/Process/OAuth2/GrantAccessByOAuth2TokenProcess.php index 43ce5d1..d729524 100644 --- a/src/Domain/Process/OAuth2/GrantAccessByOAuth2TokenProcess.php +++ b/src/Domain/Process/OAuth2/GrantAccessByOAuth2TokenProcess.php @@ -124,7 +124,14 @@ public function createRedirectResponseForRequest(Request $request, UserOAuthLogi */ private function logException(Request $request, Throwable $throwable): void { + $content = $throwable->getTraceAsString(); + $prevException = $throwable->getPrevious(); + if ($prevException) { + $content .= "\nPrevious exception:\n" . $prevException->getTraceAsString(); + } + $context = $this->contextFactory->buildFromRequest($request); + $context->setContent($content); $arrayContext = $this->serializer->toArray($context); if (false === is_array($arrayContext)) { $arrayContext = []; From a56dc676f3897323a897025dfe02888ebadb921b Mon Sep 17 00:00:00 2001 From: Ronald Marfoldi Date: Tue, 16 Sep 2025 10:23:13 +0200 Subject: [PATCH 2/4] Log trace for authorization exception --- .../GrantAccessByOAuth2TokenProcess.php | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/Domain/Process/OAuth2/GrantAccessByOAuth2TokenProcess.php b/src/Domain/Process/OAuth2/GrantAccessByOAuth2TokenProcess.php index d729524..c62a7f5 100644 --- a/src/Domain/Process/OAuth2/GrantAccessByOAuth2TokenProcess.php +++ b/src/Domain/Process/OAuth2/GrantAccessByOAuth2TokenProcess.php @@ -22,10 +22,12 @@ use Exception; use Lcobucci\JWT\Token\RegisteredClaims; use Psr\Log\LoggerInterface; -use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; +use Symfony\Contracts\HttpClient\Exception\ExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface; use Throwable; final class GrantAccessByOAuth2TokenProcess @@ -124,13 +126,27 @@ public function createRedirectResponseForRequest(Request $request, UserOAuthLogi */ private function logException(Request $request, Throwable $throwable): void { + $context = $this->contextFactory->buildFromRequest($request); + $content = $throwable->getTraceAsString(); $prevException = $throwable->getPrevious(); if ($prevException) { $content .= "\nPrevious exception:\n" . $prevException->getTraceAsString(); } + if ($prevException instanceof HttpExceptionInterface) { + $response = $prevException->getResponse(); + try { + $context + ->setHttpStatus($response->getStatusCode()) + ->setResponse($response->getContent()) + ; + } catch (ExceptionInterface $responseException) { + $context + ->setResponse(sprintf('Failed to retrieve a response content! (error: %s)', $responseException->getMessage())) + ; + } + } - $context = $this->contextFactory->buildFromRequest($request); $context->setContent($content); $arrayContext = $this->serializer->toArray($context); if (false === is_array($arrayContext)) { From 9f7ecf3d15ea694fc8332537ef7df01a2706c0c0 Mon Sep 17 00:00:00 2001 From: Ronald Marfoldi Date: Tue, 16 Sep 2025 10:44:29 +0200 Subject: [PATCH 3/4] Log trace for authorization exception --- .../OAuth2/GrantAccessByOAuth2TokenProcess.php | 3 +++ .../UnsuccessfulAccessTokenRequestException.php | 14 ++++++++++++++ src/HttpClient/OAuth2HttpClient.php | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Domain/Process/OAuth2/GrantAccessByOAuth2TokenProcess.php b/src/Domain/Process/OAuth2/GrantAccessByOAuth2TokenProcess.php index c62a7f5..3aa68ac 100644 --- a/src/Domain/Process/OAuth2/GrantAccessByOAuth2TokenProcess.php +++ b/src/Domain/Process/OAuth2/GrantAccessByOAuth2TokenProcess.php @@ -146,6 +146,9 @@ private function logException(Request $request, Throwable $throwable): void ; } } + if ($throwable instanceof UnsuccessfulAccessTokenRequestException) { + $context->setParams($throwable->getBodyParams()); + } $context->setContent($content); $arrayContext = $this->serializer->toArray($context); diff --git a/src/Exception/UnsuccessfulAccessTokenRequestException.php b/src/Exception/UnsuccessfulAccessTokenRequestException.php index 875fdfa..457cca7 100644 --- a/src/Exception/UnsuccessfulAccessTokenRequestException.php +++ b/src/Exception/UnsuccessfulAccessTokenRequestException.php @@ -9,8 +9,22 @@ final class UnsuccessfulAccessTokenRequestException extends AnzuException { + private array $bodyParams = []; + public static function create(string $message, ?Throwable $previous = null): self { return new self($message, 0, $previous); } + + public function setBodyParams(array $bodyParams): self + { + $this->bodyParams = $bodyParams; + + return $this; + } + + public function getBodyParams(): array + { + return $this->bodyParams; + } } diff --git a/src/HttpClient/OAuth2HttpClient.php b/src/HttpClient/OAuth2HttpClient.php index a1265f8..6484bfd 100644 --- a/src/HttpClient/OAuth2HttpClient.php +++ b/src/HttpClient/OAuth2HttpClient.php @@ -148,7 +148,7 @@ private function sendTokenRequest(string $url, array $bodyParameters): AccessTok $this->serializer->deserialize($response->getContent(), OpaqueAccessTokenResponseDto::class) ); } catch (ExceptionInterface $exception) { - throw UnsuccessfulAccessTokenRequestException::create('Token request failed!', $exception); + throw UnsuccessfulAccessTokenRequestException::create('Token request failed!', $exception)->setBodyParams($bodyParameters); } catch (SerializerException $exception) { throw UnsuccessfulAccessTokenRequestException::create('Invalid jwt token response!', $exception); } From e0dab006ca6c94208f32e5835232d6a675d54c6c Mon Sep 17 00:00:00 2001 From: Ronald Marfoldi Date: Tue, 16 Sep 2025 11:26:36 +0200 Subject: [PATCH 4/4] Fix ApiTokenAuthenticator with wrong credentials --- .../OAuth2/GrantAccessByOAuth2TokenProcess.php | 3 --- .../UnsuccessfulAccessTokenRequestException.php | 14 -------------- src/HttpClient/OAuth2HttpClient.php | 2 +- .../Authentication/ApiTokenAuthenticator.php | 7 ++++++- 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/src/Domain/Process/OAuth2/GrantAccessByOAuth2TokenProcess.php b/src/Domain/Process/OAuth2/GrantAccessByOAuth2TokenProcess.php index 3aa68ac..c62a7f5 100644 --- a/src/Domain/Process/OAuth2/GrantAccessByOAuth2TokenProcess.php +++ b/src/Domain/Process/OAuth2/GrantAccessByOAuth2TokenProcess.php @@ -146,9 +146,6 @@ private function logException(Request $request, Throwable $throwable): void ; } } - if ($throwable instanceof UnsuccessfulAccessTokenRequestException) { - $context->setParams($throwable->getBodyParams()); - } $context->setContent($content); $arrayContext = $this->serializer->toArray($context); diff --git a/src/Exception/UnsuccessfulAccessTokenRequestException.php b/src/Exception/UnsuccessfulAccessTokenRequestException.php index 457cca7..875fdfa 100644 --- a/src/Exception/UnsuccessfulAccessTokenRequestException.php +++ b/src/Exception/UnsuccessfulAccessTokenRequestException.php @@ -9,22 +9,8 @@ final class UnsuccessfulAccessTokenRequestException extends AnzuException { - private array $bodyParams = []; - public static function create(string $message, ?Throwable $previous = null): self { return new self($message, 0, $previous); } - - public function setBodyParams(array $bodyParams): self - { - $this->bodyParams = $bodyParams; - - return $this; - } - - public function getBodyParams(): array - { - return $this->bodyParams; - } } diff --git a/src/HttpClient/OAuth2HttpClient.php b/src/HttpClient/OAuth2HttpClient.php index 6484bfd..a1265f8 100644 --- a/src/HttpClient/OAuth2HttpClient.php +++ b/src/HttpClient/OAuth2HttpClient.php @@ -148,7 +148,7 @@ private function sendTokenRequest(string $url, array $bodyParameters): AccessTok $this->serializer->deserialize($response->getContent(), OpaqueAccessTokenResponseDto::class) ); } catch (ExceptionInterface $exception) { - throw UnsuccessfulAccessTokenRequestException::create('Token request failed!', $exception)->setBodyParams($bodyParameters); + throw UnsuccessfulAccessTokenRequestException::create('Token request failed!', $exception); } catch (SerializerException $exception) { throw UnsuccessfulAccessTokenRequestException::create('Invalid jwt token response!', $exception); } diff --git a/src/Security/Authentication/ApiTokenAuthenticator.php b/src/Security/Authentication/ApiTokenAuthenticator.php index af60d68..190b8d2 100644 --- a/src/Security/Authentication/ApiTokenAuthenticator.php +++ b/src/Security/Authentication/ApiTokenAuthenticator.php @@ -58,10 +58,15 @@ public function onAuthenticationFailure(Request $request, AuthenticationExceptio private function getCredentials(Request $request): array { - return u((string) $request->headers->get('Authorization')) + $credentials = u((string) $request->headers->get('Authorization')) ->replaceMatches('~Bearer[\s+]~', '') ->trim() ->split(':', 2); + if (2 === count($credentials)) { + return $credentials; + } + + return [null, null]; } private function checkCredentials(string $token, ApiTokenUserInterface $user): bool