Skip to content

Commit 29d2cd8

Browse files
committed
Removed anonymous stuff from new system
1 parent c30d6f9 commit 29d2cd8

File tree

12 files changed

+138
-156
lines changed

12 files changed

+138
-156
lines changed

UPGRADE-5.1.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,24 @@ Routing
112112
SecurityBundle
113113
--------------
114114

115+
* Deprecated `anonymous: lazy` in favor of `lazy: true`
116+
117+
*Before*
118+
```yaml
119+
security:
120+
firewalls:
121+
main:
122+
anonymous: lazy
123+
```
124+
125+
*After*
126+
```yaml
127+
security:
128+
firewalls:
129+
main:
130+
anonymous: true
131+
lazy: true
132+
```
115133
* Marked the `AbstractFactory`, `AnonymousFactory`, `FormLoginFactory`, `FormLoginLdapFactory`, `GuardAuthenticationFactory`,
116134
`HttpBasicFactory`, `HttpBasicLdapFactory`, `JsonLoginFactory`, `JsonLoginLdapFactory`, `RememberMeFactory`, `RemoteUserFactory`
117135
and `X509Factory` as `@internal`. Instead of extending these classes, create your own implementation based on

src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ private function addFirewallsSection(ArrayNodeDefinition $rootNode, array $facto
197197
->scalarNode('entry_point')->end()
198198
->scalarNode('provider')->end()
199199
->booleanNode('stateless')->defaultFalse()->end()
200+
->booleanNode('lazy')->defaultFalse()->end()
200201
->scalarNode('context')->cannotBeEmpty()->end()
201202
->arrayNode('logout')
202203
->treatTrueLike([])

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

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory;
1313

1414
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
15+
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
1516
use Symfony\Component\DependencyInjection\ChildDefinition;
1617
use Symfony\Component\DependencyInjection\ContainerBuilder;
1718
use Symfony\Component\DependencyInjection\Parameter;
@@ -46,16 +47,7 @@ public function create(ContainerBuilder $container, $id, $config, $userProvider,
4647

4748
public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId): string
4849
{
49-
if (null === $config['secret']) {
50-
$config['secret'] = new Parameter('container.build_hash');
51-
}
52-
53-
$authenticatorId = 'security.authenticator.anonymous.'.$firewallName;
54-
$container
55-
->setDefinition($authenticatorId, new ChildDefinition('security.authenticator.anonymous'))
56-
->replaceArgument(0, $config['secret']);
57-
58-
return $authenticatorId;
50+
throw new InvalidConfigurationException(sprintf('The authenticator manager no longer has "anonymous" security. Please remove this option under the "%s" firewall'.($config['lazy'] ? ' and add "lazy: true".' : '.'), $firewallName));
5951
}
6052

6153
public function getPosition()
@@ -76,7 +68,7 @@ public function addConfiguration(NodeDefinition $builder)
7668
->then(function ($v) { return ['lazy' => true]; })
7769
->end()
7870
->children()
79-
->booleanNode('lazy')->defaultFalse()->end()
71+
->booleanNode('lazy')->defaultFalse()->setDeprecated('symfony/security-bundle', '5.1', 'Using "anonymous: lazy" to make the firewall lazy is deprecated, use "lazy: true" instead.')->end()
8072
->scalarNode('secret')->defaultNull()->end()
8173
->end()
8274
;

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ public function load(array $configs, ContainerBuilder $container)
111111

112112
if ($this->authenticatorManagerEnabled = $config['enable_authenticator_manager']) {
113113
$loader->load('security_authenticator.xml');
114+
115+
// The authenticator system no longer has anonymous tokens. This makes sure AccessListener
116+
// and AuthorizationChecker do not throw AuthenticationCredentialsNotFoundException when no
117+
// token is available in the token storage.
118+
$container->getDefinition('security.access_listener')->setArgument(4, false);
119+
$container->getDefinition('security.authorization_checker')->setArgument(4, false);
120+
$container->getDefinition('security.authorization_checker')->setArgument(5, false);
114121
} else {
115122
$loader->load('security_legacy.xml');
116123
}
@@ -268,7 +275,8 @@ private function createFirewalls(array $config, ContainerBuilder $container)
268275
list($matcher, $listeners, $exceptionListener, $logoutListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds, $configId);
269276

270277
$contextId = 'security.firewall.map.context.'.$name;
271-
$context = new ChildDefinition($firewall['stateless'] || empty($firewall['anonymous']['lazy']) ? 'security.firewall.context' : 'security.firewall.lazy_context');
278+
$isLazy = !$firewall['stateless'] && (!empty($firewall['anonymous']['lazy']) || $firewall['lazy']);
279+
$context = new ChildDefinition($isLazy ? 'security.firewall.lazy_context' : 'security.firewall.context');
272280
$context = $container->setDefinition($contextId, $context);
273281
$context
274282
->replaceArgument(0, new IteratorArgument($listeners))

src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator.xml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,6 @@
111111
<argument type="service" id="property_accessor" on-invalid="null" />
112112
</service>
113113

114-
<service id="security.authenticator.anonymous"
115-
class="Symfony\Component\Security\Http\Authenticator\AnonymousAuthenticator"
116-
abstract="true">
117-
<argument type="abstract">secret</argument>
118-
<argument type="service" id="security.untracked_token_storage" />
119-
</service>
120-
121114
<service id="security.authenticator.remember_me"
122115
class="Symfony\Component\Security\Http\Authenticator\RememberMeAuthenticator"
123116
abstract="true">

src/Symfony/Component/Security/Core/Authorization/AuthorizationChecker.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Security\Core\Authorization;
1313

1414
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
15+
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
1516
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
1617
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
1718

@@ -29,24 +30,30 @@ class AuthorizationChecker implements AuthorizationCheckerInterface
2930
private $accessDecisionManager;
3031
private $authenticationManager;
3132
private $alwaysAuthenticate;
33+
private $exceptionOnNoToken;
3234

33-
public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, AccessDecisionManagerInterface $accessDecisionManager, bool $alwaysAuthenticate = false)
35+
public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, AccessDecisionManagerInterface $accessDecisionManager, bool $alwaysAuthenticate = false, bool $exceptionOnNoToken = true)
3436
{
3537
$this->tokenStorage = $tokenStorage;
3638
$this->authenticationManager = $authenticationManager;
3739
$this->accessDecisionManager = $accessDecisionManager;
3840
$this->alwaysAuthenticate = $alwaysAuthenticate;
41+
$this->exceptionOnNoToken = $exceptionOnNoToken;
3942
}
4043

