Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit41e0030

Browse files
committed
[Security][SecurityBundle] Add encryption support to OIDC tokens
The changes add encryption support to OpenID Connect (OIDC) tokens in the Symfony Security Bundle. This is useful in making the application more secure. They also ensure the tokens are correctly decrypted and validated before use. Additionally, tests have been expanded to cover these new scenarios.security:
1 parentae5843f commit41e0030

File tree

12 files changed

+492
-64
lines changed

12 files changed

+492
-64
lines changed

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class UnusedTagsPass implements CompilerPassInterface
8585
'routing.route_loader',
8686
'scheduler.schedule_provider',
8787
'scheduler.task',
88+
'security.access_token_handler.oidc.encryption_algorithm',
8889
'security.access_token_handler.oidc.signature_algorithm',
8990
'security.authenticator.login_linker',
9091
'security.expression_language_provider',

‎src/Symfony/Bundle/SecurityBundle/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
---
66

77
* Add`Security::isGrantedForUser()` to test user authorization without relying on the session. For example, users not currently logged in, or while processing a message from a message queue
8+
* Add encryption support to`OidcTokenHandler` (JWE)
89

910
7.2
1011
---

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

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,22 @@ public function create(ContainerBuilder $container, string $id, array|string $co
4141
$tokenHandlerDefinition->replaceArgument(1, (newChildDefinition('security.access_token_handler.oidc.jwkset'))
4242
->replaceArgument(0,$config['keyset'])
4343
);
44+
45+
if ($config['encryption']['enabled']) {
46+
$algorithmManager = (newChildDefinition('security.access_token_handler.oidc.encryption'))
47+
->replaceArgument(0,$config['encryption']['algorithms']);
48+
$keyset = (newChildDefinition('security.access_token_handler.oidc.jwkset'))
49+
->replaceArgument(0,$config['encryption']['keyset']);
50+
51+
$tokenHandlerDefinition->addMethodCall(
52+
'enabledJweSupport',
53+
[
54+
$keyset,
55+
$algorithmManager,
56+
$config['encryption']['enforce'],
57+
]
58+
);
59+
}
4460
}
4561

4662
publicfunctiongetKey():string
@@ -112,9 +128,28 @@ public function addConfiguration(NodeBuilder $node): void
112128
->setDeprecated('symfony/security-bundle','7.1','The "%node%" option is deprecated and will be removed in 8.0. Use the "keyset" option instead.')
113129
->end()
114130
->scalarNode('keyset')
115-
->info('JSON-encoded JWKSet used to sign the token (must contain a list of valid keys).')
131+
->info('JSON-encoded JWKSet used to sign the token (must contain a list of validpublickeys).')
116132
->isRequired()
117133
->end()
134+
->arrayNode('encryption')
135+
->canBeEnabled()
136+
->children()
137+
->booleanNode('enforce')
138+
->info('When enabled, the token shall be encrypted.')
139+
->defaultFalse()
140+
->end()
141+
->arrayNode('algorithms')
142+
->info('Algorithms used to decrypt the token.')
143+
->isRequired()
144+
->requiresAtLeastOneElement()
145+
->scalarPrototype()->end()
146+
->end()
147+
->scalarNode('keyset')
148+
->info('JSON-encoded JWKSet used to decrypt the token (must contain a list of valid private keys).')
149+
->isRequired()
150+
->end()
151+
->end()
152+
->end()
118153
->end()
119154
->end()
120155
;

‎src/Symfony/Bundle/SecurityBundle/Resources/config/schema/security-1.0.xsd

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,13 +338,29 @@
338338
<xsd:choicemaxOccurs="unbounded">
339339
<xsd:elementname="issuers"type="oidc_issuers"minOccurs="0"maxOccurs="1" />
340340
<xsd:elementname="issuer"type="password_hasher"minOccurs="0"maxOccurs="unbounded" />
341+
<xsd:elementname="encryption"type="oidc_encryption" />
341342
</xsd:choice>
342343
<xsd:attributename="claim"type="xsd:string" />
343344
<xsd:attributename="audience"type="xsd:string"use="required" />
344345
<xsd:attributename="algorithm"type="xsd:string"use="required" />
345346
<xsd:attributename="key"type="xsd:string"use="required" />
346347
</xsd:complexType>
347348

