Skip to content

Commit e556606

Browse files
chalasrnicolas-grekas
authored andcommitted
[Security] Deprecate UserInterface & TokenInterface's eraseCredentials()
1 parent ecb9728 commit e556606

File tree

24 files changed

+213
-14
lines changed

24 files changed

+213
-14
lines changed

UPGRADE-7.3.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,23 @@ backward compatibility breaks. Minor backward compatibility breaks are prefixed
66
`[BC BREAK]`, make sure your code is compatible with these entries before upgrading.
77
Read more about this in the [Symfony documentation](https://symfony.com/doc/7.3/setup/upgrade_minor.html).
88

9-
If you're upgrading from a version below 7.1, follow the [7.2 upgrade guide](UPGRADE-7.2.md) first.
9+
If you're upgrading from a version below 7.2, follow the [7.2 upgrade guide](UPGRADE-7.2.md) first.
10+
11+
Ldap
12+
----
13+
14+
* Deprecate `LdapUser::eraseCredentials()`, use `LdapUser::setPassword(null)` instead
15+
16+
Security
17+
--------
18+
19+
* Deprecate `UserInterface::eraseCredentials()` and `TokenInterface::eraseCredentials()`,
20+
use a dedicated DTO or erase credentials on your own e.g. upon `AuthenticationTokenCreatedEvent` instead
21+
22+
SecurityBundle
23+
--------------
24+
25+
* Deprecate the `erase_credentials` config option, erase credentials on your own e.g. upon `AuthenticationTokenCreatedEvent` instead
1026

1127
Console
1228
-------
@@ -115,3 +131,4 @@ VarDumper
115131

116132
* Deprecate `ResourceCaster::castCurl()`, `ResourceCaster::castGd()` and `ResourceCaster::castOpensslX509()`
117133
* Mark all casters as `@internal`
134+
* Deprecate the `CompiledClassMetadataFactory` and `CompiledClassMetadataCacheWarmer` classes

src/Symfony/Bundle/SecurityBundle/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CHANGELOG
88
* Add encryption support to `OidcTokenHandler` (JWE)
99
* Add `expose_security_errors` config option to display `AccountStatusException`
1010
* Deprecate the `security.hide_user_not_found` config option in favor of `security.expose_security_errors`
11+
* Deprecate the `erase_credentials` config option, erase credentials on your own e.g. upon `AuthenticationTokenCreatedEvent` instead
1112

1213
7.2
1314
---

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\DependencyInjection\Definition;
1717
use Symfony\Component\DependencyInjection\Reference;
1818
use Symfony\Component\Ldap\Security\CheckLdapCredentialsListener;
19+
use Symfony\Component\Ldap\Security\EraseLdapUserCredentialsListener;
1920
use Symfony\Component\Ldap\Security\LdapAuthenticator;
2021

2122
/**
@@ -42,6 +43,12 @@ public function createAuthenticator(ContainerBuilder $container, string $firewal
4243
->addArgument(new Reference('security.ldap_locator'))
4344
;
4445

46+
if (class_exists(EraseLdapUserCredentialsListener::class && !$container->getParameter('security.authentication.manager.erase_credentials'))) {
47+
$container->setDefinition('security.listener.'.$key.'.'.$firewallName.'erase_ldap_credentials', new Definition(EraseLdapUserCredentialsListener::class))
48+
->addTag('kernel.event_subscriber', ['dispatcher' => 'security.event_dispatcher.'.$firewallName])
49+
;
50+
}
51+
4552
$ldapAuthenticatorId = 'security.authenticator.'.$key.'.'.$firewallName;
4653
$definition = $container->setDefinition($ldapAuthenticatorId, new Definition(LdapAuthenticator::class))
4754
->setArguments([

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ public function load(array $configs, ContainerBuilder $container): void
136136

137137
// set some global scalars
138138
$container->setParameter('security.access.denied_url', $config['access_denied_url']);
139+
if (true === $config['erase_credentials']) {
140+
trigger_deprecation('symfony/security-bundle', '7.3', 'Setting the "security.erase_credentials" config option to true is deprecated and won\'t have any effect in 8.0, set it to false instead and use your own erasing logic if needed.');
141+
}
139142
$container->setParameter('security.authentication.manager.erase_credentials', $config['erase_credentials']);
140143
$container->setParameter('security.authentication.session_strategy.strategy', $config['session_fixation_strategy']);
141144

src/Symfony/Bundle/SecurityBundle/Tests/Debug/TraceableFirewallListenerTest.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ public function testOnKernelRequestRecordsAuthenticatorsInfo()
103103
[new TraceableAuthenticator($notSupportingAuthenticator), new TraceableAuthenticator($supportingAuthenticator)],
104104
$tokenStorage,
105105
$dispatcher,
106-
'main'
106+
'main',
107+
null,
108+
false
107109
);
108110

109111
$listener = new TraceableAuthenticatorManagerListener(new AuthenticatorManagerListener($authenticatorManager));

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ public function isEnabled(): bool
250250
return $this->enabled;
251251
}
252252

253+
#[\Deprecated]
253254
public function eraseCredentials(): void
254255
{
255256
}

src/Symfony/Bundle/SecurityBundle/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"symfony/clock": "^6.4|^7.0",
2323
"symfony/config": "^6.4|^7.0",
2424
"symfony/dependency-injection": "^6.4.11|^7.1.4",
25+
"symfony/deprecation-contracts": "^2.5|^3",
2526
"symfony/event-dispatcher": "^6.4|^7.0",
2627
"symfony/http-kernel": "^6.4|^7.0",
2728
"symfony/http-foundation": "^6.4|^7.0",

src/Symfony/Component/Ldap/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
7.3
5+
---
6+
7+
* Deprecate `LdapUser::eraseCredentials()`, use `LdapUser::setPassword(null)` instead
8+
* Add `EraseLdapUserCredentialsListener`
9+
410
7.2
511
---
612

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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+
namespace Symfony\Component\Ldap\Security;
13+
14+
use Psr\Container\ContainerInterface;
15+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
16+
use Symfony\Component\Ldap\Exception\InvalidCredentialsException;
17+
use Symfony\Component\Ldap\Exception\InvalidSearchCredentialsException;
18+
use Symfony\Component\Ldap\LdapInterface;
19+
use Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent;
20+
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
21+
use Symfony\Component\Security\Core\Exception\LogicException;
22+
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
23+
use Symfony\Component\Security\Http\Event\AuthenticationTokenCreatedEvent;
24+
use Symfony\Component\Security\Http\Event\CheckPassportEvent;
25+
26+
/**
27+
* Erases credentials from LdapUser instances upon successful authentication.
28+
*
29+
* @author Robin Chalas <[email protected]>
30+
*/
31+
class EraseLdapUserCredentialsListener implements EventSubscriberInterface
32+
{
33+
public function onAuthenticationSuccess(AuthenticationSuccessEvent $event): void
34+
{
35+
$user = $event->getAuthenticationToken()->getUser();
36+
37+
if (!$user instanceof LdapUser) {
38+
return;
39+
}
40+
41+
$user->setPassword(null);
42+
}
43+
44+
public static function getSubscribedEvents(): array
45+
{
46+
return [AuthenticationSuccessEvent::class => ['onAuthenticationSuccess', 256]];
47+
}
48+
}

src/Symfony/Component/Ldap/Security/LdapUser.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ public function getUserIdentifier(): string
6262

6363
public function eraseCredentials(): void
6464
{
65+
trigger_deprecation('symfony/security-core', '7.3', sprintf('The "%s()" method is deprecated and will be removed in 8.0, call "setPassword(null)" instead.', __METHOD__));
66+
6567
$this->password = null;
6668
}
6769

@@ -70,7 +72,7 @@ public function getExtraFields(): array
7072
return $this->extraFields;
7173
}
7274

73-
public function setPassword(#[\SensitiveParameter] string $password): void
75+
public function setPassword(#[\SensitiveParameter] ?string $password): void
7476
{
7577
$this->password = $password;
7678
}
@@ -95,4 +97,14 @@ public function isEqualTo(UserInterface $user): bool
9597

9698
return true;
9799
}
100+
101+
public function __serialize(): array
102+
{
103+
return [$this->entry, $this->identifier, null, $this->roles, $this->extraFields];
104+
}
105+
106+
public function __unserialize(array $data): void
107+
{
108+
[$this->entry, $this->identifier, $this->password, $this->roles, $this->extraFields] = $data;
109+
}
98110
}

0 commit comments

Comments
 (0)