8000 fix(security): OIDC issuer MUST be validated according to specification · symfony/symfony@dcee5a2 · GitHub
[go: up one dir, main page]

Skip to content

Commit dcee5a2

Browse files
fix(security): OIDC issuer MUST be validated according to specification
1 parent 6bb6813 commit dcee5a2

File tree

6 files changed

+19
-6
lines changed

6 files changed

+19
-6
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ public function create(ContainerBuilder $container, string $id, array|string $co
2929
{
3030
$tokenHandlerDefinition = $container->setDefinition($id, (new ChildDefinition('security.access_token_handler.oidc'))
3131
->replaceArgument(2, $config['audience'])
32-
->replaceArgument(5, $config['claim'])
32+
->replaceArgument(3, $config['issuers'])
33+
->replaceArgument(6, $config['claim'])
3334
);
3435

3536
if (!ContainerBuilder::willBeAvailable('web-token/jwt-core', Algorithm::class, ['symfony/security-bundle'])) {
@@ -70,6 +71,11 @@ public function addConfiguration(NodeBuilder $node): void
7071
->info('Audience set in the token, for validation purpose.')
7172
->isRequired()
7273
->end()
74+
->arrayNode('issuers')
75+
->info('Issuers allowed to generate the token, for validation purpose.')
76+
->isRequired()
77+
->prototype('scalar')->end()
78+
->end()
7379
->scalarNode('algorithm')
7480
->info('Algorithm used to sign the token.')
7581
->isRequired()

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
abstract_arg('signature algorithm'),
7171
abstract_arg('signature key'),
7272
abstract_arg('audience'),
73+
abstract_arg('issuers'),
7374
service('logger')->nullOnInvalid(),
7475
service('clock'),
7576
'sub',

src/Symfony/Bundle/SecurityBundle/Tests/Functional/AccessTokenTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ public function testOidcSuccess()
343343
'iat' => $time,
344344
'nbf' => $time,
345345
'exp' => $time + 3600,
346-
'iss' => 'https://www.example.com/',
346+
'iss' => 'https://www.example.com',
347347
'aud' => 'Symfony OIDC',
348348
'sub' => 'e21bf182-1538-406e-8ccb-e25a17aba39f',
349349
'username' => 'dunglas',

src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AccessToken/config_oidc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ security:
2323
oidc:
2424
claim: 'username'
2525
audience: 'Symfony OIDC'
26+
issuers: [ 'https://www.example.com' ]
2627
algorithm: 'ES256'
2728
# tip: use https://mkjwk.org/ to generate a JWK
2829
key: '{"kty":"EC","d":"iA_TV2zvftni_9aFAQwFO_9aypfJFCSpcCyevDvz220","crv":"P-256","x":"0QEAsI1wGI-dmYatdUZoWSRWggLEpyzopuhwk-YUnA4","y":"KYl-qyZ26HobuYwlQh-r0iHX61thfP82qqEku7i0woo"}'

src/Symfony/Component/Security/Http/AccessToken/Oidc/OidcTokenHandler.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public function __construct(
4242
private Algorithm $signatureAlgorithm,
4343
private JWK $jwk,
4444
private string $audience,
45+
private array $issuers,
4546
private ?LoggerInterface $logger = null,
4647
private ClockInterface $clock = new Clock(),
4748
private string $claim = 'sub'
@@ -81,6 +82,7 @@ public function getUserBadgeFrom(string $accessToken): UserBadge
8182
new Checker\NotBeforeChecker(0, false, $this->clock),
8283
new Checker\ExpirationTimeChecker(0, false, $this->clock),
8384
new Checker\AudienceChecker($this->audience),
85+
new Checker\IssuerChecker($this->issuers),
8486
];
8587
$claimCheckerManager = new ClaimCheckerManager($checkers);
8688
// if this check fails, an InvalidClaimException is thrown

src/Symfony/Component/Security/Http/Tests/AccessToken/Oidc/OidcTokenHandlerTest.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function testGetsUserIdentifierFromSignedToken(string $claim, string $exp
4141
'iat' => $time,
4242
'nbf' => $time,
4343
'exp' => $time + 3600,
44-
'iss' => 'https://www.example.com/',
44+
'iss' => 'https://www.example.com',
4545
'aud' => self::AUDIENCE,
4646
'sub' => 'e21bf182-1538-406e-8ccb-e25a17aba39f',
4747
'email' => 'foo@example.com',
@@ -56,6 +56,7 @@ public function testGetsUserIdentifierFromSignedToken(string $claim, string $exp
5656
new ES256(),
5757
$this->getJWK(),
5858
self::AUDIENCE,
59+
['https://www.example.com'],
5960
$loggerMock,
6061
new Clock(),
6162
$claim
@@ -90,6 +91,7 @@ public function testThrowsAnErrorIfTokenIsInvalid(string $token)
9091
new ES256(),
9192
$this->getJWK(),
9293
self::AUDIENCE,
94+
['https://www.example.com'],
9395
$loggerMock,
9496
new Clock(),
9597
'sub'
@@ -106,7 +108,7 @@ public static function getInvalidTokens(): iterable
106108
'iat' => time() - 3600,
107109
'nbf' => time() - 3600,
108110
'exp' => time() - 3590,
109-
'iss' => 'https://www.example.com/',
111+
'iss' => 'https://www.example.com',
110112
'aud' => self::AUDIENCE,
111113
'sub' => 'e21bf182-1538-406e-8ccb-e25a17aba39f',
112114
'email' => 'foo@example.com',
@@ -118,7 +120,7 @@ public static function getInvalidTokens(): iterable
118120
'iat' => time(),
119121
'nbf' => time(),
120122
'exp' => time() + 3590,
121-
'iss' => 'https://www.example.com/',
123+
'iss' => 'https://www.example.com',
122124
'aud' => 'invalid',
123125
'sub' => 'e21bf182-1538-406e-8ccb-e25a17aba39f',
124126
'email' => 'foo@example.com',
@@ -139,7 +141,7 @@ public function testThrowsAnErrorIfUserPropertyIsMissing()
139141
'iat' => $time,
140142
'nbf' => $time,
141143
'exp' => $time + 3600,
142-
'iss' => 'https://www.example.com/',
144+
'iss' => 'https://www.example.com',
143145
'aud' => self::AUDIENCE,
144146
'sub' => 'e21bf182-1538-406e-8ccb-e25a17aba39f',
145147
];
@@ -149,6 +151,7 @@ public function testThrowsAnErrorIfUserPropertyIsMissing()
149151
new ES256(),
150152
self::getJWK(),
151153
self::AUDIENCE,
154+
['https://www.example.com'],
152155
$loggerMock,
153156
new Clock(),
154157
'email'

0 commit comments

Comments
 (0)
0