diff --git a/lib/Event/ExchangedTokenRequestedEvent.php b/lib/Event/ExchangedTokenRequestedEvent.php index 0870e83b..87e7a5ec 100644 --- a/lib/Event/ExchangedTokenRequestedEvent.php +++ b/lib/Event/ExchangedTokenRequestedEvent.php @@ -20,6 +20,7 @@ class ExchangedTokenRequestedEvent extends Event { public function __construct( private string $targetAudience, + private array $extraScopes = [], ) { parent::__construct(); } @@ -32,6 +33,10 @@ public function setTargetAudience(string $targetAudience): void { $this->targetAudience = $targetAudience; } + public function getExtraScopes(): array { + return $this->extraScopes; + } + public function getToken(): ?Token { return $this->token; } diff --git a/lib/Listener/ExchangedTokenRequestedListener.php b/lib/Listener/ExchangedTokenRequestedListener.php index 642a74c1..dc6eb273 100644 --- a/lib/Listener/ExchangedTokenRequestedListener.php +++ b/lib/Listener/ExchangedTokenRequestedListener.php @@ -37,10 +37,11 @@ public function handle(Event $event): void { } $targetAudience = $event->getTargetAudience(); + $extraScopes = $event->getExtraScopes(); $this->logger->debug('[ExchangedTokenRequestedListener] received request for audience: ' . $targetAudience); // classic token exchange with an external provider - $token = $this->tokenService->getExchangedToken($targetAudience); + $token = $this->tokenService->getExchangedToken($targetAudience, $extraScopes); $event->setToken($token); } } diff --git a/lib/Service/TokenService.php b/lib/Service/TokenService.php index b16ac609..d492d6a4 100644 --- a/lib/Service/TokenService.php +++ b/lib/Service/TokenService.php @@ -220,7 +220,7 @@ public function decodeIdToken(Token $token): array { * @throws TokenExchangeFailedException * @throws \JsonException */ - public function getExchangedToken(string $targetAudience): Token { + public function getExchangedToken(string $targetAudience, array $extraScopes = []): Token { $storeLoginTokenEnabled = $this->config->getAppValue(Application::APP_ID, 'store_login_token', '0') === '1'; if (!$storeLoginTokenEnabled) { throw new TokenExchangeFailedException( @@ -240,6 +240,10 @@ public function getExchangedToken(string $targetAudience): Token { } $oidcProvider = $this->providerMapper->getProvider($loginToken->getProviderId()); $discovery = $this->discoveryService->obtainDiscovery($oidcProvider); + $scope = $oidcProvider->getScope(); + if (!empty($extraScopes)) { + $scope .= ' ' . implode(' ', $extraScopes); + } try { $clientSecret = $oidcProvider->getClientSecret(); @@ -267,6 +271,7 @@ public function getExchangedToken(string $targetAudience): Token { // this one will get us an access token and refresh token within the response 'requested_token_type' => 'urn:ietf:params:oauth:token-type:refresh_token', 'audience' => $targetAudience, + 'scope' => $scope, ], ] );