349+
<xsd:complexTypename="oidc_encryption">
350+
<xsd:choicemaxOccurs="unbounded">
351+
<xsd:elementname="algorithms"type="oidc_encryption_algorithms"minOccurs="1"maxOccurs="1" />
352+
</xsd:choice>
353+
<xsd:attributename="enabled"type="xsd:boolean" />
354+
<xsd:attributename="enforce"type="xsd:boolean" />
355+
<xsd:attributename="keyset"type="xsd:string"use="required" />
356+
</xsd:complexType>
357+
358+
<xsd:complexTypename="oidc_encryption_algorithms">
359+
<xsd:sequence>
360+
<xsd:elementname="algorithm"type="xsd:string"minOccurs="1"maxOccurs="unbounded" />
361+
</xsd:sequence>
362+
</xsd:complexType>
363+
348364
<xsd:complexTypename="oidc_issuers">
349365
<xsd:sequence>
350366
<xsd:elementname="issuer"type="xsd:string"minOccurs="1"maxOccurs="unbounded" />

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

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@
1515
useJose\Component\Core\AlgorithmManagerFactory;
1616
useJose\Component\Core\JWK;
1717
useJose\Component\Core\JWKSet;
18+
useJose\Component\Encryption\Algorithm\ContentEncryption\A128CBCHS256;
19+
useJose\Component\Encryption\Algorithm\ContentEncryption\A128GCM;
20+
useJose\Component\Encryption\Algorithm\ContentEncryption\A192CBCHS384;
21+
useJose\Component\Encryption\Algorithm\ContentEncryption\A192GCM;
22+
useJose\Component\Encryption\Algorithm\ContentEncryption\A256CBCHS512;
23+
useJose\Component\Encryption\Algorithm\ContentEncryption\A256GCM;
24+
useJose\Component\Encryption\Algorithm\KeyEncryption\ECDHES;
25+
useJose\Component\Encryption\Algorithm\KeyEncryption\ECDHSS;
26+
useJose\Component\Encryption\Algorithm\KeyEncryption\RSAOAEP;
1827
useJose\Component\Signature\Algorithm\ES256;
1928
useJose\Component\Signature\Algorithm\ES384;
2029
useJose\Component\Signature\Algorithm\ES512;
@@ -135,5 +144,47 @@
135144

136145
->set('security.access_token_handler.oidc.signature.PS512',PS512::class)
137146
->tag('security.access_token_handler.oidc.signature_algorithm')
147+
148+
// Encryption
149+
// Note that - all xxxKW algorithms are not defined as an extra dependency is required
150+
// - The RSA_1.5 is missing as deprecated
151+
->set('security.access_token_handler.oidc.encryption_algorithm_manager_factory', AlgorithmManagerFactory::class)
152+
->args([
153+
tagged_iterator('security.access_token_handler.oidc.encryption_algorithm'),
154+
])
155+
156+
->set('security.access_token_handler.oidc.encryption', AlgorithmManager::class)
157+
->abstract()
158+
->factory([service('security.access_token_handler.oidc.encryption_algorithm_manager_factory'),'create'])
159+
->args([
160+
abstract_arg('encryption algorithms'),
161+
])
162+
163+
->set('security.access_token_handler.oidc.encryption.RSAOAEP',RSAOAEP::class)
164+
->tag('security.access_token_handler.oidc.encryption_algorithm')
165+
166+
->set('security.access_token_handler.oidc.encryption.ECDHES',ECDHES::class)
167+
->tag('security.access_token_handler.oidc.encryption_algorithm')
168+
169+
->set('security.access_token_handler.oidc.encryption.ECDHSS',ECDHSS::class)
170+
->tag('security.access_token_handler.oidc.encryption_algorithm')
171+
172+
->set('security.access_token_handler.oidc.encryption.A128CBCHS256',A128CBCHS256::class)
173+
->tag('security.access_token_handler.oidc.encryption_algorithm')
174+
175+
->set('security.access_token_handler.oidc.encryption.A192CBCHS384',A192CBCHS384::class)
176+
->tag('security.access_token_handler.oidc.encryption_algorithm')
177+
178+
->set('security.access_token_handler.oidc.encryption.A256CBCHS512',A256CBCHS512::class)
179+
->tag('security.access_token_handler.oidc.encryption_algorithm')
180+
181+
->set('security.access_token_handler.oidc.encryption.A128GCM',A128GCM::class)
182+
->tag('security.access_token_handler.oidc.encryption_algorithm')
183+
184+
->set('security.access_token_handler.oidc.encryption.A192GCM',A192GCM::class)
185+
->tag('security.access_token_handler.oidc.encryption_algorithm')
186+
187+
->set('security.access_token_handler.oidc.encryption.A256GCM',A256GCM::class)
188+
->tag('security.access_token_handler.oidc.encryption_algorithm')
138189
;
139190
};

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

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public function testInvalidOidcTokenHandlerConfigurationKeyMissing()
113113
$factory =newAccessTokenFactory($this->createTokenHandlerFactories());
114114

115115
$this->expectException(InvalidConfigurationException::class);
116-
$this->expectExceptionMessage('The child config "keyset" under "access_token.token_handler.oidc" must be configured: JSON-encoded JWKSet used to sign the token (must contain a list of valid keys).');
116+
$this->expectExceptionMessage('The child config "keyset" under "access_token.token_handler.oidc" must be configured: JSON-encoded JWKSet used to sign the token (must contain a list of validpublickeys).');
117117

118118
$this->processConfig($config,$factory);
119119
}
@@ -257,6 +257,88 @@ public function testOidcTokenHandlerConfigurationWithMultipleAlgorithms()
257257
$this->assertEquals($expected,$container->getDefinition('security.access_token_handler.firewall1')->getArguments());
258258
}
259259

260+
publicfunctiontestOidcTokenHandlerConfigurationWithEncryption()
261+
{
262+
$container =newContainerBuilder();
263+
$jwkset ='{"keys":[{"kty":"EC","crv":"P-256","x":"FtgMtrsKDboRO-Zo0XC7tDJTATHVmwuf9GK409kkars","y":"rWDE0ERU2SfwGYCo1DWWdgFEbZ0MiAXLRBBOzBgs_jY","d":"4G7bRIiKih0qrFxc0dtvkHUll19tTyctoCR3eIbOrO0"},{"kty":"EC","crv":"P-256","x":"0QEAsI1wGI-dmYatdUZoWSRWggLEpyzopuhwk-YUnA4","y":"KYl-qyZ26HobuYwlQh-r0iHX61thfP82qqEku7i0woo","d":"iA_TV2zvftni_9aFAQwFO_9aypfJFCSpcCyevDvz220"}]}';
264+
$config = [
265+
'token_handler' => [
266+
'oidc' => [
267+
'algorithms' => ['RS256','ES256'],
268+
'issuers' => ['https://www.example.com'],
269+
'audience' =>'audience',
270+
'keyset' =>$jwkset,
271+
'encryption' => [
272+
'enabled' =>true,
273+
'keyset' =>$jwkset,
274+
'algorithms' => ['RSA-OAEP','RSA1_5'],
275+
],
276+
],
277+
],
278+
];
279+
280+
$factory =newAccessTokenFactory($this->createTokenHandlerFactories());
281+
$finalizedConfig =$this->processConfig($config,$factory);
282+
283+
$factory->createAuthenticator($container,'firewall1',$finalizedConfig,'userprovider');
284+
285+
$this->assertTrue($container->hasDefinition('security.authenticator.access_token.firewall1'));
286+
$this->assertTrue($container->hasDefinition('security.access_token_handler.firewall1'));
287+
}
288+
289+
publicfunctiontestInvalidOidcTokenHandlerConfigurationMissingEncryptionKeyset()
290+
{
291+
$jwkset ='{"keys":[{"kty":"EC","crv":"P-256","x":"FtgMtrsKDboRO-Zo0XC7tDJTATHVmwuf9GK409kkars","y":"rWDE0ERU2SfwGYCo1DWWdgFEbZ0MiAXLRBBOzBgs_jY","d":"4G7bRIiKih0qrFxc0dtvkHUll19tTyctoCR3eIbOrO0"},{"kty":"EC","crv":"P-256","x":"0QEAsI1wGI-dmYatdUZoWSRWggLEpyzopuhwk-YUnA4","y":"KYl-qyZ26HobuYwlQh-r0iHX61thfP82qqEku7i0woo","d":"iA_TV2zvftni_9aFAQwFO_9aypfJFCSpcCyevDvz220"}]}';
292+
$config = [
293+
'token_handler' => [
294+
'oidc' => [
295+
'algorithms' => ['RS256','ES256'],
296+
'issuers' => ['https://www.example.com'],
297+
'audience' =>'audience',
298+
'keyset' =>$jwkset,
299+
'encryption' => [
300+
'enabled' =>true,
301+
'algorithms' => ['RSA-OAEP','RSA1_5'],
302+
],
303+
],
304+
],
305+
];
306+
307+
$factory =newAccessTokenFactory($this->createTokenHandlerFactories());
308+
309+
$this->expectException(InvalidConfigurationException::class);
310+
$this->expectExceptionMessage('The child config "keyset" under "access_token.token_handler.oidc.encryption" must be configured: JSON-encoded JWKSet used to decrypt the token (must contain a list of valid private keys).');
311+
312+
$this->processConfig($config,$factory);
313+
}
314+
315+
publicfunctiontestInvalidOidcTokenHandlerConfigurationMissingAlgorithm()
316+
{
317+
$jwkset ='{"keys":[{"kty":"EC","crv":"P-256","x":"FtgMtrsKDboRO-Zo0XC7tDJTATHVmwuf9GK409kkars","y":"rWDE0ERU2SfwGYCo1DWWdgFEbZ0MiAXLRBBOzBgs_jY","d":"4G7bRIiKih0qrFxc0dtvkHUll19tTyctoCR3eIbOrO0"},{"kty":"EC","crv":"P-256","x":"0QEAsI1wGI-dmYatdUZoWSRWggLEpyzopuhwk-YUnA4","y":"KYl-qyZ26HobuYwlQh-r0iHX61thfP82qqEku7i0woo","d":"iA_TV2zvftni_9aFAQwFO_9aypfJFCSpcCyevDvz220"}]}';
318+
$config = [
319+
'token_handler' => [
320+
'oidc' => [
321+
'algorithms' => ['RS256','ES256'],
322+
'issuers' => ['https://www.example.com'],
323+
'audience' =>'audience',
324+
'keyset' =>$jwkset,
325+
'encryption' => [
326+
'enabled' =>true,
327+
'keyset' =>$jwkset,
328+
'algorithms' => [],
329+
],
330+
],
331+
],
332+
];
333+
334+
$factory =newAccessTokenFactory($this->createTokenHandlerFactories());
335+
336+
$this->expectException(InvalidConfigurationException::class);
337+
$this->expectExceptionMessage('The path "access_token.token_handler.oidc.encryption.algorithms" should have at least 1 element(s) defined.');
338+
339+
$this->processConfig($config,$factory);
340+
}
341+
260342
publicfunctiontestOidcUserInfoTokenHandlerConfigurationWithExistingClient()
261343
{
262344
$container =newContainerBuilder();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp