Skip to content

Commit 33351d8

Browse files
[Security] Add clock dependency to OidcTokenHandler
From "web-token/jwt-checker": The parameter "$clock" will become mandatory in 4.0.0. Please set a valid PSR Clock implementation instead of "null".
1 parent e61f15a commit 33351d8

File tree

6 files changed

+71
-58
lines changed

6 files changed

+71
-58
lines changed

DependencyInjection/Security/AccessToken/OidcTokenHandlerFactory.php

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
use Jose\Component\Core\Algorithm;
1515
use Jose\Component\Core\JWK;
16-
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SignatureAlgorithmFactory;
1716
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
1817
use Symfony\Component\DependencyInjection\ChildDefinition;
1918
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -28,26 +27,28 @@ class OidcTokenHandlerFactory implements TokenHandlerFactoryInterface
2827
{
2928
public function create(ContainerBuilder $container, string $id, array|string $config): void
3029
{
31-
$tokenHandlerDefinition = $container->setDefinition($id, new ChildDefinition('security.access_token_handler.oidc'));
32-
$tokenHandlerDefinition->replaceArgument(3, $config['claim']);
33-
$tokenHandlerDefinition->replaceArgument(4, $config['audience']);
30+
$tokenHandlerDefinition = $container->setDefinition($id, (new ChildDefinition('security.access_token_handler.oidc'))
31+
->replaceArgument(4, $config['claim'])
32+
->replaceArgument(5, $config['audience'])
33+
);
3434

35-
// Create the signature algorithm and the JWK
3635
if (!ContainerBuilder::willBeAvailable('web-token/jwt-core', Algorithm::class, ['symfony/security-bundle'])) {
37-
$container->register('security.access_token_handler.oidc.signature', 'stdClass')
36+
$container->register('security.access_token_handler.oidc.signature', Algorithm::class)
3837
->addError('You cannot use the "oidc" token handler since "web-token/jwt-core" is not installed. Try running "web-token/jwt-core".');
39-
$container->register('security.access_token_handler.oidc.jwk', 'stdClass')
38+
$container->register('security.access_token_handler.oidc.jwk', JWK::class)
4039
->addError('You cannot use the "oidc" token handler since "web-token/jwt-core" is not installed. Try running "web-token/jwt-core".');
40+
}
41+
42+
if (\in_array($config['algorithm'], ['ES256', 'ES384', 'ES512'], true)) {
43+
$tokenHandlerDefinition->replaceArgument(0, new Reference('security.access_token_handler.oidc.signature.'.$config['algorithm']));
4144
} else {
42-
$container->register('security.access_token_handler.oidc.signature', Algorithm::class)
43-
->setFactory([SignatureAlgorithmFactory::class, 'create'])
44-
->setArguments([$config['signature']['algorithm']]);
45-
$container->register('security.access_token_handler.oidc.jwk', JWK::class)
46-
->setFactory([JWK::class, 'createFromJson'])
47-
->setArguments([$config['signature']['key']]);
45+
$tokenHandlerDefinition->replaceArgument(0, (new ChildDefinition('security.access_token_handler.oidc.signature')))
46+
->replaceArgument(0, $config['algorithm']);
4847
}
49-
$tokenHandlerDefinition->replaceArgument(0, new Reference('security.access_token_handler.oidc.signature'));
50-
$tokenHandlerDefinition->replaceArgument(1, new Reference('security.access_token_handler.oidc.jwk'));
48+
49+
$tokenHandlerDefinition->replaceArgument(1, (new ChildDefinition('security.access_token_handler.oidc.jwk'))
50+
->replaceArgument(0, $config['key'])
51+
);
5152
}
5253

5354
public function getKey(): string
@@ -69,18 +70,13 @@ public function addConfiguration(NodeBuilder $node): void
6970
->info('Audience set in the token, for validation purpose.')
7071
->defaultNull()
7172
->end()
72-
->arrayNode('signature')
73+
->scalarNode('algorithm')
74+
->info('Algorithm used to sign the token.')
75+
->isRequired()
76+
->end()
77+
->scalarNode('key')
78+
->info('JSON-encoded JWK used to sign the token (must contain a "kty" key).')
7379
->isRequired()
74-
->children()
75-
->scalarNode('algorithm')
76-
->info('Algorithm used to sign the token.')
77-
->isRequired()
78-
->end()
79-
->scalarNode('key')
80-
->info('JSON-encoded JWK used to sign the token (must contain a "kty" key).')
81-
->isRequired()
82-
->end()
83-
->end()
8480
->end()
8581
->end()
8682
->end()

DependencyInjection/Security/Factory/SignatureAlgorithmFactory.php

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory;
1313

14-
use Jose\Component\Core\Algorithm as SignatureAlgorithm;
14+
use Jose\Component\Core\Algorithm as AlgorithmInterface;
1515
use Jose\Component\Signature\Algorithm;
1616
use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
1717
use Symfony\Component\Security\Http\AccessToken\Oidc\OidcTokenHandler;
@@ -23,29 +23,21 @@
2323
*/
2424
final class SignatureAlgorithmFactory
2525
{
26-
public static function create(string $algorithm): SignatureAlgorithm
26+
public static function create(string $algorithm): AlgorithmInterface
2727
{
2828
switch ($algorithm) {
2929
case 'ES256':
30-
if (!class_exists(Algorithm\ES256::class)) {
31-
throw new \LogicException('You cannot use the "ES256" signature algorithm since "web-token/jwt-signature-algorithm-ecdsa" is not installed. Try running "composer require web-token/jwt-signature-algorithm-ecdsa".');
32-
}
33-
34-
return new Algorithm\ES256();
3530
case 'ES384':
36-
if (!class_exists(Algorithm\ES384::class)) {
37-
throw new \LogicException('You cannot use the "ES384" signature algorithm since "web-token/jwt-signature-algorithm-ecdsa" is not installed. Try running "composer require web-token/jwt-signature-algorithm-ecdsa".');
38-
}
39-
40-
return new Algorithm\ES384();
4131
case 'ES512':
42-
if (!class_exists(Algorithm\ES512::class)) {
43-
throw new \LogicException('You cannot use the "ES512" signature algorithm since "web-token/jwt-signature-algorithm-ecdsa" is not installed. Try running "composer require web-token/jwt-signature-algorithm-ecdsa".');
32+
if (!class_exists(Algorithm::class.'\\'.$algorithm)) {
33+
throw new \LogicException(sprintf('You cannot use the "%s" signature algorithm since "web-token/jwt-signature-algorithm-ecdsa" is not installed. Try running "composer require web-token/jwt-signature-algorithm-ecdsa".', $algorithm));
4434
}
4535

46-
return new Algorithm\ES512();
47-
default:
48-
throw new InvalidArgumentException(sprintf('Unsupported signature algorithm "%s". Only ES* algorithms are supported. If you want to use another algorithm, create your TokenHandler as a service.', $algorithm));
36+
$algorithm = Algorithm::class.'\\'.$algorithm;
37+
38+
return new $algorithm();
4939
}
40+
41+
throw new InvalidArgumentException(sprintf('Unsupported signature algorithm "%s". Only ES* algorithms are supported. If you want to use another algorithm, create your TokenHandler as a service.', $algorithm));
5042
}
5143
}

Resources/config/schema/security-1.0.xsd

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -335,16 +335,8 @@
335335
</xsd:complexType>
336336

337337
<xsd:complexType name="oidc">
338-
<xsd:sequence>
339-
<xsd:choice minOccurs="1" maxOccurs="1">
340-
<xsd:element name="signature" type="oidc_signature" />
341-
</xsd:choice>
342-
</xsd:sequence>
343338
<xsd:attribute name="claim" type="xsd:string" />
344339
<xsd:attribute name="audience" type="xsd:string" />
345-
</xsd:complexType>
346-
347-
<xsd:complexType name="oidc_signature">
348340
<xsd:attribute name="algorithm" type="xsd:string" use="required" />
349341
<xsd:attribute name="key" type="xsd:string" use="required" />
350342
</xsd:complexType>

Resources/config/security_authenticator_access_token.php

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
1313

14+
use Jose\Component\Core\Algorithm;
15+
use Jose\Component\Core\JWK;
16+
use Jose\Component\Signature\Algorithm\ES256;
17+
use Jose\Component\Signature\Algorithm\ES384;
18+
use Jose\Component\Signature\Algorithm\ES512;
19+
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SignatureAlgorithmFactory;
1420
use Symfony\Component\Security\Http\AccessToken\ChainAccessTokenExtractor;
1521
use Symfony\Component\Security\Http\AccessToken\FormEncodedBodyExtractor;
1622
use Symfony\Component\Security\Http\AccessToken\HeaderAccessTokenExtractor;
@@ -62,10 +68,37 @@
6268
->abstract()
6369
->args([
6470
abstract_arg('signature algorithm'),
65-
abstract_arg('jwk'),
71+
abstract_arg('signature key'),
6672
service('logger')->nullOnInvalid(),
73+
service('clock'),
6774
'sub',
6875
null,
6976
])
77+
78+
->set('security.access_token_handler.oidc.jwk', JWK::class)
79+
->abstract()
80+
->factory([JWK::class, 'createFromJson'])
81+
->args([
82+
abstract_arg('signature key'),
83+
])
84+
85+
->set('security.access_token_handler.oidc.signature', Algorithm::class)
86+
->abstract()
87+
->factory([SignatureAlgorithmFactory::class, 'create'])
88+
->args([
89+
abstract_arg('signature algorithm'),
90+
])
91+
92+
->set('security.access_token_handler.oidc.signature.ES256', ES256::class)
93+
->parent('security.access_token_handler.oidc.signature')
94+
->args(['index_0' => 'ES256'])
95+
96+
->set('security.access_token_handler.oidc.signature.ES384', ES384::class)
97+
->parent('security.access_token_handler.oidc.signature')
98+
->args(['index_0' => 'ES384'])
99+
100+
->set('security.access_token_handler.oidc.signature.ES512', ES512::class)
101+
->parent('security.access_token_handler.oidc.signature')
102+
->args(['index_0' => 'ES512'])
70103
;
71104
};

Tests/Functional/app/AccessToken/config_oidc.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,9 @@ security:
2323
oidc:
2424
claim: 'username'
2525
audience: 'Symfony OIDC'
26-
signature:
27-
algorithm: 'ES256'
28-
# tip: use https://mkjwk.org/ to generate a JWK
29-
key: '{"kty":"EC","d":"iA_TV2zvftni_9aFAQwFO_9aypfJFCSpcCyevDvz220","crv":"P-256","x":"0QEAsI1wGI-dmYatdUZoWSRWggLEpyzopuhwk-YUnA4","y":"KYl-qyZ26HobuYwlQh-r0iHX61thfP82qqEku7i0woo"}'
26+
algorithm: 'ES256'
27+
# tip: use https://mkjwk.org/ to generate a JWK
28+
key: '{"kty":"EC","d":"iA_TV2zvftni_9aFAQwFO_9aypfJFCSpcCyevDvz220","crv":"P-256","x":"0QEAsI1wGI-dmYatdUZoWSRWggLEpyzopuhwk-YUnA4","y":"KYl-qyZ26HobuYwlQh-r0iHX61thfP82qqEku7i0woo"}'
3029
token_extractors: 'header'
3130
realm: 'My API'
3231

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"php": ">=8.1",
2020
"composer-runtime-api": ">=2.1",
2121
"ext-xml": "*",
22+
"symfony/clock": "^6.3",
2223
"symfony/config": "^6.1",
2324
"symfony/dependency-injection": "^6.2",
2425
"symfony/event-dispatcher": "^5.4|^6.0",
@@ -38,7 +39,7 @@
3839
"symfony/dom-crawler": "^5.4|^6.0",
3940
"symfony/expression-language": "^5.4|^6.0",
4041
"symfony/form": "^5.4|^6.0",
41-
"symfony/framework-bundle": "^5.4|^6.0",
42+
"symfony/framework-bundle": "^6.3",
4243
"symfony/ldap": "^5.4|^6.0",
4344
"symfony/process": "^5.4|^6.0",
4445
"symfony/rate-limiter": "^5.4|^6.0",
@@ -59,7 +60,7 @@
5960
"conflict": {
6061
"symfony/browser-kit": "<5.4",
6162
"symfony/console": "<5.4",
62-
"symfony/framework-bundle": "<5.4",
63+
"symfony/framework-bundle": "<6.3",
6364
"symfony/http-client": "<5.4",
6465
"symfony/ldap": "<5.4",
6566
"symfony/twig-bundle": "<5.4"

0 commit comments

Comments
 (0)