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

Commit251957a

Browse files
[Security] add "anonymous: lazy" mode to firewalls
1 parent20df3a1 commit251957a

File tree

9 files changed

+223
-3
lines changed

9 files changed

+223
-3
lines changed

‎src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
useSymfony\Component\HttpFoundation\Response;
1818
useSymfony\Component\HttpKernel\DataCollector\DataCollector;
1919
useSymfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
20+
useSymfony\Component\Security\Core\Authentication\Token\AnonymousToken;
2021
useSymfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
2122
useSymfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
2223
useSymfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
@@ -127,7 +128,7 @@ public function collect(Request $request, Response $response, \Exception $except
127128

128129
$logoutUrl =null;
129130
try {
130-
if (null !==$this->logoutUrlGenerator) {
131+
if (null !==$this->logoutUrlGenerator &&$token && !$tokeninstanceof AnonymousToken) {
131132
$logoutUrl =$this->logoutUrlGenerator->getLogoutPath();
132133
}
133134
}catch (\Exception$e) {

‎src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AnonymousFactory.php‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,12 @@ public function getKey()
5555
publicfunctionaddConfiguration(NodeDefinition$builder)
5656
{
5757
$builder
58+
->beforeNormalization()
59+
->ifTrue(function ($v) {return'lazy' ===$v; })
60+
->then(function ($v) {return ['lazy' =>true]; })
61+
->end()
5862
->children()
63+
->booleanNode('lazy')->end()
5964
->scalarNode('secret')->defaultNull()->end()
6065
->end()
6166
;

‎src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,8 @@ private function createFirewalls(array $config, ContainerBuilder $container)
243243
list($matcher,$listeners,$exceptionListener,$logoutListener) =$this->createFirewall($container,$name,$firewall,$authenticationProviders,$providerIds,$configId);
244244

245245
$contextId ='security.firewall.map.context.'.$name;
246-
$context =$container->setDefinition($contextId,newChildDefinition('security.firewall.context'));
246+
$context =newChildDefinition($firewall['stateless'] ||empty($firewall['anonymous']['lazy']) ?'security.firewall.context' :'security.firewall.lazy_context');
247+
$context =$container->setDefinition($contextId,$context);
247248
$context
248249
->replaceArgument(0,newIteratorArgument($listeners))
249250
->replaceArgument(1,$exceptionListener)
@@ -409,7 +410,9 @@ private function createFirewall(ContainerBuilder $container, string $id, array $
409410
}
410411

411412
// Access listener
412-
$listeners[] =newReference('security.access_listener');
413+
if ($firewall['stateless'] ||empty($firewall['anonymous']['lazy'])) {
414+
$listeners[] =newReference('security.access_listener');
415+
}
413416

414417
// Exception listener
415418
$exceptionListener =newReference($this->createExceptionListener($container,$firewall,$id,$configuredEntryPoint ?:$defaultEntryPoint,$firewall['stateless']));

‎src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,16 @@
151151
<argument /><!-- FirewallConfig-->
152152
</service>
153153

154+
<serviceid="security.firewall.lazy_context"class="Symfony\Bundle\SecurityBundle\Security\LazyFirewallContext"abstract="true">
155+
<argumenttype="collection" />
156+
<argumenttype="service"id="security.exception_listener" />
157+
<argument /><!-- LogoutListener-->
158+
<argument /><!-- FirewallConfig-->
159+
<argumenttype="service"id="security.access_listener" />
160+
<argumenttype="service"id="security.untracked_token_storage" />
161+
<argumenttype="service"id="security.access_map" />
162+
</service>
163+
154164
<serviceid="security.firewall.config"class="Symfony\Bundle\SecurityBundle\Security\FirewallConfig"abstract="true">
155165
<argument /><!-- name-->
156166
<argument /><!-- user_checker-->
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Bundle\SecurityBundle\Security;
13+
14+
useSymfony\Component\HttpKernel\Event\RequestEvent;
15+
useSymfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
16+
useSymfony\Component\Security\Core\Exception\LazyResponseException;
17+
useSymfony\Component\Security\Http\AccessMapInterface;
18+
useSymfony\Component\Security\Http\Event\LazyResponseEvent;
19+
useSymfony\Component\Security\Http\Firewall\AccessListener;
20+
useSymfony\Component\Security\Http\Firewall\ExceptionListener;
21+
useSymfony\Component\Security\Http\Firewall\LogoutListener;
22+
23+
/**
24+
* Lazily calls authentication listeners when actually required by the access listener.
25+
*
26+
* @author Nicolas Grekas <p@tchwork.com>
27+
*/
28+
class LazyFirewallContextextends FirewallContext
29+
{
30+
private$accessListener;
31+
private$tokenStorage;
32+
private$map;
33+
34+
publicfunction__construct(iterable$listeners, ?ExceptionListener$exceptionListener, ?LogoutListener$logoutListener, ?FirewallConfig$config,AccessListener$accessListener,TokenStorage$tokenStorage,AccessMapInterface$map)
35+
{
36+
parent::__construct($listeners,$exceptionListener,$logoutListener,$config);
37+
38+
$this->accessListener =$accessListener;
39+
$this->tokenStorage =$tokenStorage;
40+
$this->map =$map;
41+
}
42+
43+
publicfunctiongetListeners():iterable
44+
{
45+
return [$this];
46+
}
47+
48+
publicfunction__invoke(RequestEvent$event)
49+
{
50+
$this->tokenStorage->setInitializer(function ()use ($event) {
51+
$event =newLazyResponseEvent($event);
52+
foreach (parent::getListeners()as$listener) {
53+
if (\is_callable($listener)) {
54+
$listener($event);
55+
}else {
56+
@trigger_error(sprintf('Calling the "%s::handle()" method from the firewall is deprecated since Symfony 4.3, implement "__invoke()" instead.',\get_class($this)),E_USER_DEPRECATED);
57+
$listener->handle($event);
58+
}
59+
}
60+
});
61+
62+
try {
63+
[$attributes] =$this->map->getPatterns($event->getRequest());
64+
65+
if ($attributes) {
66+
($this->accessListener)($event);
67+
}
68+
}catch (LazyResponseException$e) {
69+
$event->setResponse($e->getResponse());
70+
}
71+
}
72+
}

‎src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorage.php‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,18 @@
2525
class TokenStorageimplements TokenStorageInterface, ResetInterface
2626
{
2727
private$token;
28+
private$initializer;
2829

2930
/**
3031
* {@inheritdoc}
3132
*/
3233
publicfunctiongetToken()
3334
{
35+
if ($initializer =$this->initializer) {
36+
$this->initializer =null;
37+
$initializer();
38+
}
39+
3440
return$this->token;
3541
}
3642

@@ -43,9 +49,15 @@ public function setToken(TokenInterface $token = null)
4349
@trigger_error(sprintf('Not implementing the "%s::getRoleNames()" method in "%s" is deprecated since Symfony 4.3.', TokenInterface::class,\get_class($token)),E_USER_DEPRECATED);
4450
}
4551

52+
$this->initializer =null;
4653
$this->token =$token;
4754
}
4855

56+
publicfunctionsetInitializer(\Closure$initializer):void
57+
{
58+
$this->initializer =$initializer;
59+
}
60+
4961
publicfunctionreset()
5062
{
5163
$this->setToken(null);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Security\Core\Exception;
13+
14+
useSymfony\Component\HttpFoundation\Response;
15+
16+
/**
17+
* Wraps a lazily computed response in a signaling exception.
18+
*
19+
* @author Nicolas Grekas <p@tchwork.com>
20+
*/
21+
class LazyResponseExceptionextends \Exceptionimplements ExceptionInterface
22+
{
23+
private$response;
24+
25+
publicfunction__construct(Response$response)
26+
{
27+
$this->response =$response;
28+
}
29+
30+
publicfunctiongetResponse():Response
31+
{
32+
return$this->response;
33+
}
34+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Security\Http\Event;
13+
14+
useSymfony\Component\HttpFoundation\Request;
15+
useSymfony\Component\HttpFoundation\Response;
16+
useSymfony\Component\HttpKernel\Event\RequestEvent;
17+
useSymfony\Component\HttpKernel\HttpKernelInterface;
18+
useSymfony\Component\Security\Core\Exception\LazyResponseException;
19+
20+
/**
21+
* Wraps a lazily computed response in a signaling exception.
22+
*
23+
* @author Nicolas Grekas <p@tchwork.com>
24+
*/
25+
finalclass LazyResponseEventextends RequestEvent
26+
{
27+
private$event;
28+
29+
publicfunction__construct(parent$event)
30+
{
31+
$this->event =$event;
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
publicfunctionsetResponse(Response$response)
38+
{
39+
$this->stopPropagation();
40+
$this->event->stopPropagation();
41+
42+
thrownewLazyResponseException($response);
43+
}
44+
45+
/**
46+
* {@inheritdoc}
47+
*/
48+
publicfunctiongetKernel():HttpKernelInterface
49+
{
50+
return$this->event->getKernel();
51+
}
52+
53+
/**
54+
* {@inheritdoc}
55+
*/
56+
publicfunctiongetRequest():Request
57+
{
58+
return$this->event->getRequest();
59+
}
60+
61+
/**
62+
* {@inheritdoc}
63+
*/
64+
publicfunctiongetRequestType():int
65+
{
66+
return$this->event->getRequestType();
67+
}
68+
69+
/**
70+
* {@inheritdoc}
71+
*/
72+
publicfunctionisMasterRequest():bool
73+
{
74+
return$this->event->isMasterRequest();
75+
}
76+
}

‎src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
useSymfony\Component\Security\Core\Exception\AccountStatusException;
2727
useSymfony\Component\Security\Core\Exception\AuthenticationException;
2828
useSymfony\Component\Security\Core\Exception\InsufficientAuthenticationException;
29+
useSymfony\Component\Security\Core\Exception\LazyResponseException;
2930
useSymfony\Component\Security\Core\Exception\LogoutException;
3031
useSymfony\Component\Security\Core\Security;
3132
useSymfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;
@@ -103,6 +104,12 @@ public function onKernelException(GetResponseForExceptionEvent $event)
103104
return;
104105
}
105106

107+
if ($exceptioninstanceof LazyResponseException) {
108+
$event->setResponse($exception->getResponse());
109+
110+
return;
111+
}
112+
106113
if ($exceptioninstanceof LogoutException) {
107114
$this->handleLogoutException($exception);
108115

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp