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 without JWKSet nor "discovery". Please configure JWKSet in the constructor, or call "enableDiscovery" method.');
        }

        $jwkset = $this->signatureKeyset;
        if ($this->discovery) {
            $jwkset = new JWKSet([]);
            foreach ($this->discovery as ['cache' => $discoveryCache, 'client' => $discoveryClient, 'oidcConfigurationCacheKey' => $oidcConfigurationCacheKey, 'oidcJWKSetCacheKey' => $oidcJWKSetCacheKey]) {
                try {
                    $oidcConfiguration = json_decode($discoveryCache->get($oidcConfigurationCacheKey, function () use ($discoveryClient): string {
                        $response = $discoveryClient->request('GET', '.well-known/openid-configuration');

                        return $response->getContent();
                    }), true, 512, \JSON_THROW_ON_ERROR);
                } catch (\Throwable $e) {
                    $this->logger?->error('An error occurred while requesting OIDC configuration.', [
                        'error' => $e->getMessage(),
                        'trace' => $e->getTraceAsString(),
                    ]);

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

                try {
                    $json = $discoveryCache->get($oidcJWKSetCacheKey, function () use (
                        $discoveryClient,
                        $oidcConfiguration): string {
                        $response = $discoveryClient->request('GET', $oidcConfiguration['jwks_uri']);
                        // we only need signature key
                        $keys = array_filter($response->toArray()['keys'], static fn (array $key) => 'sig' === $key['use']);

                        return json_encode(['keys' => $keys]);
                    });

                    foreach (JWKSet::createFromJson($json) as $key) {
                        $jwkset = $jwkset->with($key);
                    }
                } catch (\Throwable $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);
                }
            }
        }

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

Review comment (performance):
```suggestion
                    $json = $discoveryCache->get($oidcJWKSetCacheKey, static function () use ($discoveryClient, $oidcConfiguration): string {
```

Code after:

        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 {
            $accessToken = $this->decryptIfNeeded($accessToken);
            $claims = $this->loadAndVerifyJws($accessToken, $jwkset);