Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit dab1d31

Browse files
fix(security): improve oidc_user_info DX + introduce base_uri option
1 parent 5bab536 commit dab1d31

File tree

3 files changed

+40
-18
lines changed

3 files changed

+40
-18
lines changed

src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/AccessToken/OidcUserInfoTokenHandlerFactory.php

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use Symfony\Component\DependencyInjection\ChildDefinition;
1616
use Symfony\Component\DependencyInjection\ContainerBuilder;
1717
use Symfony\Component\DependencyInjection\Reference;
18-
use Symfony\Component\HttpClient\HttpClient;
18+
use Symfony\Contracts\HttpClient\HttpClientInterface;
1919

2020
/**
2121
* Configures a token handler for an OIDC server.
@@ -30,20 +30,19 @@ public function create(ContainerBuilder $container, string $id, array|string $co
3030
$tokenHandlerDefinition->replaceArgument(2, $config['claim']);
3131

3232
// Create the client service
33-
if (!isset($config['client']['id'])) {
33+
if (isset($config['base_uri'])) {
3434
$clientDefinitionId = 'http_client.security.access_token_handler.oidc_user_info';
35-
if (!ContainerBuilder::willBeAvailable('symfony/http-client', HttpClient::class, ['symfony/security-bundle'])) {
35+
if (!ContainerBuilder::willBeAvailable('symfony/http-client', HttpClientInterface::class, ['symfony/security-bundle'])) {
3636
$container->register($clientDefinitionId, 'stdClass')
3737
->addError('You cannot use the "oidc_user_info" token handler since the HttpClient component is not installed. Try running "composer require symfony/http-client".');
3838
} else {
39-
$container->register($clientDefinitionId, HttpClient::class)
40-
->setFactory([HttpClient::class, 'create'])
41-
->setArguments([$config['client']])
39+
$container->setDefinition($clientDefinitionId, new ChildDefinition('security.access_token_handler.oidc_user_info.http_client'))
40+
->setArguments(['base_uri' => $config['base_uri']])
4241
->addTag('http_client.client');
4342
}
4443
}
4544

46-
$tokenHandlerDefinition->replaceArgument(0, new Reference($config['client']['id'] ?? $clientDefinitionId));
45+
$tokenHandlerDefinition->replaceArgument(0, new Reference($clientDefinitionId ?? $config['client']));
4746
}
4847

4948
public function getKey(): string
@@ -56,19 +55,28 @@ public function addConfiguration(NodeBuilder $node): void
5655
$node
5756
->arrayNode($this->getKey())
5857
->fixXmlConfig($this->getKey())
58+
->beforeNormalization()
59+
->ifString()
60+
->then(static function ($v): array { return ['claim' => 'sub', 'base_uri' => $v]; })
61+
->end()
62+
->validate()
63+
->ifTrue(function ($v) { return !empty($v['base_uri']) && !empty($v['client']); })
64+
->thenInvalid('You cannot configure the base_uri and the client together.')
65+
->end()
66+
->validate()
67+
->ifTrue(function ($v) { return empty($v['base_uri']) && empty($v['client']); })
68+
->thenInvalid('You must configure the "base_uri" or the "client" option.')
69+
->end()
5970
->children()
6071
->scalarNode('claim')
6172
->info('Claim which contains the user identifier (e.g.: sub, email..).')
6273
->defaultValue('sub')
6374
->end()
64-
->arrayNode('client')
65-
->info('HttpClient to call the OIDC server.')
66-
->isRequired()
67-
->beforeNormalization()
68-
->ifString()
69-
->then(static function ($v): array { return ['id' => $v]; })
70-
->end()
71-
->prototype('scalar')->end()
75+
->scalarNode('base_uri')
76+
->info('HttpClient base_uri to call the OIDC server.')
77+
->end()
78+
->scalarNode('client')
79+
->info('HttpClient service id to call the OIDC server.')
7280
->end()
7381
->end()
7482
->end()

src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator_access_token.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\Security\Http\AccessToken\Oidc\OidcUserInfoTokenHandler;
1919
use Symfony\Component\Security\Http\AccessToken\QueryAccessTokenExtractor;
2020
use Symfony\Component\Security\Http\Authenticator\AccessTokenAuthenticator;
21+
use Symfony\Contracts\HttpClient\HttpClientInterface;
2122

2223
return static function (ContainerConfigurator $container) {
2324
$container->services()
@@ -44,6 +45,10 @@
4445
])
4546

4647
// OIDC
48+
->set('security.access_token_handler.oidc_user_info.http_client', HttpClientInterface::class)
49+
->abstract()
50+
->factory([service('http_client'), 'withOptions'])
51+
4752
->set('security.access_token_handler.oidc_user_info', OidcUserInfoTokenHandler::class)
4853
->abstract()
4954
->args([

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AccessTokenFactoryTest.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,14 @@ public function testOidcUserInfoTokenHandlerConfigurationWithExistingClient()
8989
$this->assertFalse($container->hasDefinition('http_client.security.access_token_handler.oidc_user_info'));
9090
}
9191

92-
public function testOidcUserInfoTokenHandlerConfigurationWithClientCreation()
92+
/**
93+
* @dataProvider getOidcUserInfoConfiguration
94+
*/
95+
public function testOidcUserInfoTokenHandlerConfigurationWithBaseUri(array $configuration)
9396
{
9497
$container = new ContainerBuilder();
9598
$config = [
96-
'token_handler' => ['oidc_user_info' => ['client' => ['base_uri' => 'https://www.example.com/realms/demo/protocol/openid-connect/userinfo']]],
99+
'token_handler' => ['oidc_user_info' => $configuration],
97100
];
98101

99102
$factory = new AccessTokenFactory($this->createTokenHandlerFactories());
@@ -106,6 +109,12 @@ public function testOidcUserInfoTokenHandlerConfigurationWithClientCreation()
106109
$this->assertTrue($container->hasDefinition('http_client.security.access_token_handler.oidc_user_info'));
107110
}
108111

112+
public function getOidcUserInfoConfiguration(): iterable
113+
{
114+
yield [['base_uri' => 'https://www.example.com/realms/demo/protocol/openid-connect/userinfo']];
115+
yield ['https://www.example.com/realms/demo/protocol/openid-connect/userinfo'];
116+
}
117+
109118
public function testMultipleTokenHandlersSet()
110119
{
111120
$this->expectException(InvalidConfigurationException::class);
@@ -114,7 +123,7 @@ public function testMultipleTokenHandlersSet()
114123
$config = [
115124
'token_handler' => [
116125
'id' => 'in_memory_token_handler_service_id',
117-
'oidc_user_info' => ['client' => 'oidc.client'],
126+
'oidc_user_info' => 'https://www.example.com/realms/demo/protocol/openid-connect/userinfo',
118127
],
119128
];
120129

0 commit comments

Comments
 (0)