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

Appearance settings

Commit e3aca7f

Browse filesBrowse files
committed
[Security] Deprecate remaining anonymous checks
1 parent 76a7fe7 commit e3aca7f
Copy full SHA for e3aca7f

File tree

18 files changed

+158
-27
lines changed
Filter options

18 files changed

+158
-27
lines changed

‎UPGRADE-5.4.md

Copy file name to clipboardExpand all lines: UPGRADE-5.4.md
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,30 @@ Security
6262
* Deprecate `AnonymousToken`, as the related authenticator was deprecated in 5.3
6363
* Deprecate `Token::getCredentials()`, tokens should no longer contain credentials (as they represent authenticated sessions)
6464
* Deprecate not returning an `UserInterface` from `Token::getUser()`
65+
* Deprecate `AuthenticatedVoter::IS_AUTHENTICATED_ANONYMOUSLY` and `AuthenticatedVoter::IS_ANONYMOUS`,
66+
use `AuthenticatedVoter::PUBLIC_ACCESS` instead.
67+
68+
Before:
69+
```yaml
70+
# config/packages/security.yaml
71+
security:
72+
# ...
73+
access_control:
74+
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
75+
```
76+
77+
After:
78+
```yaml
79+
# config/packages/security.yaml
80+
security:
81+
# ...
82+
access_control:
83+
- { path: ^/login, roles: PUBLIC_ACCESS }
84+
```
85+
86+
* Deprecate `AuthenticationTrustResolverInterface::isAnonymous()` and the `is_anonymous()` expression function
87+
as anonymous no longer exists in version 6, use the `isFullFledged()` or the new `isAuthenticated()` instead
88+
if you want to check if the request is (fully) authenticated.
6589
* Deprecate the `$authManager` argument of `AccessListener`, the argument will be removed
6690
* Deprecate the `$authenticationManager` argument of the `AuthorizationChecker` constructor, the argument will be removed
6791
* Deprecate setting the `$alwaysAuthenticate` argument to `true` and not setting the

‎UPGRADE-6.0.md

Copy file name to clipboardExpand all lines: UPGRADE-6.0.md
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,30 @@ Security
210210
* Remove `AnonymousToken`
211211
* Remove `Token::getCredentials()`, tokens should no longer contain credentials (as they represent authenticated sessions)
212212
* Restrict the return type of `Token::getUser()` to `UserInterface` (removing `string|\Stringable`)
213+
* Remove `AuthenticatedVoter::IS_AUTHENTICATED_ANONYMOUSLY` and `AuthenticatedVoter::IS_ANONYMOUS`,
214+
use `AuthenticatedVoter::PUBLIC_ACCESS` instead.
215+
216+
Before:
217+
```yaml
218+
# config/packages/security.yaml
219+
security:
220+
# ...
221+
access_control:
222+
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
223+
```
224+
225+
After:
226+
```yaml
227+
# config/packages/security.yaml
228+
security:
229+
# ...
230+
access_control:
231+
- { path: ^/login, roles: PUBLIC_ACCESS }
232+
```
233+
234+
* Remove `AuthenticationTrustResolverInterface::isAnonymous()` and the `is_anonymous()` expression function
235+
as anonymous no longer exists in version 6, use the `isFullFledged()` or the new `isAuthenticated()` instead
236+
if you want to check if the request is (fully) authenticated.
213237
* Remove the 4th and 5th argument of `AuthorizationChecker`
214238
* Remove the 5th argument of `AccessListener`
215239
* Remove class `User`, use `InMemoryUser` or your own implementation instead.

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
5.4
55
---
66

7+
* Deprecate `FirewallConfig::allowsAnonymous()` and the `allows_anonymous` from the data collector data, there will be no anonymous concept as of version 6.
78
* Deprecate not setting `$authenticatorManagerEnabled` to `true` in `SecurityDataCollector` and `DebugFirewallCommand`
89
* Deprecate `SecurityFactoryInterface` and `SecurityExtension::addSecurityListenerFactory()` in favor of
910
`AuthenticatorFactoryInterface` and `SecurityExtension::addAuthenticatorFactory()`

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ public function collect(Request $request, Response $response, \Throwable $except
184184
if (null !== $firewallConfig) {
185185
$this->data['firewall'] = [
186186
'name' => $firewallConfig->getName(),
187-
'allows_anonymous' => $firewallConfig->allowsAnonymous(),
187+
'allows_anonymous' => $this->authenticatorManagerEnabled ? false : $firewallConfig->allowsAnonymous(),
188188
'request_matcher' => $firewallConfig->getRequestMatcher(),
189189
'security_enabled' => $firewallConfig->isSecurityEnabled(),
190190
'stateless' => $firewallConfig->isStateless(),

‎src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,13 @@ public function isSecurityEnabled(): bool
6464
return $this->securityEnabled;
6565
}
6666

67+
/**
68+
* @deprecated since Symfony 5.4
69+
*/
6770
public function allowsAnonymous(): bool
6871
{
72+
trigger_deprecation('symfony/security-bundle', '5.4', 'The "%s()" method is deprecated.', __METHOD__);
73+
6974
return \in_array('anonymous', $this->listeners, true);
7075
}
7176

‎src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ public function testGetFirewall()
141141
$collected = $collector->getFirewall();
142142

143143
$this->assertSame($firewallConfig->getName(), $collected['name']);
144-
$this->assertSame($firewallConfig->allowsAnonymous(), $collected['allows_anonymous']);
145144
$this->assertSame($firewallConfig->getRequestMatcher(), $collected['request_matcher']);
146145
$this->assertSame($firewallConfig->isSecurityEnabled(), $collected['security_enabled']);
147146
$this->assertSame($firewallConfig->isStateless(), $collected['stateless']);

‎src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/base_config.yml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/base_config.yml
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,5 @@ security:
5353
- { path: ^/secured-by-one-env-placeholder-and-one-real-ip$, ips: ['%env(APP_IP)%', 198.51.100.0], roles: IS_AUTHENTICATED_ANONYMOUSLY }
5454
- { path: ^/secured-by-one-env-placeholder-multiple-ips-and-one-real-ip$, ips: ['%env(APP_IPS)%', 198.51.100.0], roles: IS_AUTHENTICATED_ANONYMOUSLY }
5555
- { path: ^/highly_protected_resource$, roles: IS_ADMIN }
56-
- { path: ^/protected-via-expression$, allow_if: "(is_anonymous() and request.headers.get('user-agent') matches '/Firefox/i') or is_granted('ROLE_USER')" }
56+
- { path: ^/protected-via-expression$, allow_if: "(!is_authenticated() and request.headers.get('user-agent') matches '/Firefox/i') or is_granted('ROLE_USER')" }
5757
- { path: .*, roles: IS_AUTHENTICATED_FULLY }

‎src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallConfigTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallConfigTest.php
+1-2Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class FirewallConfigTest extends TestCase
1818
{
1919
public function testGetters()
2020
{
21-
$listeners = ['logout', 'remember_me', 'anonymous'];
21+
$listeners = ['logout', 'remember_me'];
2222
$options = [
2323
'request_matcher' => 'foo_request_matcher',
2424
'security' => false,
@@ -57,7 +57,6 @@ public function testGetters()
5757
$this->assertSame($options['access_denied_handler'], $config->getAccessDeniedHandler());
5858
$this->assertSame($options['access_denied_url'], $config->getAccessDeniedUrl());
5959
$this->assertSame($options['user_checker'], $config->getUserChecker());
60-
$this->assertTrue($config->allowsAnonymous());
6160
$this->assertSame($listeners, $config->getListeners());
6261
$this->assertSame($options['switch_user'], $config->getSwitchUser());
6362
}

‎src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php
+13-2Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,22 @@
2323
*/
2424
class AuthenticationTrustResolver implements AuthenticationTrustResolverInterface
2525
{
26+
public function isAuthenticated(TokenInterface $token = null): bool
27+
{
28+
return null !== $token && !$token instanceof NullToken
29+
// @deprecated since Symfony 5.4, TokenInterface::isAuthenticated() and AnonymousToken no longer exists in 6.0
30+
&& !$token instanceof AnonymousToken && $token->isAuthenticated(false);
31+
}
32+
2633
/**
2734
* {@inheritdoc}
2835
*/
29-
public function isAnonymous(TokenInterface $token = null)
36+
public function isAnonymous(TokenInterface $token = null/*, $deprecation = true*/)
3037
{
38+
if (1 === \func_num_args() || false !== func_get_arg(1)) {
39+
trigger_deprecation('symfony/security-core', '5.4', 'The "%s()" method is deprecated, use "isAuthenticated()" or "isFullFledged()" if you want to check if the request is (fully) authenticated.', __METHOD__);
40+
}
41+
3142
if (null === $token) {
3243
return false;
3344
}
@@ -56,6 +67,6 @@ public function isFullFledged(TokenInterface $token = null)
5667
return false;
5768
}
5869

59-
return !$this->isAnonymous($token) && !$this->isRememberMe($token);
70+
return !$this->isAnonymous($token, false) && !$this->isRememberMe($token);
6071
}
6172
}

‎src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolverInterface.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolverInterface.php
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
* Interface for resolving the authentication status of a given token.
1818
*
1919
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
20+
*
21+
* @method bool isAuthenticated(TokenInterface $token = null)
2022
*/
2123
interface AuthenticationTrustResolverInterface
2224
{
@@ -27,6 +29,8 @@ interface AuthenticationTrustResolverInterface
2729
* If null is passed, the method must return false.
2830
*
2931
* @return bool
32+
*
33+
* @deprecated since Symfony 5.4, use !isAuthenticated() instead
3034
*/
3135
public function isAnonymous(TokenInterface $token = null);
3236

‎src/Symfony/Component/Security/Core/Authorization/ExpressionLanguageProvider.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/Authorization/ExpressionLanguageProvider.php
+7-3Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
1515
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
16+
use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter;
1617

1718
/**
1819
* Define some ExpressionLanguage functions.
@@ -25,15 +26,18 @@ public function getFunctions()
2526
{
2627
return [
2728
new ExpressionFunction('is_anonymous', function () {
28-
return '$token && $auth_checker->isGranted("IS_ANONYMOUS")';
29+
return 'trigger_deprecation("symfony/security-core", "5.4", "The \"is_anonymous()\" expression function is deprecated.") || ($token && $auth_checker->isGranted("IS_ANONYMOUS"))';
2930
}, function (array $variables) {
31+
trigger_deprecation('symfony/security-core', '5.4', 'The "is_anonymous()" expression function is deprecated.');
32+
3033
return $variables['token'] && $variables['auth_checker']->isGranted('IS_ANONYMOUS');
3134
}),
3235

36+
// @deprecated remove the ternary and always use IS_AUTHENTICATED in 6.0
3337
new ExpressionFunction('is_authenticated', function () {
34-
return '$token && !$auth_checker->isGranted("IS_ANONYMOUS")';
38+
return 'defined("'.AuthenticatedVoter::class.'::IS_AUTHENTICATED") ? $auth_checker->isGranted("IS_AUTHENTICATED") : ($token && !$auth_checker->isGranted("IS_ANONYMOUS"))';
3539
}, function (array $variables) {
36-
return $variables['token'] && !$variables['auth_checker']->isGranted('IS_ANONYMOUS');
40+
return \defined(AuthenticatedVoter::class.'::IS_AUTHENTICATED') ? $variables['auth_checker']->isGranted('IS_AUTHENTICATED') : ($variables['token'] && !$variables['auth_checker']->isGranted('IS_ANONYMOUS'));
3741
}),
3842

3943
new ExpressionFunction('is_fully_authenticated', function () {

‎src/Symfony/Component/Security/Core/Authorization/Voter/AuthenticatedVoter.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/Authorization/Voter/AuthenticatedVoter.php
+22-1Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@
1212
namespace Symfony\Component\Security\Core\Authorization\Voter;
1313

1414
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
15+
use Symfony\Component\Security\Core\Authentication\Token\NullToken;
1516
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
1617
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
1718

1819
/**
1920
* AuthenticatedVoter votes if an attribute like IS_AUTHENTICATED_FULLY,
20-
* IS_AUTHENTICATED_REMEMBERED, or IS_AUTHENTICATED_ANONYMOUSLY is present.
21+
* IS_AUTHENTICATED_REMEMBERED, IS_AUTHENTICATED is present.
2122
*
2223
* This list is most restrictive to least restrictive checking.
2324
*
@@ -28,8 +29,15 @@ class AuthenticatedVoter implements VoterInterface
2829
{
2930
public const IS_AUTHENTICATED_FULLY = 'IS_AUTHENTICATED_FULLY';
3031
public const IS_AUTHENTICATED_REMEMBERED = 'IS_AUTHENTICATED_REMEMBERED';
32+
/**
33+
* @deprecated since Symfony 5.4
34+
*/
3135
public const IS_AUTHENTICATED_ANONYMOUSLY = 'IS_AUTHENTICATED_ANONYMOUSLY';
36+
/**
37+
* @deprecated since Symfony 5.4
38+
*/
3239
public const IS_ANONYMOUS = 'IS_ANONYMOUS';
40+
public const IS_AUTHENTICATED = 'IS_AUTHENTICATED';
3341
public const IS_IMPERSONATOR = 'IS_IMPERSONATOR';
3442
public const IS_REMEMBERED = 'IS_REMEMBERED';
3543
public const PUBLIC_ACCESS = 'PUBLIC_ACCESS';
@@ -55,6 +63,7 @@ public function vote(TokenInterface $token, $subject, array $attributes)
5563
if (null === $attribute || (self::IS_AUTHENTICATED_FULLY !== $attribute
5664
&& self::IS_AUTHENTICATED_REMEMBERED !== $attribute
5765
&& self::IS_AUTHENTICATED_ANONYMOUSLY !== $attribute
66+
&& self::IS_AUTHENTICATED !== $attribute
5867
&& self::IS_ANONYMOUS !== $attribute
5968
&& self::IS_IMPERSONATOR !== $attribute
6069
&& self::IS_REMEMBERED !== $attribute)) {
@@ -78,6 +87,16 @@ public function vote(TokenInterface $token, $subject, array $attributes)
7887
&& ($this->authenticationTrustResolver->isAnonymous($token)
7988
|| $this->authenticationTrustResolver->isRememberMe($token)
8089
|| $this->authenticationTrustResolver->isFullFledged($token))) {
90+
trigger_deprecation('symfony/security-core', '5.4', 'The "IS_AUTHENTICATED_ANONYMOUSLY" security attribute is deprecated, use "IS_AUTHENTICATED" or "IS_AUTHENTICATED_FULLY" instead if you want to check if the request is (fully) authenticated.');
91+
92+
return VoterInterface::ACCESS_GRANTED;
93+
}
94+
95+
// @deprecated $this->authenticationTrustResolver must implement isAuthenticated() in 6.0
96+
if (self::IS_AUTHENTICATED === $attribute
97+
&& (method_exists($this->authenticationTrustResolver, 'isAuthenticated')
98+
? $this->authenticationTrustResolver->isAuthenticated($token)
99+
: (null !== $token && !$token instanceof NullToken))) {
81100
return VoterInterface::ACCESS_GRANTED;
82101
}
83102

@@ -86,6 +105,8 @@ public function vote(TokenInterface $token, $subject, array $attributes)
86105
}
87106

88107
if (self::IS_ANONYMOUS === $attribute && $this->authenticationTrustResolver->isAnonymous($token)) {
108+
trigger_deprecation('symfony/security-core', '5.4', 'The "IS_ANONYMOUSLY" security attribute is deprecated, anonymous no longer exists in version 6.');
109+
89110
return VoterInterface::ACCESS_GRANTED;
90111
}
91112

‎src/Symfony/Component/Security/Core/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/CHANGELOG.md
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ CHANGELOG
77
* Deprecate `AnonymousToken`, as the related authenticator was deprecated in 5.3
88
* Deprecate `Token::getCredentials()`, tokens should no longer contain credentials (as they represent authenticated sessions)
99
* Deprecate returning `string|\Stringable` from `Token::getUser()` (it must return a `UserInterface`)
10+
* Deprecate `AuthenticatedVoter::IS_AUTHENTICATED_ANONYMOUSLY` and `AuthenticatedVoter::IS_ANONYMOUS`,
11+
use `AuthenticatedVoter::IS_AUTHENTICATED_FULLY` or `AuthenticatedVoter::IS_AUTHENTICATED` instead.
12+
* Deprecate `AuthenticationTrustResolverInterface::isAnonymous()` and the `is_anonymous()` expression
13+
function as anonymous no longer exists in version 6, use the `isFullFledged()` or the new
14+
`isAuthenticated()` instead if you want to check if the request is (fully) authenticated.
1015
* Deprecate the `$authenticationManager` argument of the `AuthorizationChecker` constructor
1116
* Deprecate setting the `$alwaysAuthenticate` argument to `true` and not setting the
1217
`$exceptionOnNoToken` argument to `false` of `AuthorizationChecker`

‎src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationTrustResolverTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationTrustResolverTest.php
+21-2Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,14 @@
1616
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
1717
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
1818
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
19+
use Symfony\Component\Security\Core\User\InMemoryUser;
20+
use Symfony\Component\Security\Core\User\User;
1921

2022
class AuthenticationTrustResolverTest extends TestCase
2123
{
24+
/**
25+
* @group legacy
26+
*/
2227
public function testIsAnonymous()
2328
{
2429
$resolver = new AuthenticationTrustResolver();
@@ -50,6 +55,17 @@ public function testisFullFledged()
5055
$this->assertTrue($resolver->isFullFledged(new FakeCustomToken()));
5156
}
5257

58+
public function testIsAuthenticated()
59+
{
60+
$resolver = new AuthenticationTrustResolver();
61+
$this->assertFalse($resolver->isAuthenticated(null));
62+
$this->assertTrue($resolver->isAuthenticated($this->getRememberMeToken()));
63+
$this->assertTrue($resolver->isAuthenticated(new FakeCustomToken()));
64+
}
65+
66+
/**
67+
* @group legacy
68+
*/
5369
public function testIsAnonymousWithClassAsConstructorButStillExtending()
5470
{
5571
$resolver = $this->getResolver();
@@ -102,7 +118,7 @@ protected function getToken()
102118

103119
protected function getAnonymousToken()
104120
{
105-
return $this->getMockBuilder(AnonymousToken::class)->setConstructorArgs(['', ''])->getMock();
121+
return new AnonymousToken('secret', 'anon.');
106122
}
107123

108124
private function getRealCustomAnonymousToken()
@@ -116,7 +132,9 @@ public function __construct()
116132

117133
protected function getRememberMeToken()
118134
{
119-
return $this->getMockBuilder(RememberMeToken::class)->setMethods(['setPersistent'])->disableOriginalConstructor()->getMock();
135+
$user = class_exists(InMemoryUser::class) ? new InMemoryUser('wouter', '', ['ROLE_USER']) : new User('wouter', '', ['ROLE_USER']);
136+
137+
return new RememberMeToken($user, 'main', 'secret');
120138
}
121139

122140
protected function getResolver()
@@ -176,6 +194,7 @@ public function getUserIdentifier(): string
176194

177195
public function isAuthenticated(): bool
178196
{
197+
return true;
179198
}
180199

181200
public function setAuthenticated(bool $isAuthenticated)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.