Repository: symfony/symfony
File: src/Symfony/Component/Security/Http/AccessToken/Oidc/OidcTokenHandler.php (PHP)

Code before:
            throw new \LogicException('You cannot use the "oidc" token handler since "web-token/jwt-signature" and "web-token/jwt-checker" are not installed. Try running "composer require web-token/jwt-signature web-token/jwt-checker".');
        }

        if (!$this->discoveryClients && !$this->signatureKeyset) {
            throw new \LogicException('You cannot use the "oidc" token handler without JWKSet nor "discovery". Please configure JWKSet in the constructor, or call "enableDiscovery" method.');
        }

        $jwkset = $this->signatureKeyset;
        if ($this->discoveryClients) {
            $clients = $this->discoveryClients;
            $keys = $this->discoveryCache->get($this->oidcConfigurationCacheKey, static function () use ($clients): array {
                try {
                    $configResponses = [];
                    foreach ($clients as $discoveryClient) {
                        $configResponses[] = $discoveryClient->request('GET', '.well-known/openid-configuration');
                    }

                    $jwkSetResponses = [];
                    foreach ($discoveryClient->stream($configResponses) as $response => $chunk) {
                        if ($chunk->isLast()) {
                            $jwkSetResponses[] = $discoveryClient->request('GET', $response->toArray()['jwks_uri']);
                        }
                    }

                    $keys = [];
                    foreach ($jwkSetResponses as $response) {
                        foreach ($response->toArray()['keys'] as $key) {
                            if ('sig' === $key['use']) {
                                $keys[] = $key;
                            }
                        }
                    }

                    return $keys;
                } catch (\Exception $e) {
                    $this->logger?->error('An error occurred while requesting OIDC certs.', [
                        'error' => $e->getMessage(),
                        'trace' => $e->getTraceAsString(),
                    ]);

                    throw new BadCredentialsException('Invalid credentials.', $e->getCode(), $e);
                }
            });

            $jwkset = JWKSet::createFromKeyData(['keys' => $keys]);
        }

        try {
            $accessToken = $this->decryptIfNeeded($accessToken);
            $claims = $this->loadAndVerifyJws($accessToken, $jwkset);
            $this->verifyClaims($claims);

Review comment (suggestion):
@nicolas-grekas I need your wisdom here. In the first foreach, I fetch the `openid-configuration` per client.

Then, I just pick the last client, to call `stream` as I figured there is not really a connection to the client there, that works.

But as soon as I need to request the `jwks_uri` I need to know the client this response is associated with.

Is there a way to keep this reference? I tried `$chunk->getOffset()` but it's related to something else.

I also inspected `$response` to see if it contains anything related to the client, but that's not part of it. 



Code after:
            throw new \LogicException('You cannot use the "oidc" token handler since "web-token/jwt-signature" and "web-token/jwt-checker" are not installed. Try running "composer require web-token/jwt-signature web-token/jwt-checker".');
        }

        if (!$this->discoveryClients && !$this->signatureKeyset) {
            throw new \LogicException('You cannot use the "oidc" token handler without JWKSet nor "discovery". Please configure JWKSet in the constructor, or call "enableDiscovery" method.');
        }

        $jwkset = $this->signatureKeyset;
        if ($this->discoveryClients) {
            $clients = $this->discoveryClients;
            $logger = $this->logger;
            $keys = $this->discoveryCache->get($this->oidcConfigurationCacheKey, static function () use ($clients, $logger): array {
                try {
                    $configResponses = [];
                    foreach ($clients as $client) {
                        $configResponses[] = $client->request('GET', '.well-known/openid-configuration', [
                            'user_data' => $client,
                        ]);
                    }

                    $jwkSetResponses = [];
                    foreach ($client->stream($configResponses) as $response => $chunk) {
                        if ($chunk->isLast()) {
                            $jwkSetResponses[] = $response->getInfo('user_data')->request('GET', $response->toArray()['jwks_uri']);
                        }
                    }

                    $keys = [];
                    foreach ($jwkSetResponses as $response) {
                        foreach ($response->toArray()['keys'] as $key) {
                            if ('sig' === $key['use']) {
                                $keys[] = $key;
                            }
                        }
                    }

                    return $keys;
                } catch (\Exception $e) {
                    $logger?->error('An error occurred while requesting OIDC certs.', [
                        'error' => $e->getMessage(),
                        'trace' => $e->getTraceAsString(),
                    ]);

                    throw new BadCredentialsException('Invalid credentials.', $e->getCode(), $e);
                }
            });

            $jwkset = JWKSet::createFromKeyData(['keys' => $keys]);
        }

        try {