Skip to content

Commit 7fdff54

Browse files
Use cacheable OpenID Configuration (#5)
1 parent d529ec8 commit 7fdff54

File tree

4 files changed

+71
-7
lines changed

4 files changed

+71
-7
lines changed

config/oidc.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,19 @@
3535
'code_challenge_method' => env('OIDC_CODE_CHALLENGE_METHOD', 'S256'),
3636

3737
/**
38-
* TTL of the OpenID configuration cache in seconds.
39-
*/
40-
'configuration_cache_ttl' => env('OIDC_CONFIGURATION_CACHE_TTL', 60 * 60 * 24),
38+
* Configuration Cache
39+
*/
40+
'configuration_cache' => [
41+
/**
42+
* The cache store to use.
43+
*/
44+
'store' => env('OIDC_CONFIGURATION_CACHE_DRIVER', 'file'),
45+
46+
/**
47+
* The cache TTL in seconds.
48+
*/
49+
'ttl' => env('OIDC_CONFIGURATION_CACHE_TTL', 60 * 60 * 24),
50+
],
4151

4252
/**
4353
* Route configuration

src/OpenIDConnectClient.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,29 @@
55
namespace MinVWS\OpenIDConnectLaravel;
66

77
use Illuminate\Support\Facades\Session;
8+
use Illuminate\Support\Str;
89
use Jumbojett\OpenIDConnectClient as BaseOpenIDConnectClient;
910
use Jumbojett\OpenIDConnectClientException;
11+
use MinVWS\OpenIDConnectLaravel\OpenIDConfiguration\OpenIDConfiguration;
1012
use MinVWS\OpenIDConnectLaravel\Services\JWE\JweDecryptInterface;
1113

1214
class OpenIDConnectClient extends BaseOpenIDConnectClient
1315
{
1416
protected ?JweDecryptInterface $jweDecrypter;
17+
protected ?OpenIDConfiguration $openIDConfiguration;
1518

1619
public function __construct(
1720
?string $providerUrl = null,
1821
?string $clientId = null,
1922
?string $clientSecret = null,
2023
?string $issuer = null,
21-
?JweDecryptInterface $jweDecrypter = null
24+
?JweDecryptInterface $jweDecrypter = null,
25+
?OpenIDConfiguration $openIDConfiguration = null,
2226
) {
2327
parent::__construct($providerUrl, $clientId, $clientSecret, $issuer);
2428

2529
$this->jweDecrypter = $jweDecrypter;
30+
$this->openIDConfiguration = $openIDConfiguration;
2631
}
2732

2833
protected function startSession(): void
@@ -78,4 +83,29 @@ protected function handleJweResponse($jwe): string
7883
}
7984
return $this->jweDecrypter->decrypt($jwe);
8085
}
86+
87+
/**
88+
* Use cached OpenID configuration if available.
89+
*
90+
* @param string $param
91+
* @param string $default optional
92+
* @throws OpenIDConnectClientException
93+
* @return string|string[]|bool
94+
* @psalm-suppress ImplementedReturnTypeMismatch
95+
*/
96+
protected function getWellKnownConfigValue($param, $default = null): string|array|bool
97+
{
98+
if ($this->openIDConfiguration === null) {
99+
return parent::getWellKnownConfigValue($param, $default);
100+
}
101+
102+
$config = $this->openIDConfiguration;
103+
$param = Str::camel($param);
104+
105+
if (!property_exists($config, $param)) {
106+
return parent::getWellKnownConfigValue($param, $default);
107+
}
108+
109+
return $config->{$param};
110+
}
81111
}

src/OpenIDConnectServiceProvider.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ protected function registerConfigurationLoader(): void
6464
$this->app->singleton(OpenIDConfigurationLoader::class, function (Application $app) {
6565
return new OpenIDConfigurationLoader(
6666
$app['config']->get('oidc.issuer'),
67-
$app['config']->get('oidc.cache_ttl'),
68-
$app['config']->get('oidc.cache_store'),
67+
$app['cache']->store($app['config']->get('oidc.configuration_cache.store')),
68+
$app['config']->get('oidc.configuration_cache.ttl'),
6969
);
7070
});
7171
}
@@ -75,7 +75,8 @@ protected function registerClient(): void
7575
$this->app->singleton(OpenIDConnectClient::class, function (Application $app) {
7676
$oidc = new OpenIDConnectClient(
7777
providerUrl: $app['config']->get('oidc.issuer'),
78-
jweDecrypter: $app->make(JweDecryptInterface::class)
78+
jweDecrypter: $app->make(JweDecryptInterface::class),
79+
openIDConfiguration: $app->make(OpenIDConfigurationLoader::class)->getConfiguration(),
7980
);
8081
$oidc->setClientID($app['config']->get('oidc.client_id'));
8182
if (!empty($app['config']->get('oidc.client_secret'))) {

tests/Feature/OpenIDConfigurationLoaderTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,29 @@ public function testLoaderReturnsEmptyConfigurationOnEmptyJsonResponse(): void
200200
$this->assertEmpty($configuration->tokenEndpoint);
201201
}
202202

203+
public function testConfigurationIsLoadedMultipleTimesWhenCacheStoreIsNull(): void
204+
{
205+
$this->fakeSuccessfulResponse();
206+
207+
$loader = new OpenIDConfigurationLoader(
208+
issuer: 'https://provider.rdobeheer.nl',
209+
cacheStore: Cache::store('null'),
210+
);
211+
212+
// Load 2 times
213+
$loader->getConfiguration();
214+
$configuration = $loader->getConfiguration();
215+
216+
Http::assertSentCount(2);
217+
218+
$this->assertSame("3.0", $configuration->version);
219+
$this->assertSame("https://provider.rdobeheer.nl", $configuration->issuer);
220+
$this->assertSame("https://provider.rdobeheer.nl/authorize", $configuration->authorizationEndpoint);
221+
$this->assertSame("https://provider.rdobeheer.nl/jwks", $configuration->jwksUri);
222+
$this->assertSame("https://provider.rdobeheer.nl/token", $configuration->tokenEndpoint);
223+
$this->assertSame("https://provider.rdobeheer.nl/userinfo", $configuration->userinfoEndpoint);
224+
}
225+
203226
protected function fakeSuccessfulResponse(): void
204227
{
205228
Http::fake([

0 commit comments

Comments
 (0)