4144
/**
4245
* {@inheritdoc}
4346
*
44-
* @throws AuthenticationCredentialsNotFoundException when the token storage has no authentication token
47+
* @throws AuthenticationCredentialsNotFoundException when the token storage has no authentication token and $exceptionOnNoToken is set to true
4548
*/
4649
final public function isGranted($attribute, $subject = null): bool
4750
{
4851
if (null === ($token = $this->tokenStorage->getToken())) {
49-
throw new AuthenticationCredentialsNotFoundException('The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL.');
52+
if ($this->exceptionOnNoToken) {
53+
throw new AuthenticationCredentialsNotFoundException('The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL.');
54+
}
55+
56+
return false;
5057
}
5158

5259
if ($this->alwaysAuthenticate || !$token->isAuthenticated()) {

src/Symfony/Component/Security/Core/Tests/Authorization/AuthorizationCheckerTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ public function testVoteWithoutAuthenticationToken()
7373
$this->authorizationChecker->isGranted('ROLE_FOO');
7474
}
7575

76+
public function testVoteWithoutAuthenticationTokenAndExceptionOnNoTokenIsFalse()
77+
{
78+
$authorizationChecker = new AuthorizationChecker($this->tokenStorage, $this->authenticationManager, $this->accessDecisionManager, false, false);
79+
80+
$this->assertFalse($authorizationChecker->isGranted('ROLE_FOO'));
81+
}
82+
7683
/**
7784
* @dataProvider isGrantedProvider
7885
*/

src/Symfony/Component/Security/Http/Authenticator/AnonymousAuthenticator.php

Lines changed: 0 additions & 67 deletions
This file was deleted.

src/Symfony/Component/Security/Http/Firewall/AccessListener.php

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,21 @@
3131
*/
3232
class AccessListener extends AbstractListener
3333
{
34+
const PUBLIC_ACCESS = 'PUBLIC_ACCESS';
35+
3436
private $tokenStorage;
3537
private $accessDecisionManager;
3638
private $map;
3739
private $authManager;
40+
private $exceptionOnNoToken;
3841

39-
public function __construct(TokenStorageInterface $tokenStorage, AccessDecisionManagerInterface $accessDecisionManager, AccessMapInterface $map, AuthenticationManagerInterface $authManager)
42+
public function __construct(TokenStorageInterface $tokenStorage, AccessDecisionManagerInterface $accessDecisionManager, AccessMapInterface $map, AuthenticationManagerInterface $authManager, bool $exceptionOnNoToken = true)
4043
{
4144
$this->tokenStorage = $tokenStorage;
4245
$this->accessDecisionManager = $accessDecisionManager;
4346
$this->map = $map;
4447
$this->authManager = $authManager;
48+
$this->exceptionOnNoToken = $exceptionOnNoToken;
4549
}
4650

4751
/**
@@ -52,18 +56,18 @@ public function supports(Request $request): ?bool
5256
[$attributes] = $this->map->getPatterns($request);
5357
$request->attributes->set('_access_control_attributes', $attributes);
5458

55-
return $attributes && [AuthenticatedVoter::IS_AUTHENTICATED_ANONYMOUSLY] !== $attributes ? true : null;
59+
return $attributes && ([AuthenticatedVoter::IS_AUTHENTICATED_ANONYMOUSLY] !== $attributes && [self::PUBLIC_ACCESS] !== $attributes) ? true : null;
5660
}
5761

5862
/**
5963
* Handles access authorization.
6064
*
6165
* @throws AccessDeniedException
62-
* @throws AuthenticationCredentialsNotFoundException
66+
* @throws AuthenticationCredentialsNotFoundException when the token storage has no authentication token and $exceptionOnNoToken is set to true
6367
*/
6468
public function authenticate(RequestEvent $event)
6569
{
66-
if (!$event instanceof LazyResponseEvent && null === $token = $this->tokenStorage->getToken()) {
70+
if (!$event instanceof LazyResponseEvent && null === ($token = $this->tokenStorage->getToken()) && $this->exceptionOnNoToken) {
6771
throw new AuthenticationCredentialsNotFoundException('A Token was not found in the TokenStorage.');
6872
}
6973

@@ -76,8 +80,26 @@ public function authenticate(RequestEvent $event)
7680
return;
7781
}
7882

79-
if ($event instanceof LazyResponseEvent && null === $token = $this->tokenStorage->getToken()) {
80-
throw new AuthenticationCredentialsNotFoundException('A Token was not found in the TokenStorage.');
83+
if ($event instanceof LazyResponseEvent) {
84+
$token = $this->tokenStorage->getToken();
85+
}
86+
87+
if (null === $token) {
88+
if ($this->exceptionOnNoToken) {
89+
throw new AuthenticationCredentialsNotFoundException('A Token was not found in the TokenStorage.');
90+
}
91+
92+
if ([AuthenticatedVoter::IS_AUTHENTICATED_ANONYMOUSLY] === $attributes) {
93+
trigger_deprecation('symfony/security-http', '5.1', 'Using "IS_AUTHENTICATED_ANONYMOUSLY" in your access_control rules when using the authenticator Security system is deprecated, use "PUBLIC_ACCESS" instead.');
94+
95+
return;
96+
}
97+
98+
if ([self::PUBLIC_ACCESS] === $attributes) {
99+
return;
100+
}
101+
102+
throw $this->createAccessDeniedException($request, $attributes);
81103
}
82104

83105
if (!$token->isAuthenticated()) {
@@ -86,11 +108,16 @@ public function authenticate(RequestEvent $event)
86108
}
87109

88110
if (!$this->accessDecisionManager->decide($token, $attributes, $request, true)) {
89-
$exception = new AccessDeniedException();
90-
$exception->setAttributes($attributes);
91-
$exception->setSubject($request);
92-
93-
throw $exception;
111+
throw $this->createAccessDeniedException($request, $attributes);
94112
}
95113
}
114+
115+
private function createAccessDeniedException(Request $request, array $attributes)
116+
{
117+
$exception = new AccessDeniedException();
118+
$exception->setAttributes($attributes);
119+
$exception->setSubject($request);
120+
121+
return $exception;
122+
}
96123
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,9 @@ private function handleAccessDeniedException(ExceptionEvent $event, AccessDenied
144144

145145
try {
146146
$insufficientAuthenticationException = new InsufficientAuthenticationException('Full authentication is required to access this resource.', 0, $exception);
147-
$insufficientAuthenticationException->setToken($token);
147+
if (null !== $token) {
148+
$insufficientAuthenticationException->setToken($token);
149+
}
148150

149151
$event->setResponse($this->startAuthentication($event->getRequest(), $insufficientAuthenticationException));
150152
} catch (\Exception $e) {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy