[Security] Rename UserInterface::getUsername() to getUserIdentifier()
This commit is contained in:
parent
c469ea6fff
commit
8afd7a3765
@ -9,6 +9,7 @@ Asset
|
|||||||
DoctrineBridge
|
DoctrineBridge
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
* Deprecate `UserLoaderInterface::loadUserByUsername()` in favor of `UserLoaderInterface::loadUserByIdentifier()
|
||||||
* Remove `UuidV*Generator` classes
|
* Remove `UuidV*Generator` classes
|
||||||
|
|
||||||
DomCrawler
|
DomCrawler
|
||||||
@ -178,6 +179,11 @@ Security
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* Deprecate `UserInterface::getUsername()` in favor of `UserInterface::getUserIdentifier()`
|
||||||
|
* Deprecate `TokenInterface::getUsername()` in favor of `TokenInterface::getUserIdentifier()`
|
||||||
|
* Deprecate `UserProviderInterface::loadUserByUsername()` in favor of `UserProviderInterface::loadUserByIdentifier()`
|
||||||
|
* Deprecate `UsernameNotFoundException` in favor of `UserNotFoundException` and `getUsername()`/`setUsername()` in favor of `getUserIdentifier()`/`setUserIdentifier()`
|
||||||
|
* Deprecate `PersistentTokenInterface::getUsername()` in favor of `PersistentTokenInterface::getUserIdentifier()`
|
||||||
* Deprecate calling `PasswordUpgraderInterface::upgradePassword()` with a `UserInterface` instance that does not implement `PasswordAuthenticatedUserInterface`
|
* Deprecate calling `PasswordUpgraderInterface::upgradePassword()` with a `UserInterface` instance that does not implement `PasswordAuthenticatedUserInterface`
|
||||||
* Deprecate calling methods `hashPassword()`, `isPasswordValid()` and `needsRehash()` on `UserPasswordHasherInterface` with a `UserInterface` instance that does not implement `PasswordAuthenticatedUserInterface`
|
* Deprecate calling methods `hashPassword()`, `isPasswordValid()` and `needsRehash()` on `UserPasswordHasherInterface` with a `UserInterface` instance that does not implement `PasswordAuthenticatedUserInterface`
|
||||||
* Deprecate all classes in the `Core\Encoder\` sub-namespace, use the `PasswordHasher` component instead
|
* Deprecate all classes in the `Core\Encoder\` sub-namespace, use the `PasswordHasher` component instead
|
||||||
|
@ -6,6 +6,11 @@ Asset
|
|||||||
|
|
||||||
* Removed `RemoteJsonManifestVersionStrategy`, use `JsonManifestVersionStrategy` instead.
|
* Removed `RemoteJsonManifestVersionStrategy`, use `JsonManifestVersionStrategy` instead.
|
||||||
|
|
||||||
|
DoctrineBridge
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* Remove `UserLoaderInterface::loadUserByUsername()` in favor of `UserLoaderInterface::loadUserByIdentifier()
|
||||||
|
|
||||||
Config
|
Config
|
||||||
------
|
------
|
||||||
|
|
||||||
@ -262,6 +267,11 @@ Security
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* Remove `UserInterface::getUsername()` in favor of `UserInterface::getUserIdentifier()`
|
||||||
|
* Remove `TokenInterface::getUsername()` in favor of `TokenInterface::getUserIdentifier()`
|
||||||
|
* Remove `UserProviderInterface::loadUserByUsername()` in favor of `UserProviderInterface::loadUserByIdentifier()`
|
||||||
|
* Remove `UsernameNotFoundException` in favor of `UserNotFoundException` and `getUsername()`/`setUsername()` in favor of `getUserIdentifier()`/`setUserIdentifier()`
|
||||||
|
* Remove `PersistentTokenInterface::getUsername()` in favor of `PersistentTokenInterface::getUserIdentifier()`
|
||||||
* Calling `PasswordUpgraderInterface::upgradePassword()` with a `UserInterface` instance that
|
* Calling `PasswordUpgraderInterface::upgradePassword()` with a `UserInterface` instance that
|
||||||
does not implement `PasswordAuthenticatedUserInterface` now throws a `\TypeError`.
|
does not implement `PasswordAuthenticatedUserInterface` now throws a `\TypeError`.
|
||||||
* Calling methods `hashPassword()`, `isPasswordValid()` and `needsRehash()` on `UserPasswordHasherInterface`
|
* Calling methods `hashPassword()`, `isPasswordValid()` and `needsRehash()` on `UserPasswordHasherInterface`
|
||||||
|
@ -4,6 +4,7 @@ CHANGELOG
|
|||||||
5.3
|
5.3
|
||||||
---
|
---
|
||||||
|
|
||||||
|
* Deprecate `UserLoaderInterface::loadUserByUsername()` in favor of `UserLoaderInterface::loadUserByIdentifier()
|
||||||
* Deprecate `DoctrineTestHelper` and `TestRepositoryFactory`
|
* Deprecate `DoctrineTestHelper` and `TestRepositoryFactory`
|
||||||
* [BC BREAK] Remove `UuidV*Generator` classes
|
* [BC BREAK] Remove `UuidV*Generator` classes
|
||||||
* Add `UuidGenerator`
|
* Add `UuidGenerator`
|
||||||
|
@ -119,7 +119,8 @@ class DoctrineTokenProvider implements TokenProviderInterface
|
|||||||
.' VALUES (:class, :username, :series, :value, :lastUsed)';
|
.' VALUES (:class, :username, :series, :value, :lastUsed)';
|
||||||
$paramValues = [
|
$paramValues = [
|
||||||
'class' => $token->getClass(),
|
'class' => $token->getClass(),
|
||||||
'username' => $token->getUsername(),
|
// @deprecated since 5.3, change to $token->getUserIdentifier() in 6.0
|
||||||
|
'username' => method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername(),
|
||||||
'series' => $token->getSeries(),
|
'series' => $token->getSeries(),
|
||||||
'value' => $token->getTokenValue(),
|
'value' => $token->getTokenValue(),
|
||||||
'lastUsed' => $token->getLastUsed(),
|
'lastUsed' => $token->getLastUsed(),
|
||||||
|
@ -16,7 +16,7 @@ use Doctrine\Persistence\Mapping\ClassMetadata;
|
|||||||
use Doctrine\Persistence\ObjectManager;
|
use Doctrine\Persistence\ObjectManager;
|
||||||
use Doctrine\Persistence\ObjectRepository;
|
use Doctrine\Persistence\ObjectRepository;
|
||||||
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||||
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
@ -50,21 +50,35 @@ class EntityUserProvider implements UserProviderInterface, PasswordUpgraderInter
|
|||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function loadUserByUsername(string $username)
|
public function loadUserByUsername(string $username)
|
||||||
|
{
|
||||||
|
trigger_deprecation('symfony/doctrine-bridge', '5.3', 'Method "%s()" is deprecated, use loadUserByIdentifier() instead.', __METHOD__);
|
||||||
|
|
||||||
|
return $this->loadUserByIdentifier($username);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadUserByIdentifier(string $identifier): UserInterface
|
||||||
{
|
{
|
||||||
$repository = $this->getRepository();
|
$repository = $this->getRepository();
|
||||||
if (null !== $this->property) {
|
if (null !== $this->property) {
|
||||||
$user = $repository->findOneBy([$this->property => $username]);
|
$user = $repository->findOneBy([$this->property => $identifier]);
|
||||||
} else {
|
} else {
|
||||||
if (!$repository instanceof UserLoaderInterface) {
|
if (!$repository instanceof UserLoaderInterface) {
|
||||||
throw new \InvalidArgumentException(sprintf('You must either make the "%s" entity Doctrine Repository ("%s") implement "Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface" or set the "property" option in the corresponding entity provider configuration.', $this->classOrAlias, get_debug_type($repository)));
|
throw new \InvalidArgumentException(sprintf('You must either make the "%s" entity Doctrine Repository ("%s") implement "Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface" or set the "property" option in the corresponding entity provider configuration.', $this->classOrAlias, get_debug_type($repository)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = $repository->loadUserByUsername($username);
|
// @deprecated since 5.3, change to $repository->loadUserByIdentifier() in 6.0
|
||||||
|
if (method_exists($repository, 'loadUserByIdentifier')) {
|
||||||
|
$user = $repository->loadUserByIdentifier($identifier);
|
||||||
|
} else {
|
||||||
|
trigger_deprecation('symfony/doctrine-bridge', '5.3', 'Not implementing method "loadUserByIdentifier()" in user loader "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($repository));
|
||||||
|
|
||||||
|
$user = $repository->loadUserByUsername($identifier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $user) {
|
if (null === $user) {
|
||||||
$e = new UsernameNotFoundException(sprintf('User "%s" not found.', $username));
|
$e = new UserNotFoundException(sprintf('User "%s" not found.', $identifier));
|
||||||
$e->setUsername($username);
|
$e->setUserIdentifier($identifier);
|
||||||
|
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
@ -96,8 +110,8 @@ class EntityUserProvider implements UserProviderInterface, PasswordUpgraderInter
|
|||||||
|
|
||||||
$refreshedUser = $repository->find($id);
|
$refreshedUser = $repository->find($id);
|
||||||
if (null === $refreshedUser) {
|
if (null === $refreshedUser) {
|
||||||
$e = new UsernameNotFoundException('User with id '.json_encode($id).' not found.');
|
$e = new UserNotFoundException('User with id '.json_encode($id).' not found.');
|
||||||
$e->setUsername(json_encode($id));
|
$e->setUserIdentifier(json_encode($id));
|
||||||
|
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
@ -22,16 +22,11 @@ use Symfony\Component\Security\Core\User\UserInterface;
|
|||||||
*
|
*
|
||||||
* @see UserInterface
|
* @see UserInterface
|
||||||
*
|
*
|
||||||
|
* @method UserInterface|null loadUserByIdentifier(string $identifier) loads the user for the given user identifier (e.g. username or email).
|
||||||
|
* This method must return null if the user is not found.
|
||||||
|
*
|
||||||
* @author Michal Trojanowski <michal@kmt-studio.pl>
|
* @author Michal Trojanowski <michal@kmt-studio.pl>
|
||||||
*/
|
*/
|
||||||
interface UserLoaderInterface
|
interface UserLoaderInterface
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Loads the user for the given username.
|
|
||||||
*
|
|
||||||
* This method must return null if the user is not found.
|
|
||||||
*
|
|
||||||
* @return UserInterface|null
|
|
||||||
*/
|
|
||||||
public function loadUserByUsername(string $username);
|
|
||||||
}
|
}
|
||||||
|
@ -37,4 +37,9 @@ class BaseUser
|
|||||||
{
|
{
|
||||||
return $this->username;
|
return $this->username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getUserIdentifier(): string
|
||||||
|
{
|
||||||
|
return $this->username;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,11 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
|||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getUserIdentifier(): string
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
public function eraseCredentials()
|
public function eraseCredentials()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ use Symfony\Bridge\Doctrine\Security\User\EntityUserProvider;
|
|||||||
use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
|
use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
|
||||||
use Symfony\Bridge\Doctrine\Tests\DoctrineTestHelper;
|
use Symfony\Bridge\Doctrine\Tests\DoctrineTestHelper;
|
||||||
use Symfony\Bridge\Doctrine\Tests\Fixtures\User;
|
use Symfony\Bridge\Doctrine\Tests\Fixtures\User;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||||
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
@ -60,7 +60,7 @@ class EntityUserProviderTest extends TestCase
|
|||||||
|
|
||||||
$provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\User', 'name');
|
$provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\User', 'name');
|
||||||
|
|
||||||
$this->assertSame($user, $provider->loadUserByUsername('user1'));
|
$this->assertSame($user, $provider->loadUserByIdentifier('user1'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadUserByUsernameWithUserLoaderRepositoryAndWithoutProperty()
|
public function testLoadUserByUsernameWithUserLoaderRepositoryAndWithoutProperty()
|
||||||
@ -70,7 +70,7 @@ class EntityUserProviderTest extends TestCase
|
|||||||
$repository = $this->createMock(UserLoaderRepository::class);
|
$repository = $this->createMock(UserLoaderRepository::class);
|
||||||
$repository
|
$repository
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('loadUserByUsername')
|
->method('loadUserByIdentifier')
|
||||||
->with('user1')
|
->with('user1')
|
||||||
->willReturn($user);
|
->willReturn($user);
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ class EntityUserProviderTest extends TestCase
|
|||||||
->willReturn($repository);
|
->willReturn($repository);
|
||||||
|
|
||||||
$provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\User');
|
$provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\User');
|
||||||
$this->assertSame($user, $provider->loadUserByUsername('user1'));
|
$this->assertSame($user, $provider->loadUserByIdentifier('user1'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadUserByUsernameWithNonUserLoaderRepositoryAndWithoutProperty()
|
public function testLoadUserByUsernameWithNonUserLoaderRepositoryAndWithoutProperty()
|
||||||
@ -98,7 +98,7 @@ class EntityUserProviderTest extends TestCase
|
|||||||
$em->flush();
|
$em->flush();
|
||||||
|
|
||||||
$provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\User');
|
$provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\User');
|
||||||
$provider->loadUserByUsername('user1');
|
$provider->loadUserByIdentifier('user1');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRefreshUserRequiresId()
|
public function testRefreshUserRequiresId()
|
||||||
@ -126,7 +126,7 @@ class EntityUserProviderTest extends TestCase
|
|||||||
$provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\User', 'name');
|
$provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\User', 'name');
|
||||||
|
|
||||||
$user2 = new User(1, 2, 'user2');
|
$user2 = new User(1, 2, 'user2');
|
||||||
$this->expectException(UsernameNotFoundException::class);
|
$this->expectException(UserNotFoundException::class);
|
||||||
$this->expectExceptionMessage('User with id {"id1":1,"id2":2} not found');
|
$this->expectExceptionMessage('User with id {"id1":1,"id2":2} not found');
|
||||||
|
|
||||||
$provider->refreshUser($user2);
|
$provider->refreshUser($user2);
|
||||||
@ -153,7 +153,7 @@ class EntityUserProviderTest extends TestCase
|
|||||||
{
|
{
|
||||||
$repository = $this->createMock(UserLoaderRepository::class);
|
$repository = $this->createMock(UserLoaderRepository::class);
|
||||||
$repository->expects($this->once())
|
$repository->expects($this->once())
|
||||||
->method('loadUserByUsername')
|
->method('loadUserByIdentifier')
|
||||||
->with('name')
|
->with('name')
|
||||||
->willReturn(
|
->willReturn(
|
||||||
$this->createMock(UserInterface::class)
|
$this->createMock(UserInterface::class)
|
||||||
@ -164,7 +164,7 @@ class EntityUserProviderTest extends TestCase
|
|||||||
'Symfony\Bridge\Doctrine\Tests\Fixtures\User'
|
'Symfony\Bridge\Doctrine\Tests\Fixtures\User'
|
||||||
);
|
);
|
||||||
|
|
||||||
$provider->loadUserByUsername('name');
|
$provider->loadUserByIdentifier('name');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadUserByUserNameShouldDeclineInvalidInterface()
|
public function testLoadUserByUserNameShouldDeclineInvalidInterface()
|
||||||
@ -177,7 +177,7 @@ class EntityUserProviderTest extends TestCase
|
|||||||
'Symfony\Bridge\Doctrine\Tests\Fixtures\User'
|
'Symfony\Bridge\Doctrine\Tests\Fixtures\User'
|
||||||
);
|
);
|
||||||
|
|
||||||
$provider->loadUserByUsername('name');
|
$provider->loadUserByIdentifier('name');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPasswordUpgrades()
|
public function testPasswordUpgrades()
|
||||||
@ -231,6 +231,7 @@ class EntityUserProviderTest extends TestCase
|
|||||||
|
|
||||||
abstract class UserLoaderRepository implements ObjectRepository, UserLoaderInterface
|
abstract class UserLoaderRepository implements ObjectRepository, UserLoaderInterface
|
||||||
{
|
{
|
||||||
|
abstract public function loadUserByIdentifier(string $identifier): ?UserInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class PasswordUpgraderRepository implements ObjectRepository, PasswordUpgraderInterface
|
abstract class PasswordUpgraderRepository implements ObjectRepository, PasswordUpgraderInterface
|
||||||
|
@ -42,10 +42,16 @@ abstract class AbstractTokenProcessor
|
|||||||
|
|
||||||
if (null !== $token = $this->getToken()) {
|
if (null !== $token = $this->getToken()) {
|
||||||
$record['extra'][$this->getKey()] = [
|
$record['extra'][$this->getKey()] = [
|
||||||
'username' => $token->getUsername(),
|
|
||||||
'authenticated' => $token->isAuthenticated(),
|
'authenticated' => $token->isAuthenticated(),
|
||||||
'roles' => $token->getRoleNames(),
|
'roles' => $token->getRoleNames(),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// @deprecated since 5.3, change to $token->getUserIdentifier() in 6.0
|
||||||
|
if (method_exists($token, 'getUserIdentifier')) {
|
||||||
|
$record['extra'][$this->getKey()]['username'] = $record['extra'][$this->getKey()]['user_identifier'] = $token->getUserIdentifier();
|
||||||
|
} else {
|
||||||
|
$record['extra'][$this->getKey()]['username'] = $token->getUsername();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $record;
|
return $record;
|
||||||
|
@ -37,11 +37,15 @@ class SwitchUserTokenProcessorTest extends TestCase
|
|||||||
|
|
||||||
$expected = [
|
$expected = [
|
||||||
'impersonator_token' => [
|
'impersonator_token' => [
|
||||||
'username' => 'original_user',
|
|
||||||
'authenticated' => true,
|
'authenticated' => true,
|
||||||
'roles' => ['ROLE_SUPER_ADMIN'],
|
'roles' => ['ROLE_SUPER_ADMIN'],
|
||||||
|
'username' => 'original_user',
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
$this->assertSame($expected, $record['extra']);
|
if (method_exists($originalToken, 'getUserIdentifier')) {
|
||||||
|
$expected['impersonator_token']['user_identifier'] = 'original_user';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $record['extra']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,12 @@ use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
|||||||
*/
|
*/
|
||||||
class TokenProcessorTest extends TestCase
|
class TokenProcessorTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testProcessor()
|
public function testLegacyProcessor()
|
||||||
{
|
{
|
||||||
|
if (method_exists(UsernamePasswordToken::class, 'getUserIdentifier')) {
|
||||||
|
$this->markTestSkipped('This test requires symfony/security-core <5.3');
|
||||||
|
}
|
||||||
|
|
||||||
$token = new UsernamePasswordToken('user', 'password', 'provider', ['ROLE_USER']);
|
$token = new UsernamePasswordToken('user', 'password', 'provider', ['ROLE_USER']);
|
||||||
$tokenStorage = $this->createMock(TokenStorageInterface::class);
|
$tokenStorage = $this->createMock(TokenStorageInterface::class);
|
||||||
$tokenStorage->method('getToken')->willReturn($token);
|
$tokenStorage->method('getToken')->willReturn($token);
|
||||||
@ -38,4 +42,24 @@ class TokenProcessorTest extends TestCase
|
|||||||
$this->assertEquals($token->isAuthenticated(), $record['extra']['token']['authenticated']);
|
$this->assertEquals($token->isAuthenticated(), $record['extra']['token']['authenticated']);
|
||||||
$this->assertEquals(['ROLE_USER'], $record['extra']['token']['roles']);
|
$this->assertEquals(['ROLE_USER'], $record['extra']['token']['roles']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testProcessor()
|
||||||
|
{
|
||||||
|
if (!method_exists(UsernamePasswordToken::class, 'getUserIdentifier')) {
|
||||||
|
$this->markTestSkipped('This test requires symfony/security-core 5.3+');
|
||||||
|
}
|
||||||
|
|
||||||
|
$token = new UsernamePasswordToken('user', 'password', 'provider', ['ROLE_USER']);
|
||||||
|
$tokenStorage = $this->createMock(TokenStorageInterface::class);
|
||||||
|
$tokenStorage->method('getToken')->willReturn($token);
|
||||||
|
|
||||||
|
$processor = new TokenProcessor($tokenStorage);
|
||||||
|
$record = ['extra' => []];
|
||||||
|
$record = $processor($record);
|
||||||
|
|
||||||
|
$this->assertArrayHasKey('token', $record['extra']);
|
||||||
|
$this->assertEquals($token->getUserIdentifier(), $record['extra']['token']['user_identifier']);
|
||||||
|
$this->assertEquals($token->isAuthenticated(), $record['extra']['token']['authenticated']);
|
||||||
|
$this->assertEquals(['ROLE_USER'], $record['extra']['token']['roles']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,6 @@ class SecurityController implements ContainerAwareInterface
|
|||||||
|
|
||||||
public function profileAction()
|
public function profileAction()
|
||||||
{
|
{
|
||||||
return new Response('Welcome '.$this->container->get('security.token_storage')->getToken()->getUsername().'!');
|
return new Response('Welcome '.$this->container->get('security.token_storage')->getToken()->getUserIdentifier().'!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,9 @@ class SecurityDataCollector extends DataCollector implements LateDataCollectorIn
|
|||||||
|
|
||||||
$impersonatorUser = null;
|
$impersonatorUser = null;
|
||||||
if ($token instanceof SwitchUserToken) {
|
if ($token instanceof SwitchUserToken) {
|
||||||
$impersonatorUser = $token->getOriginalToken()->getUsername();
|
$originalToken = $token->getOriginalToken();
|
||||||
|
// @deprecated since 5.3, change to $originalToken->getUserIdentifier() in 6.0
|
||||||
|
$impersonatorUser = method_exists($originalToken, 'getUserIdentifier') ? $originalToken->getUserIdentifier() : $originalToken->getUsername();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $this->roleHierarchy) {
|
if (null !== $this->roleHierarchy) {
|
||||||
@ -126,7 +128,8 @@ class SecurityDataCollector extends DataCollector implements LateDataCollectorIn
|
|||||||
'token' => $token,
|
'token' => $token,
|
||||||
'token_class' => $this->hasVarDumper ? new ClassStub(\get_class($token)) : \get_class($token),
|
'token_class' => $this->hasVarDumper ? new ClassStub(\get_class($token)) : \get_class($token),
|
||||||
'logout_url' => $logoutUrl,
|
'logout_url' => $logoutUrl,
|
||||||
'user' => $token->getUsername(),
|
// @deprecated since 5.3, change to $token->getUserIdentifier() in 6.0
|
||||||
|
'user' => method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername(),
|
||||||
'roles' => $assignedRoles,
|
'roles' => $assignedRoles,
|
||||||
'inherited_roles' => array_unique($inheritedRoles),
|
'inherited_roles' => array_unique($inheritedRoles),
|
||||||
'supports_role_hierarchy' => null !== $this->roleHierarchy,
|
'supports_role_hierarchy' => null !== $this->roleHierarchy,
|
||||||
|
@ -48,8 +48,30 @@ class InMemoryFactory implements UserProviderFactoryInterface
|
|||||||
->fixXmlConfig('user')
|
->fixXmlConfig('user')
|
||||||
->children()
|
->children()
|
||||||
->arrayNode('users')
|
->arrayNode('users')
|
||||||
->useAttributeAsKey('name')
|
->useAttributeAsKey('identifier')
|
||||||
->normalizeKeys(false)
|
->normalizeKeys(false)
|
||||||
|
->beforeNormalization()
|
||||||
|
->always()
|
||||||
|
->then(function ($v) {
|
||||||
|
$deprecation = false;
|
||||||
|
foreach ($v as $i => $child) {
|
||||||
|
if (!isset($child['name'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$deprecation = true;
|
||||||
|
|
||||||
|
$v[$i]['identifier'] = $child['name'];
|
||||||
|
unset($v[$i]['name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($deprecation) {
|
||||||
|
trigger_deprecation('symfony/security-bundle', '5.3', 'The "in_memory.user.name" option is deprecated, use "identifier" instead.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $v;
|
||||||
|
})
|
||||||
|
->end()
|
||||||
->prototype('array')
|
->prototype('array')
|
||||||
->children()
|
->children()
|
||||||
->scalarNode('password')->defaultNull()->end()
|
->scalarNode('password')->defaultNull()->end()
|
||||||
|
@ -136,7 +136,8 @@
|
|||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
|
|
||||||
<xsd:complexType name="user">
|
<xsd:complexType name="user">
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
<xsd:attribute name="identifier" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
<xsd:attribute name="password" type="xsd:string" />
|
<xsd:attribute name="password" type="xsd:string" />
|
||||||
<xsd:attribute name="roles" type="xsd:string" />
|
<xsd:attribute name="roles" type="xsd:string" />
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
|
@ -297,7 +297,7 @@ abstract class CompleteConfigurationTest extends TestCase
|
|||||||
} elseif (3 === $i) {
|
} elseif (3 === $i) {
|
||||||
$this->assertEquals('IS_AUTHENTICATED_ANONYMOUSLY', $attributes[0]);
|
$this->assertEquals('IS_AUTHENTICATED_ANONYMOUSLY', $attributes[0]);
|
||||||
$expression = $container->getDefinition((string) $attributes[1])->getArgument(0);
|
$expression = $container->getDefinition((string) $attributes[1])->getArgument(0);
|
||||||
$this->assertEquals("token.getUsername() matches '/^admin/'", $expression);
|
$this->assertEquals("token.getUserIdentifier() matches '/^admin/'", $expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ $container->loadFromExtension('security', [
|
|||||||
'access_control' => [
|
'access_control' => [
|
||||||
['path' => '/blog/524', 'role' => 'ROLE_USER', 'requires_channel' => 'https', 'methods' => ['get', 'POST'], 'port' => 8000],
|
['path' => '/blog/524', 'role' => 'ROLE_USER', 'requires_channel' => 'https', 'methods' => ['get', 'POST'], 'port' => 8000],
|
||||||
['path' => '/blog/.*', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY'],
|
['path' => '/blog/.*', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY'],
|
||||||
['path' => '/blog/524', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY', 'allow_if' => "token.getUsername() matches '/^admin/'"],
|
['path' => '/blog/524', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY', 'allow_if' => "token.getUserIdentifier() matches '/^admin/'"],
|
||||||
],
|
],
|
||||||
|
|
||||||
'role_hierarchy' => [
|
'role_hierarchy' => [
|
||||||
|
@ -97,7 +97,7 @@ $container->loadFromExtension('security', [
|
|||||||
'access_control' => [
|
'access_control' => [
|
||||||
['path' => '/blog/524', 'role' => 'ROLE_USER', 'requires_channel' => 'https', 'methods' => ['get', 'POST'], 'port' => 8000],
|
['path' => '/blog/524', 'role' => 'ROLE_USER', 'requires_channel' => 'https', 'methods' => ['get', 'POST'], 'port' => 8000],
|
||||||
['path' => '/blog/.*', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY'],
|
['path' => '/blog/.*', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY'],
|
||||||
['path' => '/blog/524', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY', 'allow_if' => "token.getUsername() matches '/^admin/'"],
|
['path' => '/blog/524', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY', 'allow_if' => "token.getUserIdentifier() matches '/^admin/'"],
|
||||||
],
|
],
|
||||||
|
|
||||||
'role_hierarchy' => [
|
'role_hierarchy' => [
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
<provider name="default">
|
<provider name="default">
|
||||||
<memory>
|
<memory>
|
||||||
<user name="foo" password="foo" roles="ROLE_USER" />
|
<user identifier="foo" password="foo" roles="ROLE_USER" />
|
||||||
</memory>
|
</memory>
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<config>
|
<config>
|
||||||
<provider name="default">
|
<provider name="default">
|
||||||
<memory>
|
<memory>
|
||||||
<user name="foo" password="foo" roles="ROLE_USER" />
|
<user identifier="foo" password="foo" roles="ROLE_USER" />
|
||||||
</memory>
|
</memory>
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
<provider name="default">
|
<provider name="default">
|
||||||
<memory>
|
<memory>
|
||||||
<user name="foo" password="foo" roles="ROLE_USER" />
|
<user identifier="foo" password="foo" roles="ROLE_USER" />
|
||||||
</memory>
|
</memory>
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
<provider name="default">
|
<provider name="default">
|
||||||
<memory>
|
<memory>
|
||||||
<user name="foo" password="foo" roles="ROLE_USER" />
|
<user identifier="foo" password="foo" roles="ROLE_USER" />
|
||||||
</memory>
|
</memory>
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
|
@ -25,20 +25,20 @@
|
|||||||
|
|
||||||
<provider name="default">
|
<provider name="default">
|
||||||
<memory>
|
<memory>
|
||||||
<user name="foo" password="foo" roles="ROLE_USER" />
|
<user identifier="foo" password="foo" roles="ROLE_USER" />
|
||||||
</memory>
|
</memory>
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
<provider name="digest">
|
<provider name="digest">
|
||||||
<memory>
|
<memory>
|
||||||
<user name="foo" password="foo" roles="ROLE_USER, ROLE_ADMIN" />
|
<user identifier="foo" password="foo" roles="ROLE_USER, ROLE_ADMIN" />
|
||||||
</memory>
|
</memory>
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
<provider name="basic">
|
<provider name="basic">
|
||||||
<memory>
|
<memory>
|
||||||
<user name="foo" password="0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" roles="ROLE_SUPER_ADMIN" />
|
<user identifier="foo" password="0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" roles="ROLE_SUPER_ADMIN" />
|
||||||
<user name="bar" password="0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" roles="ROLE_USER, ROLE_ADMIN" />
|
<user identifier="bar" password="0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" roles="ROLE_USER, ROLE_ADMIN" />
|
||||||
</memory>
|
</memory>
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
@ -78,6 +78,6 @@
|
|||||||
|
|
||||||
<rule path="/blog/524" role="ROLE_USER" requires-channel="https" methods="get,POST" port="8000" />
|
<rule path="/blog/524" role="ROLE_USER" requires-channel="https" methods="get,POST" port="8000" />
|
||||||
<rule role='IS_AUTHENTICATED_ANONYMOUSLY' path="/blog/.*" />
|
<rule role='IS_AUTHENTICATED_ANONYMOUSLY' path="/blog/.*" />
|
||||||
<rule role='IS_AUTHENTICATED_ANONYMOUSLY' allow-if="token.getUsername() matches '/^admin/'" path="/blog/524" />
|
<rule role='IS_AUTHENTICATED_ANONYMOUSLY' allow-if="token.getUserIdentifier() matches '/^admin/'" path="/blog/524" />
|
||||||
</config>
|
</config>
|
||||||
</srv:container>
|
</srv:container>
|
||||||
|
@ -25,20 +25,20 @@
|
|||||||
|
|
||||||
<provider name="default">
|
<provider name="default">
|
||||||
<memory>
|
<memory>
|
||||||
<user name="foo" password="foo" roles="ROLE_USER" />
|
<user identifier="foo" password="foo" roles="ROLE_USER" />
|
||||||
</memory>
|
</memory>
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
<provider name="digest">
|
<provider name="digest">
|
||||||
<memory>
|
<memory>
|
||||||
<user name="foo" password="foo" roles="ROLE_USER, ROLE_ADMIN" />
|
<user identifier="foo" password="foo" roles="ROLE_USER, ROLE_ADMIN" />
|
||||||
</memory>
|
</memory>
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
<provider name="basic">
|
<provider name="basic">
|
||||||
<memory>
|
<memory>
|
||||||
<user name="foo" password="0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" roles="ROLE_SUPER_ADMIN" />
|
<user identifier="foo" password="0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" roles="ROLE_SUPER_ADMIN" />
|
||||||
<user name="bar" password="0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" roles="ROLE_USER, ROLE_ADMIN" />
|
<user identifier="bar" password="0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" roles="ROLE_USER, ROLE_ADMIN" />
|
||||||
</memory>
|
</memory>
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
@ -78,6 +78,6 @@
|
|||||||
|
|
||||||
<rule path="/blog/524" role="ROLE_USER" requires-channel="https" methods="get,POST" port="8000" />
|
<rule path="/blog/524" role="ROLE_USER" requires-channel="https" methods="get,POST" port="8000" />
|
||||||
<rule role='IS_AUTHENTICATED_ANONYMOUSLY' path="/blog/.*" />
|
<rule role='IS_AUTHENTICATED_ANONYMOUSLY' path="/blog/.*" />
|
||||||
<rule role='IS_AUTHENTICATED_ANONYMOUSLY' allow-if="token.getUsername() matches '/^admin/'" path="/blog/524" />
|
<rule role='IS_AUTHENTICATED_ANONYMOUSLY' allow-if="token.getUserIdentifier() matches '/^admin/'" path="/blog/524" />
|
||||||
</config>
|
</config>
|
||||||
</srv:container>
|
</srv:container>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<config>
|
<config>
|
||||||
<provider name="default">
|
<provider name="default">
|
||||||
<memory>
|
<memory>
|
||||||
<user name="foo" password="foo" roles="ROLE_USER" />
|
<user identifier="foo" password="foo" roles="ROLE_USER" />
|
||||||
</memory>
|
</memory>
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
|
@ -84,4 +84,4 @@ security:
|
|||||||
-
|
-
|
||||||
path: /blog/.*
|
path: /blog/.*
|
||||||
role: IS_AUTHENTICATED_ANONYMOUSLY
|
role: IS_AUTHENTICATED_ANONYMOUSLY
|
||||||
- { path: /blog/524, role: IS_AUTHENTICATED_ANONYMOUSLY, allow_if: "token.getUsername() matches '/^admin/'" }
|
- { path: /blog/524, role: IS_AUTHENTICATED_ANONYMOUSLY, allow_if: "token.getUserIdentifier() matches '/^admin/'" }
|
||||||
|
@ -84,4 +84,4 @@ security:
|
|||||||
-
|
-
|
||||||
path: /blog/.*
|
path: /blog/.*
|
||||||
role: IS_AUTHENTICATED_ANONYMOUSLY
|
role: IS_AUTHENTICATED_ANONYMOUSLY
|
||||||
- { path: /blog/524, role: IS_AUTHENTICATED_ANONYMOUSLY, allow_if: "token.getUsername() matches '/^admin/'" }
|
- { path: /blog/524, role: IS_AUTHENTICATED_ANONYMOUSLY, allow_if: "token.getUserIdentifier() matches '/^admin/'" }
|
||||||
|
@ -19,6 +19,6 @@ class ProfileController extends AbstractController
|
|||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('ROLE_USER');
|
$this->denyAccessUnlessGranted('ROLE_USER');
|
||||||
|
|
||||||
return $this->json(['email' => $this->getUser()->getUsername()]);
|
return $this->json(['email' => $this->getUser()->getUserIdentifier()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{% extends "base.html.twig" %}
|
{% extends "base.html.twig" %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
Hello {{ app.user.username }}!<br /><br />
|
Hello {{ app.user.userIdentifier }}!<br /><br />
|
||||||
You're browsing to path "{{ app.request.pathInfo }}".<br /><br />
|
You're browsing to path "{{ app.request.pathInfo }}".<br /><br />
|
||||||
<a href="{{ logout_path('default') }}">Log out</a>.
|
<a href="{{ logout_path('default') }}">Log out</a>.
|
||||||
<a href="{{ logout_url('default') }}">Log out</a>.
|
<a href="{{ logout_url('default') }}">Log out</a>.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{% extends "base.html.twig" %}
|
{% extends "base.html.twig" %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
Hello {{ user.username }}!<br /><br />
|
Hello {{ user.userIdentifier }}!<br /><br />
|
||||||
You're browsing to path "{{ app.request.pathInfo }}".
|
You're browsing to path "{{ app.request.pathInfo }}".
|
||||||
|
|
||||||
<a href="{{ logout_path('default') }}">Log out</a>.
|
<a href="{{ logout_path('default') }}">Log out</a>.
|
||||||
|
@ -33,6 +33,6 @@ class AuthenticationController
|
|||||||
return new Response('Not logged in.');
|
return new Response('Not logged in.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Response('Username: '.$user->getUsername());
|
return new Response('Username: '.$user->getUserIdentifier());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,6 @@ class TestController
|
|||||||
{
|
{
|
||||||
public function loginCheckAction(UserInterface $user)
|
public function loginCheckAction(UserInterface $user)
|
||||||
{
|
{
|
||||||
return new JsonResponse(['message' => sprintf('Welcome @%s!', $user->getUsername())]);
|
return new JsonResponse(['message' => sprintf('Welcome @%s!', $user->getUserIdentifier())]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,6 @@ class JsonAuthenticationSuccessHandler implements AuthenticationSuccessHandlerIn
|
|||||||
{
|
{
|
||||||
public function onAuthenticationSuccess(Request $request, TokenInterface $token): Response
|
public function onAuthenticationSuccess(Request $request, TokenInterface $token): Response
|
||||||
{
|
{
|
||||||
return new JsonResponse(['message' => sprintf('Good game @%s!', $token->getUsername())]);
|
return new JsonResponse(['message' => sprintf('Good game @%s!', $token->getUserIdentifier())]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,6 @@ class TestCustomLoginLinkSuccessHandler implements AuthenticationSuccessHandlerI
|
|||||||
{
|
{
|
||||||
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
|
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
|
||||||
{
|
{
|
||||||
return new JsonResponse(['message' => sprintf('Welcome %s!', $token->getUsername())]);
|
return new JsonResponse(['message' => sprintf('Welcome %s!', $token->getUserIdentifier())]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ namespace Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\SecuredPageBundl
|
|||||||
|
|
||||||
use Symfony\Bundle\SecurityBundle\Tests\Functional\UserWithoutEquatable;
|
use Symfony\Bundle\SecurityBundle\Tests\Functional\UserWithoutEquatable;
|
||||||
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
use Symfony\Component\Security\Core\User\InMemoryUser;
|
use Symfony\Component\Security\Core\User\InMemoryUser;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||||
@ -16,7 +16,7 @@ class ArrayUserProvider implements UserProviderInterface
|
|||||||
|
|
||||||
public function addUser(UserInterface $user)
|
public function addUser(UserInterface $user)
|
||||||
{
|
{
|
||||||
$this->users[$user->getUsername()] = $user;
|
$this->users[$user->getUserIdentifier()] = $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setUser($username, UserInterface $user)
|
public function setUser($username, UserInterface $user)
|
||||||
@ -31,11 +31,16 @@ class ArrayUserProvider implements UserProviderInterface
|
|||||||
|
|
||||||
public function loadUserByUsername($username)
|
public function loadUserByUsername($username)
|
||||||
{
|
{
|
||||||
$user = $this->getUser($username);
|
return $this->loadUserByIdentifier($username);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadUserByIdentifier(string $identifier): UserInterface
|
||||||
|
{
|
||||||
|
$user = $this->getUser($identifier);
|
||||||
|
|
||||||
if (null === $user) {
|
if (null === $user) {
|
||||||
$e = new UsernameNotFoundException(sprintf('User "%s" not found.', $username));
|
$e = new UserNotFoundException(sprintf('User "%s" not found.', $identifier));
|
||||||
$e->setUsername($username);
|
$e->setUsername($identifier);
|
||||||
|
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
@ -49,10 +54,10 @@ class ArrayUserProvider implements UserProviderInterface
|
|||||||
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_debug_type($user)));
|
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_debug_type($user)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$storedUser = $this->getUser($user->getUsername());
|
$storedUser = $this->getUser($user->getUserIdentifier());
|
||||||
$class = \get_class($storedUser);
|
$class = \get_class($storedUser);
|
||||||
|
|
||||||
return new $class($storedUser->getUsername(), $storedUser->getPassword(), $storedUser->getRoles(), $storedUser->isEnabled());
|
return new $class($storedUser->getUserIdentifier(), $storedUser->getPassword(), $storedUser->getRoles(), $storedUser->isEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function supportsClass($class)
|
public function supportsClass($class)
|
||||||
|
@ -51,7 +51,7 @@ class RememberMeFooController
|
|||||||
{
|
{
|
||||||
public function __invoke(UserInterface $user)
|
public function __invoke(UserInterface $user)
|
||||||
{
|
{
|
||||||
return new Response($user->getUsername());
|
return new Response($user->getUserIdentifier());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +66,12 @@ class RememberMeUserProvider implements UserProviderInterface
|
|||||||
|
|
||||||
public function loadUserByUsername($username)
|
public function loadUserByUsername($username)
|
||||||
{
|
{
|
||||||
return $this->inner->loadUserByUsername($username);
|
return $this->loadUserByIdentifier($username);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadUserByIdentifier(string $identifier): UserInterface
|
||||||
|
{
|
||||||
|
return $this->inner->loadUserByIdentifier($identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function refreshUser(UserInterface $user)
|
public function refreshUser(UserInterface $user)
|
||||||
|
@ -28,7 +28,7 @@ class LoginLinkAuthenticationTest extends AbstractWebTestCase
|
|||||||
$this->markTestSkipped('Login link auth requires symfony/security-http:^5.2');
|
$this->markTestSkipped('Login link auth requires symfony/security-http:^5.2');
|
||||||
}
|
}
|
||||||
|
|
||||||
$client = $this->createClient(['test_case' => 'LoginLink', 'root_config' => 'config.yml']);
|
$client = $this->createClient(['test_case' => 'LoginLink', 'root_config' => 'config.yml', 'debug' => true]);
|
||||||
|
|
||||||
// we need an active request that is under the firewall to use the linker
|
// we need an active request that is under the firewall to use the linker
|
||||||
$request = Request::create('/get-login-link');
|
$request = Request::create('/get-login-link');
|
||||||
|
@ -106,7 +106,7 @@ final class UserWithoutEquatable implements UserInterface, PasswordAuthenticated
|
|||||||
|
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return $this->getUsername();
|
return $this->getUserIdentifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -141,6 +141,11 @@ final class UserWithoutEquatable implements UserInterface, PasswordAuthenticated
|
|||||||
return $this->username;
|
return $this->username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getUserIdentifier()
|
||||||
|
{
|
||||||
|
return $this->username;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -83,7 +83,8 @@ class CheckLdapCredentialsListener implements EventSubscriberInterface
|
|||||||
} else {
|
} else {
|
||||||
throw new LogicException('Using the "query_string" config without using a "search_dn" and a "search_password" is not supported.');
|
throw new LogicException('Using the "query_string" config without using a "search_dn" and a "search_password" is not supported.');
|
||||||
}
|
}
|
||||||
$username = $ldap->escape($user->getUsername(), '', LdapInterface::ESCAPE_FILTER);
|
// @deprecated since 5.3, change to $user->getUserIdentifier() in 6.0
|
||||||
|
$username = $ldap->escape(method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername(), '', LdapInterface::ESCAPE_FILTER);
|
||||||
$query = str_replace('{username}', $username, $ldapBadge->getQueryString());
|
$query = str_replace('{username}', $username, $ldapBadge->getQueryString());
|
||||||
$result = $ldap->query($ldapBadge->getDnString(), $query)->execute();
|
$result = $ldap->query($ldapBadge->getDnString(), $query)->execute();
|
||||||
if (1 !== $result->count()) {
|
if (1 !== $result->count()) {
|
||||||
@ -92,7 +93,8 @@ class CheckLdapCredentialsListener implements EventSubscriberInterface
|
|||||||
|
|
||||||
$dn = $result[0]->getDn();
|
$dn = $result[0]->getDn();
|
||||||
} else {
|
} else {
|
||||||
$username = $ldap->escape($user->getUsername(), '', LdapInterface::ESCAPE_DN);
|
// @deprecated since 5.3, change to $user->getUserIdentifier() in 6.0
|
||||||
|
$username = $ldap->escape(method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername(), '', LdapInterface::ESCAPE_DN);
|
||||||
$dn = str_replace('{username}', $username, $ldapBadge->getDnString());
|
$dn = str_replace('{username}', $username, $ldapBadge->getDnString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,13 @@ class LdapUser implements UserInterface, PasswordAuthenticatedUserInterface, Equ
|
|||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function getUsername(): string
|
public function getUsername(): string
|
||||||
|
{
|
||||||
|
trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated and will be removed in 6.0, use getUserIdentifier() instead.', __METHOD__);
|
||||||
|
|
||||||
|
return $this->username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserIdentifier(): string
|
||||||
{
|
{
|
||||||
return $this->username;
|
return $this->username;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ use Symfony\Component\Ldap\Exception\ExceptionInterface;
|
|||||||
use Symfony\Component\Ldap\LdapInterface;
|
use Symfony\Component\Ldap\LdapInterface;
|
||||||
use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
|
use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
|
||||||
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||||
@ -48,7 +48,7 @@ class LdapUserProvider implements UserProviderInterface, PasswordUpgraderInterfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (null === $filter) {
|
if (null === $filter) {
|
||||||
$filter = '({uid_key}={username})';
|
$filter = '({uid_key}={user_identifier})';
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->ldap = $ldap;
|
$this->ldap = $ldap;
|
||||||
@ -66,15 +66,22 @@ class LdapUserProvider implements UserProviderInterface, PasswordUpgraderInterfa
|
|||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function loadUserByUsername(string $username)
|
public function loadUserByUsername(string $username)
|
||||||
|
{
|
||||||
|
trigger_deprecation('symfony/ldap', '5.3', 'Method "%s()" is deprecated, use loadUserByIdentifier() instead.', __METHOD__);
|
||||||
|
|
||||||
|
return $this->loadUserByIdentifier($username);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadUserByIdentifier(string $identifier): UserInterface
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->ldap->bind($this->searchDn, $this->searchPassword);
|
$this->ldap->bind($this->searchDn, $this->searchPassword);
|
||||||
$username = $this->ldap->escape($username, '', LdapInterface::ESCAPE_FILTER);
|
$identifier = $this->ldap->escape($identifier, '', LdapInterface::ESCAPE_FILTER);
|
||||||
$query = str_replace('{username}', $username, $this->defaultSearch);
|
$query = str_replace(['{username}', '{user_identifier}'], $identifier, $this->defaultSearch);
|
||||||
$search = $this->ldap->query($this->baseDn, $query);
|
$search = $this->ldap->query($this->baseDn, $query);
|
||||||
} catch (ConnectionException $e) {
|
} catch (ConnectionException $e) {
|
||||||
$e = new UsernameNotFoundException(sprintf('User "%s" not found.', $username), 0, $e);
|
$e = new UserNotFoundException(sprintf('User "%s" not found.', $identifier), 0, $e);
|
||||||
$e->setUsername($username);
|
$e->setUserIdentifier($identifier);
|
||||||
|
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
@ -83,15 +90,15 @@ class LdapUserProvider implements UserProviderInterface, PasswordUpgraderInterfa
|
|||||||
$count = \count($entries);
|
$count = \count($entries);
|
||||||
|
|
||||||
if (!$count) {
|
if (!$count) {
|
||||||
$e = new UsernameNotFoundException(sprintf('User "%s" not found.', $username));
|
$e = new UserNotFoundException(sprintf('User "%s" not found.', $identifier));
|
||||||
$e->setUsername($username);
|
$e->setUserIdentifier($identifier);
|
||||||
|
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($count > 1) {
|
if ($count > 1) {
|
||||||
$e = new UsernameNotFoundException('More than one user found.');
|
$e = new UserNotFoundException('More than one user found.');
|
||||||
$e->setUsername($username);
|
$e->setUserIdentifier($identifier);
|
||||||
|
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
@ -100,12 +107,12 @@ class LdapUserProvider implements UserProviderInterface, PasswordUpgraderInterfa
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (null !== $this->uidKey) {
|
if (null !== $this->uidKey) {
|
||||||
$username = $this->getAttributeValue($entry, $this->uidKey);
|
$identifier = $this->getAttributeValue($entry, $this->uidKey);
|
||||||
}
|
}
|
||||||
} catch (InvalidArgumentException $e) {
|
} catch (InvalidArgumentException $e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->loadUser($username, $entry);
|
return $this->loadUser($identifier, $entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -117,7 +124,7 @@ class LdapUserProvider implements UserProviderInterface, PasswordUpgraderInterfa
|
|||||||
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_debug_type($user)));
|
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_debug_type($user)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LdapUser($user->getEntry(), $user->getUsername(), $user->getPassword(), $user->getRoles(), $user->getExtraFields());
|
return new LdapUser($user->getEntry(), $user->getUserIdentifier(), $user->getPassword(), $user->getRoles(), $user->getExtraFields());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -157,7 +164,7 @@ class LdapUserProvider implements UserProviderInterface, PasswordUpgraderInterfa
|
|||||||
*
|
*
|
||||||
* @return UserInterface
|
* @return UserInterface
|
||||||
*/
|
*/
|
||||||
protected function loadUser(string $username, Entry $entry)
|
protected function loadUser(string $identifier, Entry $entry)
|
||||||
{
|
{
|
||||||
$password = null;
|
$password = null;
|
||||||
$extraFields = [];
|
$extraFields = [];
|
||||||
@ -170,7 +177,7 @@ class LdapUserProvider implements UserProviderInterface, PasswordUpgraderInterfa
|
|||||||
$extraFields[$field] = $this->getAttributeValue($entry, $field);
|
$extraFields[$field] = $this->getAttributeValue($entry, $field);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LdapUser($entry, $username, $password, $this->defaultRoles, $extraFields);
|
return new LdapUser($entry, $identifier, $password, $this->defaultRoles, $extraFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getAttributeValue(Entry $entry, string $attribute)
|
private function getAttributeValue(Entry $entry, string $attribute)
|
||||||
|
@ -20,7 +20,7 @@ use Symfony\Component\Ldap\LdapInterface;
|
|||||||
use Symfony\Component\Ldap\Security\LdapUser;
|
use Symfony\Component\Ldap\Security\LdapUser;
|
||||||
use Symfony\Component\Ldap\Security\LdapUserProvider;
|
use Symfony\Component\Ldap\Security\LdapUserProvider;
|
||||||
use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
|
use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @requires extension ldap
|
* @requires extension ldap
|
||||||
@ -29,7 +29,7 @@ class LdapUserProviderTest extends TestCase
|
|||||||
{
|
{
|
||||||
public function testLoadUserByUsernameFailsIfCantConnectToLdap()
|
public function testLoadUserByUsernameFailsIfCantConnectToLdap()
|
||||||
{
|
{
|
||||||
$this->expectException(UsernameNotFoundException::class);
|
$this->expectException(UserNotFoundException::class);
|
||||||
|
|
||||||
$ldap = $this->createMock(LdapInterface::class);
|
$ldap = $this->createMock(LdapInterface::class);
|
||||||
$ldap
|
$ldap
|
||||||
@ -39,12 +39,12 @@ class LdapUserProviderTest extends TestCase
|
|||||||
;
|
;
|
||||||
|
|
||||||
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com');
|
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com');
|
||||||
$provider->loadUserByUsername('foo');
|
$provider->loadUserByIdentifier('foo');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadUserByUsernameFailsIfNoLdapEntries()
|
public function testLoadUserByUsernameFailsIfNoLdapEntries()
|
||||||
{
|
{
|
||||||
$this->expectException(UsernameNotFoundException::class);
|
$this->expectException(UserNotFoundException::class);
|
||||||
|
|
||||||
$result = $this->createMock(CollectionInterface::class);
|
$result = $this->createMock(CollectionInterface::class);
|
||||||
$query = $this->createMock(QueryInterface::class);
|
$query = $this->createMock(QueryInterface::class);
|
||||||
@ -71,12 +71,12 @@ class LdapUserProviderTest extends TestCase
|
|||||||
;
|
;
|
||||||
|
|
||||||
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com');
|
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com');
|
||||||
$provider->loadUserByUsername('foo');
|
$provider->loadUserByIdentifier('foo');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadUserByUsernameFailsIfMoreThanOneLdapEntry()
|
public function testLoadUserByUsernameFailsIfMoreThanOneLdapEntry()
|
||||||
{
|
{
|
||||||
$this->expectException(UsernameNotFoundException::class);
|
$this->expectException(UserNotFoundException::class);
|
||||||
|
|
||||||
$result = $this->createMock(CollectionInterface::class);
|
$result = $this->createMock(CollectionInterface::class);
|
||||||
$query = $this->createMock(QueryInterface::class);
|
$query = $this->createMock(QueryInterface::class);
|
||||||
@ -103,7 +103,7 @@ class LdapUserProviderTest extends TestCase
|
|||||||
;
|
;
|
||||||
|
|
||||||
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com');
|
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com');
|
||||||
$provider->loadUserByUsername('foo');
|
$provider->loadUserByIdentifier('foo');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadUserByUsernameFailsIfMoreThanOneLdapPasswordsInEntry()
|
public function testLoadUserByUsernameFailsIfMoreThanOneLdapPasswordsInEntry()
|
||||||
@ -144,7 +144,7 @@ class LdapUserProviderTest extends TestCase
|
|||||||
;
|
;
|
||||||
|
|
||||||
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com', null, null, [], 'sAMAccountName', '({uid_key}={username})', 'userpassword');
|
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com', null, null, [], 'sAMAccountName', '({uid_key}={username})', 'userpassword');
|
||||||
$this->assertInstanceOf(LdapUser::class, $provider->loadUserByUsername('foo'));
|
$this->assertInstanceOf(LdapUser::class, $provider->loadUserByIdentifier('foo'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadUserByUsernameShouldNotFailIfEntryHasNoUidKeyAttribute()
|
public function testLoadUserByUsernameShouldNotFailIfEntryHasNoUidKeyAttribute()
|
||||||
@ -180,7 +180,7 @@ class LdapUserProviderTest extends TestCase
|
|||||||
;
|
;
|
||||||
|
|
||||||
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com', null, null, [], 'sAMAccountName', '({uid_key}={username})');
|
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com', null, null, [], 'sAMAccountName', '({uid_key}={username})');
|
||||||
$this->assertInstanceOf(LdapUser::class, $provider->loadUserByUsername('foo'));
|
$this->assertInstanceOf(LdapUser::class, $provider->loadUserByIdentifier('foo'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadUserByUsernameFailsIfEntryHasNoPasswordAttribute()
|
public function testLoadUserByUsernameFailsIfEntryHasNoPasswordAttribute()
|
||||||
@ -218,7 +218,7 @@ class LdapUserProviderTest extends TestCase
|
|||||||
;
|
;
|
||||||
|
|
||||||
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com', null, null, [], 'sAMAccountName', '({uid_key}={username})', 'userpassword');
|
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com', null, null, [], 'sAMAccountName', '({uid_key}={username})', 'userpassword');
|
||||||
$this->assertInstanceOf(LdapUser::class, $provider->loadUserByUsername('foo'));
|
$this->assertInstanceOf(LdapUser::class, $provider->loadUserByIdentifier('foo'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadUserByUsernameIsSuccessfulWithoutPasswordAttribute()
|
public function testLoadUserByUsernameIsSuccessfulWithoutPasswordAttribute()
|
||||||
@ -254,7 +254,7 @@ class LdapUserProviderTest extends TestCase
|
|||||||
;
|
;
|
||||||
|
|
||||||
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com');
|
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com');
|
||||||
$this->assertInstanceOf(LdapUser::class, $provider->loadUserByUsername('foo'));
|
$this->assertInstanceOf(LdapUser::class, $provider->loadUserByIdentifier('foo'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadUserByUsernameIsSuccessfulWithoutPasswordAttributeAndWrongCase()
|
public function testLoadUserByUsernameIsSuccessfulWithoutPasswordAttributeAndWrongCase()
|
||||||
@ -290,7 +290,7 @@ class LdapUserProviderTest extends TestCase
|
|||||||
;
|
;
|
||||||
|
|
||||||
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com');
|
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com');
|
||||||
$this->assertSame('foo', $provider->loadUserByUsername('Foo')->getUsername());
|
$this->assertSame('foo', $provider->loadUserByIdentifier('Foo')->getUserIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadUserByUsernameIsSuccessfulWithPasswordAttribute()
|
public function testLoadUserByUsernameIsSuccessfulWithPasswordAttribute()
|
||||||
@ -330,7 +330,7 @@ class LdapUserProviderTest extends TestCase
|
|||||||
;
|
;
|
||||||
|
|
||||||
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com', null, null, [], 'sAMAccountName', '({uid_key}={username})', 'userpassword', ['email']);
|
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com', null, null, [], 'sAMAccountName', '({uid_key}={username})', 'userpassword', ['email']);
|
||||||
$this->assertInstanceOf(LdapUser::class, $provider->loadUserByUsername('foo'));
|
$this->assertInstanceOf(LdapUser::class, $provider->loadUserByIdentifier('foo'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRefreshUserShouldReturnUserWithSameProperties()
|
public function testRefreshUserShouldReturnUserWithSameProperties()
|
||||||
|
@ -196,6 +196,10 @@ class SomeUser implements UserInterface
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getUserIdentifier(): string
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public function eraseCredentials()
|
public function eraseCredentials()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,11 @@ CHANGELOG
|
|||||||
5.3
|
5.3
|
||||||
---
|
---
|
||||||
|
|
||||||
|
* Deprecate `PersistentTokenInterface::getUsername()` in favor of `PersistentTokenInterface::getUserIdentifier()`
|
||||||
|
* Deprecate `UsernameNotFoundException` in favor of `UserNotFoundException` and `getUsername()`/`setUsername()` in favor of `getUserIdentifier()`/`setUserIdentifier()`
|
||||||
|
* Deprecate `UserProviderInterface::loadUserByUsername()` in favor of `UserProviderInterface::loadUserByIdentifier()`
|
||||||
|
* Deprecate `TokenInterface::getUsername()` in favor of `TokenInterface::getUserIdentifier()`
|
||||||
|
* Deprecate `UserInterface::getUsername()` in favor of `getUserIdentifier()`
|
||||||
* Add `PassportInterface:getBadges()`, implemented by `PassportTrait`
|
* Add `PassportInterface:getBadges()`, implemented by `PassportTrait`
|
||||||
* [BC BREAK] Remove method `checkIfCompletelyResolved()` from `PassportInterface`, checking that passport badges are
|
* [BC BREAK] Remove method `checkIfCompletelyResolved()` from `PassportInterface`, checking that passport badges are
|
||||||
resolved is up to `AuthenticatorManager`
|
resolved is up to `AuthenticatorManager`
|
||||||
|
@ -21,6 +21,7 @@ use Symfony\Component\Security\Core\Exception\AccountStatusException;
|
|||||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
||||||
use Symfony\Component\Security\Core\Exception\ProviderNotFoundException;
|
use Symfony\Component\Security\Core\Exception\ProviderNotFoundException;
|
||||||
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
|
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
|
||||||
|
|
||||||
// Help opcache.preload discover always-needed symbols
|
// Help opcache.preload discover always-needed symbols
|
||||||
@ -105,6 +106,11 @@ class AuthenticationProviderManager implements AuthenticationManagerInterface
|
|||||||
$this->eventDispatcher->dispatch(new AuthenticationSuccessEvent($result), AuthenticationEvents::AUTHENTICATION_SUCCESS);
|
$this->eventDispatcher->dispatch(new AuthenticationSuccessEvent($result), AuthenticationEvents::AUTHENTICATION_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @deprecated since 5.3
|
||||||
|
if ($user = $result->getUser() instanceof UserInterface && !method_exists($result->getUser(), 'getUserIdentifier')) {
|
||||||
|
trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "getUserIdentifier(): string" in user class "%s" is deprecated. This method will replace "getUsername()" in Symfony 6.0.', get_debug_type($result->getUser()));
|
||||||
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
|||||||
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
|
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
|
||||||
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
|
||||||
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
use Symfony\Component\Security\Core\User\LegacyPasswordAuthenticatedUserInterface;
|
use Symfony\Component\Security\Core\User\LegacyPasswordAuthenticatedUserInterface;
|
||||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||||
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
||||||
@ -108,7 +108,7 @@ class DaoAuthenticationProvider extends UserAuthenticationProvider
|
|||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
protected function retrieveUser(string $username, UsernamePasswordToken $token)
|
protected function retrieveUser(string $userIdentifier, UsernamePasswordToken $token)
|
||||||
{
|
{
|
||||||
$user = $token->getUser();
|
$user = $token->getUser();
|
||||||
if ($user instanceof UserInterface) {
|
if ($user instanceof UserInterface) {
|
||||||
@ -116,15 +116,22 @@ class DaoAuthenticationProvider extends UserAuthenticationProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$user = $this->userProvider->loadUserByUsername($username);
|
// @deprecated since 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0
|
||||||
|
if (method_exists($this->userProvider, 'loadUserByIdentifier')) {
|
||||||
|
$user = $this->userProvider->loadUserByIdentifier($userIdentifier);
|
||||||
|
} else {
|
||||||
|
trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider));
|
||||||
|
|
||||||
|
$user = $this->userProvider->loadUserByUsername($userIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
if (!$user instanceof UserInterface) {
|
if (!$user instanceof UserInterface) {
|
||||||
throw new AuthenticationServiceException('The user provider must return a UserInterface object.');
|
throw new AuthenticationServiceException('The user provider must return a UserInterface object.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $user;
|
return $user;
|
||||||
} catch (UsernameNotFoundException $e) {
|
} catch (UserNotFoundException $e) {
|
||||||
$e->setUsername($username);
|
$e->setUserIdentifier($userIdentifier);
|
||||||
throw $e;
|
throw $e;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$e = new AuthenticationServiceException($e->getMessage(), 0, $e);
|
$e = new AuthenticationServiceException($e->getMessage(), 0, $e);
|
||||||
|
@ -16,7 +16,7 @@ use Symfony\Component\Ldap\LdapInterface;
|
|||||||
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
||||||
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
||||||
use Symfony\Component\Security\Core\Exception\LogicException;
|
use Symfony\Component\Security\Core\Exception\LogicException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||||
@ -38,7 +38,7 @@ class LdapBindAuthenticationProvider extends UserAuthenticationProvider
|
|||||||
private $searchDn;
|
private $searchDn;
|
||||||
private $searchPassword;
|
private $searchPassword;
|
||||||
|
|
||||||
public function __construct(UserProviderInterface $userProvider, UserCheckerInterface $userChecker, string $providerKey, LdapInterface $ldap, string $dnString = '{username}', bool $hideUserNotFoundExceptions = true, string $searchDn = '', string $searchPassword = '')
|
public function __construct(UserProviderInterface $userProvider, UserCheckerInterface $userChecker, string $providerKey, LdapInterface $ldap, string $dnString = '{user_identifier}', bool $hideUserNotFoundExceptions = true, string $searchDn = '', string $searchPassword = '')
|
||||||
{
|
{
|
||||||
parent::__construct($userChecker, $providerKey, $hideUserNotFoundExceptions);
|
parent::__construct($userChecker, $providerKey, $hideUserNotFoundExceptions);
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ class LdapBindAuthenticationProvider extends UserAuthenticationProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a query string to use in order to find a DN for the username.
|
* Set a query string to use in order to find a DN for the user identifier.
|
||||||
*/
|
*/
|
||||||
public function setQueryString(string $queryString)
|
public function setQueryString(string $queryString)
|
||||||
{
|
{
|
||||||
@ -60,13 +60,20 @@ class LdapBindAuthenticationProvider extends UserAuthenticationProvider
|
|||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
protected function retrieveUser(string $username, UsernamePasswordToken $token)
|
protected function retrieveUser(string $userIdentifier, UsernamePasswordToken $token)
|
||||||
{
|
{
|
||||||
if (AuthenticationProviderInterface::USERNAME_NONE_PROVIDED === $username) {
|
if (AuthenticationProviderInterface::USERNAME_NONE_PROVIDED === $userIdentifier) {
|
||||||
throw new UsernameNotFoundException('Username can not be null.');
|
throw new UserNotFoundException('User identifier can not be null.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->userProvider->loadUserByUsername($username);
|
// @deprecated since 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0
|
||||||
|
if (method_exists($this->userProvider, 'loadUserByIdentifier')) {
|
||||||
|
return $this->userProvider->loadUserByIdentifier($userIdentifier);
|
||||||
|
} else {
|
||||||
|
trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider));
|
||||||
|
|
||||||
|
return $this->userProvider->loadUserByUsername($userIdentifier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,7 +81,8 @@ class LdapBindAuthenticationProvider extends UserAuthenticationProvider
|
|||||||
*/
|
*/
|
||||||
protected function checkAuthentication(UserInterface $user, UsernamePasswordToken $token)
|
protected function checkAuthentication(UserInterface $user, UsernamePasswordToken $token)
|
||||||
{
|
{
|
||||||
$username = $token->getUsername();
|
// @deprecated since 5.3, change to $token->getUserIdentifier() in 6.0
|
||||||
|
$userIdentifier = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername();
|
||||||
$password = $token->getCredentials();
|
$password = $token->getCredentials();
|
||||||
|
|
||||||
if ('' === (string) $password) {
|
if ('' === (string) $password) {
|
||||||
@ -88,8 +96,8 @@ class LdapBindAuthenticationProvider extends UserAuthenticationProvider
|
|||||||
} else {
|
} else {
|
||||||
throw new LogicException('Using the "query_string" config without using a "search_dn" and a "search_password" is not supported.');
|
throw new LogicException('Using the "query_string" config without using a "search_dn" and a "search_password" is not supported.');
|
||||||
}
|
}
|
||||||
$username = $this->ldap->escape($username, '', LdapInterface::ESCAPE_FILTER);
|
$userIdentifier = $this->ldap->escape($userIdentifier, '', LdapInterface::ESCAPE_FILTER);
|
||||||
$query = str_replace('{username}', $username, $this->queryString);
|
$query = str_replace(['{username}', '{user_identifier}'], $userIdentifier, $this->queryString);
|
||||||
$result = $this->ldap->query($this->dnString, $query)->execute();
|
$result = $this->ldap->query($this->dnString, $query)->execute();
|
||||||
if (1 !== $result->count()) {
|
if (1 !== $result->count()) {
|
||||||
throw new BadCredentialsException('The presented username is invalid.');
|
throw new BadCredentialsException('The presented username is invalid.');
|
||||||
@ -97,8 +105,8 @@ class LdapBindAuthenticationProvider extends UserAuthenticationProvider
|
|||||||
|
|
||||||
$dn = $result[0]->getDn();
|
$dn = $result[0]->getDn();
|
||||||
} else {
|
} else {
|
||||||
$username = $this->ldap->escape($username, '', LdapInterface::ESCAPE_DN);
|
$userIdentifier = $this->ldap->escape($userIdentifier, '', LdapInterface::ESCAPE_DN);
|
||||||
$dn = str_replace('{username}', $username, $this->dnString);
|
$dn = str_replace(['{username}', '{user_identifier}'], $userIdentifier, $this->dnString);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->ldap->bind($dn, $password);
|
$this->ldap->bind($dn, $password);
|
||||||
|
@ -24,7 +24,7 @@ use Symfony\Component\Security\Core\User\UserProviderInterface;
|
|||||||
* This authentication provider will not perform any checks on authentication
|
* This authentication provider will not perform any checks on authentication
|
||||||
* requests, as they should already be pre-authenticated. However, the
|
* requests, as they should already be pre-authenticated. However, the
|
||||||
* UserProviderInterface implementation may still throw a
|
* UserProviderInterface implementation may still throw a
|
||||||
* UsernameNotFoundException, for example.
|
* UserNotFoundException, for example.
|
||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
*/
|
*/
|
||||||
@ -54,7 +54,15 @@ class PreAuthenticatedAuthenticationProvider implements AuthenticationProviderIn
|
|||||||
throw new BadCredentialsException('No pre-authenticated principal found in request.');
|
throw new BadCredentialsException('No pre-authenticated principal found in request.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = $this->userProvider->loadUserByUsername($user);
|
$userIdentifier = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername();
|
||||||
|
// @deprecated since 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0
|
||||||
|
if (method_exists($this->userProvider, 'loadUserByIdentifier')) {
|
||||||
|
$user = $this->userProvider->loadUserByIdentifier($userIdentifier);
|
||||||
|
} else {
|
||||||
|
trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider));
|
||||||
|
|
||||||
|
$user = $this->userProvider->loadUserByUsername($userIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
$this->userChecker->checkPostAuth($user);
|
$this->userChecker->checkPostAuth($user);
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ class RememberMeAuthenticationProvider implements AuthenticationProviderInterfac
|
|||||||
|
|
||||||
$user = $token->getUser();
|
$user = $token->getUser();
|
||||||
|
|
||||||
if (!$token->getUser() instanceof UserInterface) {
|
if (!$user instanceof UserInterface) {
|
||||||
throw new LogicException(sprintf('Method "%s::getUser()" must return a "%s" instance, "%s" returned.', get_debug_type($token), UserInterface::class, get_debug_type($user)));
|
throw new LogicException(sprintf('Method "%s::getUser()" must return a "%s" instance, "%s" returned.', get_debug_type($token), UserInterface::class, get_debug_type($user)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
|||||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
|
||||||
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
|
|
||||||
@ -55,18 +55,18 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter
|
|||||||
throw new AuthenticationException('The token is not supported by this authentication provider.');
|
throw new AuthenticationException('The token is not supported by this authentication provider.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$username = $token->getUsername();
|
$username = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername();
|
||||||
if ('' === $username || null === $username) {
|
if ('' === $username || null === $username) {
|
||||||
$username = AuthenticationProviderInterface::USERNAME_NONE_PROVIDED;
|
$username = AuthenticationProviderInterface::USERNAME_NONE_PROVIDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$user = $this->retrieveUser($username, $token);
|
$user = $this->retrieveUser($username, $token);
|
||||||
} catch (UsernameNotFoundException $e) {
|
} catch (UserNotFoundException $e) {
|
||||||
if ($this->hideUserNotFoundExceptions) {
|
if ($this->hideUserNotFoundExceptions) {
|
||||||
throw new BadCredentialsException('Bad credentials.', 0, $e);
|
throw new BadCredentialsException('Bad credentials.', 0, $e);
|
||||||
}
|
}
|
||||||
$e->setUsername($username);
|
$e->setUserIdentifier($username);
|
||||||
|
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ class InMemoryTokenProvider implements TokenProviderInterface
|
|||||||
|
|
||||||
$token = new PersistentToken(
|
$token = new PersistentToken(
|
||||||
$this->tokens[$series]->getClass(),
|
$this->tokens[$series]->getClass(),
|
||||||
$this->tokens[$series]->getUsername(),
|
method_exists($this->tokens[$series], 'getUserIdentifier') ? $this->tokens[$series]->getUserIdentifier() : $this->tokens[$series]->getUsername(),
|
||||||
$series,
|
$series,
|
||||||
$tokenValue,
|
$tokenValue,
|
||||||
$lastUsed
|
$lastUsed
|
||||||
|
@ -19,18 +19,18 @@ namespace Symfony\Component\Security\Core\Authentication\RememberMe;
|
|||||||
final class PersistentToken implements PersistentTokenInterface
|
final class PersistentToken implements PersistentTokenInterface
|
||||||
{
|
{
|
||||||
private $class;
|
private $class;
|
||||||
private $username;
|
private $userIdentifier;
|
||||||
private $series;
|
private $series;
|
||||||
private $tokenValue;
|
private $tokenValue;
|
||||||
private $lastUsed;
|
private $lastUsed;
|
||||||
|
|
||||||
public function __construct(string $class, string $username, string $series, string $tokenValue, \DateTime $lastUsed)
|
public function __construct(string $class, string $userIdentifier, string $series, string $tokenValue, \DateTime $lastUsed)
|
||||||
{
|
{
|
||||||
if (empty($class)) {
|
if (empty($class)) {
|
||||||
throw new \InvalidArgumentException('$class must not be empty.');
|
throw new \InvalidArgumentException('$class must not be empty.');
|
||||||
}
|
}
|
||||||
if ('' === $username) {
|
if ('' === $userIdentifier) {
|
||||||
throw new \InvalidArgumentException('$username must not be empty.');
|
throw new \InvalidArgumentException('$userIdentifier must not be empty.');
|
||||||
}
|
}
|
||||||
if (empty($series)) {
|
if (empty($series)) {
|
||||||
throw new \InvalidArgumentException('$series must not be empty.');
|
throw new \InvalidArgumentException('$series must not be empty.');
|
||||||
@ -40,7 +40,7 @@ final class PersistentToken implements PersistentTokenInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->class = $class;
|
$this->class = $class;
|
||||||
$this->username = $username;
|
$this->userIdentifier = $userIdentifier;
|
||||||
$this->series = $series;
|
$this->series = $series;
|
||||||
$this->tokenValue = $tokenValue;
|
$this->tokenValue = $tokenValue;
|
||||||
$this->lastUsed = $lastUsed;
|
$this->lastUsed = $lastUsed;
|
||||||
@ -59,7 +59,14 @@ final class PersistentToken implements PersistentTokenInterface
|
|||||||
*/
|
*/
|
||||||
public function getUsername(): string
|
public function getUsername(): string
|
||||||
{
|
{
|
||||||
return $this->username;
|
trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use getUserIdentifier() instead.', __METHOD__);
|
||||||
|
|
||||||
|
return $this->userIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserIdentifier(): string
|
||||||
|
{
|
||||||
|
return $this->userIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,6 +15,8 @@ namespace Symfony\Component\Security\Core\Authentication\RememberMe;
|
|||||||
* Interface to be implemented by persistent token classes (such as
|
* Interface to be implemented by persistent token classes (such as
|
||||||
* Doctrine entities representing a remember-me token).
|
* Doctrine entities representing a remember-me token).
|
||||||
*
|
*
|
||||||
|
* @method string getUserIdentifier() returns the identifier used to authenticate (e.g. their e-mailaddress or username)
|
||||||
|
*
|
||||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||||
*/
|
*/
|
||||||
interface PersistentTokenInterface
|
interface PersistentTokenInterface
|
||||||
@ -26,13 +28,6 @@ interface PersistentTokenInterface
|
|||||||
*/
|
*/
|
||||||
public function getClass();
|
public function getClass();
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the username.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getUsername();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the series.
|
* Returns the series.
|
||||||
*
|
*
|
||||||
|
@ -51,10 +51,32 @@ abstract class AbstractToken implements TokenInterface
|
|||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function getUsername()
|
public function getUsername(/* $legacy = true */)
|
||||||
{
|
{
|
||||||
|
if (1 === func_num_args() && false === func_get_arg(0)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use getUserIdentifier() instead.', __METHOD__);
|
||||||
|
|
||||||
if ($this->user instanceof UserInterface) {
|
if ($this->user instanceof UserInterface) {
|
||||||
return $this->user->getUsername();
|
return method_exists($this->user, 'getUserIdentifier') ? $this->user->getUserIdentifier() : $this->user->getUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (string) $this->user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserIdentifier(): string
|
||||||
|
{
|
||||||
|
// method returns "null" in non-legacy mode if not overriden
|
||||||
|
$username = $this->getUsername(false);
|
||||||
|
if (null !== $username) {
|
||||||
|
trigger_deprecation('symfony/security-core', '5.3', 'Method "%s::getUsername()" is deprecated, override "getUserIdentifier()" instead.', get_debug_type($this));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->user instanceof UserInterface) {
|
||||||
|
// @deprecated since 5.3, change to $user->getUserIdentifier() in 6.0
|
||||||
|
return method_exists($this->user, 'getUserIdentifier') ? $this->user->getUserIdentifier() : $this->user->getUsername();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (string) $this->user;
|
return (string) $this->user;
|
||||||
@ -234,7 +256,7 @@ abstract class AbstractToken implements TokenInterface
|
|||||||
$roles[] = $role;
|
$roles[] = $role;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprintf('%s(user="%s", authenticated=%s, roles="%s")', $class, $this->getUsername(), json_encode($this->authenticated), implode(', ', $roles));
|
return sprintf('%s(user="%s", authenticated=%s, roles="%s")', $class, $this->getUserIdentifier(), json_encode($this->authenticated), implode(', ', $roles));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -283,7 +305,11 @@ abstract class AbstractToken implements TokenInterface
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->user->getUsername() !== $user->getUsername()) {
|
// @deprecated since Symfony 5.3, drop getUsername() in 6.0
|
||||||
|
$userIdentifier = function ($user) {
|
||||||
|
return method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername();
|
||||||
|
};
|
||||||
|
if ($userIdentifier($this->user) !== $userIdentifier($user)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,13 @@ class NullToken implements TokenInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getUsername()
|
public function getUsername()
|
||||||
|
{
|
||||||
|
trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use getUserIdentifier() instead.', __METHOD__);
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserIdentifier(): string
|
||||||
{
|
{
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,11 @@ class TokenStorage implements TokenStorageInterface, ResetInterface
|
|||||||
if ($token) {
|
if ($token) {
|
||||||
// ensure any initializer is called
|
// ensure any initializer is called
|
||||||
$this->getToken();
|
$this->getToken();
|
||||||
|
|
||||||
|
// @deprecated since 5.3
|
||||||
|
if (!method_exists($token, 'getUserIdentifier')) {
|
||||||
|
trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "getUserIdentifier(): string" in token class "%s" is deprecated. This method will replace "getUsername()" in Symfony 6.0.', get_debug_type($token));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->initializer = null;
|
$this->initializer = null;
|
||||||
|
@ -16,6 +16,8 @@ use Symfony\Component\Security\Core\User\UserInterface;
|
|||||||
/**
|
/**
|
||||||
* TokenInterface is the interface for the user authentication information.
|
* TokenInterface is the interface for the user authentication information.
|
||||||
*
|
*
|
||||||
|
* @method string getUserIdentifier() returns the user identifier used during authentication (e.g. a user's e-mailaddress or username)
|
||||||
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||||
*/
|
*/
|
||||||
@ -65,13 +67,6 @@ interface TokenInterface extends \Serializable
|
|||||||
*/
|
*/
|
||||||
public function setUser($user);
|
public function setUser($user);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the username.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getUsername();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the user is authenticated or not.
|
* Returns whether the user is authenticated or not.
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,96 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Security\Core\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UserNotFoundException is thrown if a User cannot be found for the given identifier.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
* @author Alexander <iam.asm89@gmail.com>
|
||||||
|
*/
|
||||||
|
class UserNotFoundException extends AuthenticationException
|
||||||
|
{
|
||||||
|
private $identifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getMessageKey()
|
||||||
|
{
|
||||||
|
return 'Username could not be found.';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the user identifier (e.g. username or e-mailaddress).
|
||||||
|
*/
|
||||||
|
public function getUserIdentifier(): string
|
||||||
|
{
|
||||||
|
return $this->identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
public function getUsername()
|
||||||
|
{
|
||||||
|
trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use getUserIdentifier() instead.', __METHOD__);
|
||||||
|
|
||||||
|
return $this->identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the user identifier (e.g. username or e-mailaddress).
|
||||||
|
*/
|
||||||
|
public function setUserIdentifier(string $identifier): void
|
||||||
|
{
|
||||||
|
$this->identifier = $identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
public function setUsername(string $username)
|
||||||
|
{
|
||||||
|
trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use getUserIdentifier() instead.', __METHOD__);
|
||||||
|
|
||||||
|
$this->identifier = $username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getMessageData()
|
||||||
|
{
|
||||||
|
return ['{{ username }}' => $this->identifier, '{{ user_identifier }}' => $this->identifier];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __serialize(): array
|
||||||
|
{
|
||||||
|
return [$this->identifier, parent::__serialize()];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __unserialize(array $data): void
|
||||||
|
{
|
||||||
|
[$this->identifier, $parentData] = $data;
|
||||||
|
$parentData = \is_array($parentData) ? $parentData : unserialize($parentData);
|
||||||
|
parent::__unserialize($parentData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class_alias(UserNotFoundException::class, UsernameNotFoundException::class);
|
@ -11,65 +11,15 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Security\Core\Exception;
|
namespace Symfony\Component\Security\Core\Exception;
|
||||||
|
|
||||||
/**
|
trigger_deprecation('symfony/security-core', '5.3', 'The "%s" class is deprecated, use "%s" instead.', UsernameNotFoundException::class, UserNotFoundException::class);
|
||||||
* UsernameNotFoundException is thrown if a User cannot be found by its username.
|
|
||||||
*
|
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
|
||||||
* @author Alexander <iam.asm89@gmail.com>
|
|
||||||
*/
|
|
||||||
class UsernameNotFoundException extends AuthenticationException
|
|
||||||
{
|
|
||||||
private $username;
|
|
||||||
|
|
||||||
/**
|
class_exists(UserNotFoundException::class);
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getMessageKey()
|
|
||||||
{
|
|
||||||
return 'Username could not be found.';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (false) {
|
||||||
/**
|
/**
|
||||||
* Get the username.
|
* @deprecated since Symfony 5.3 to be removed in 6.0, use UserNotFoundException instead.
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getUsername()
|
class UsernameNotFoundException extends AuthenticationException
|
||||||
{
|
{
|
||||||
return $this->username;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the username.
|
|
||||||
*/
|
|
||||||
public function setUsername(string $username)
|
|
||||||
{
|
|
||||||
$this->username = $username;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getMessageData()
|
|
||||||
{
|
|
||||||
return ['{{ username }}' => $this->username];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function __serialize(): array
|
|
||||||
{
|
|
||||||
return [$this->username, parent::__serialize()];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function __unserialize(array $data): void
|
|
||||||
{
|
|
||||||
[$this->username, $parentData] = $data;
|
|
||||||
$parentData = \is_array($parentData) ? $parentData : unserialize($parentData);
|
|
||||||
parent::__unserialize($parentData);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ use Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent;
|
|||||||
use Symfony\Component\Security\Core\Exception\AccountStatusException;
|
use Symfony\Component\Security\Core\Exception\AccountStatusException;
|
||||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
use Symfony\Component\Security\Core\Exception\ProviderNotFoundException;
|
use Symfony\Component\Security\Core\Exception\ProviderNotFoundException;
|
||||||
|
use Symfony\Component\Security\Core\User\InMemoryUser;
|
||||||
|
|
||||||
class AuthenticationProviderManagerTest extends TestCase
|
class AuthenticationProviderManagerTest extends TestCase
|
||||||
{
|
{
|
||||||
@ -90,9 +91,12 @@ class AuthenticationProviderManagerTest extends TestCase
|
|||||||
|
|
||||||
public function testAuthenticateWhenOneReturnsAuthenticationExceptionButNotAll()
|
public function testAuthenticateWhenOneReturnsAuthenticationExceptionButNotAll()
|
||||||
{
|
{
|
||||||
|
$expected = $this->createMock(TokenInterface::class);
|
||||||
|
$expected->expects($this->any())->method('getUser')->willReturn(new InMemoryUser('wouter', null));
|
||||||
|
|
||||||
$manager = new AuthenticationProviderManager([
|
$manager = new AuthenticationProviderManager([
|
||||||
$this->getAuthenticationProvider(true, null, AuthenticationException::class),
|
$this->getAuthenticationProvider(true, null, AuthenticationException::class),
|
||||||
$this->getAuthenticationProvider(true, $expected = $this->createMock(TokenInterface::class)),
|
$this->getAuthenticationProvider(true, $expected),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$token = $manager->authenticate($this->createMock(TokenInterface::class));
|
$token = $manager->authenticate($this->createMock(TokenInterface::class));
|
||||||
@ -106,8 +110,10 @@ class AuthenticationProviderManagerTest extends TestCase
|
|||||||
->expects($this->never())
|
->expects($this->never())
|
||||||
->method('supports')
|
->method('supports')
|
||||||
;
|
;
|
||||||
|
$expected = $this->createMock(TokenInterface::class);
|
||||||
|
$expected->expects($this->any())->method('getUser')->willReturn(new InMemoryUser('wouter', null));
|
||||||
$manager = new AuthenticationProviderManager([
|
$manager = new AuthenticationProviderManager([
|
||||||
$this->getAuthenticationProvider(true, $expected = $this->createMock(TokenInterface::class)),
|
$this->getAuthenticationProvider(true, $expected),
|
||||||
$second,
|
$second,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -155,6 +155,10 @@ class FakeCustomToken implements TokenInterface
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getUserIdentifier(): string
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public function isAuthenticated(): bool
|
public function isAuthenticated(): bool
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\Security\Core\Tests\Authentication\Provider;
|
namespace Symfony\Component\Security\Core\Tests\Authentication\Provider;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
|
||||||
use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactoryInterface;
|
use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactoryInterface;
|
||||||
use Symfony\Component\PasswordHasher\Hasher\PlaintextPasswordHasher;
|
use Symfony\Component\PasswordHasher\Hasher\PlaintextPasswordHasher;
|
||||||
use Symfony\Component\PasswordHasher\PasswordHasherInterface;
|
use Symfony\Component\PasswordHasher\PasswordHasherInterface;
|
||||||
@ -20,8 +21,9 @@ use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
|||||||
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
|
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
|
||||||
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
|
||||||
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
use Symfony\Component\Security\Core\User\InMemoryUser;
|
use Symfony\Component\Security\Core\User\InMemoryUser;
|
||||||
|
use Symfony\Component\Security\Core\User\InMemoryUserProvider;
|
||||||
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
@ -29,13 +31,25 @@ use Symfony\Component\Security\Core\User\UserProviderInterface;
|
|||||||
|
|
||||||
class DaoAuthenticationProviderTest extends TestCase
|
class DaoAuthenticationProviderTest extends TestCase
|
||||||
{
|
{
|
||||||
|
use ExpectDeprecationTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testRetrieveUserWhenProviderDoesNotReturnAnUserInterface()
|
public function testRetrieveUserWhenProviderDoesNotReturnAnUserInterface()
|
||||||
{
|
{
|
||||||
$this->expectException(AuthenticationServiceException::class);
|
$this->expectException(AuthenticationServiceException::class);
|
||||||
$provider = $this->getProvider('fabien');
|
$userProvider = $this->createMock(DaoAuthenticationProviderTest_UserProvider::class);
|
||||||
|
$userProvider->expects($this->once())
|
||||||
|
->method('loadUserByUsername')
|
||||||
|
->willReturn('fabien')
|
||||||
|
;
|
||||||
|
$provider = $this->getProvider(null, null, null, $userProvider);
|
||||||
$method = new \ReflectionMethod($provider, 'retrieveUser');
|
$method = new \ReflectionMethod($provider, 'retrieveUser');
|
||||||
$method->setAccessible(true);
|
$method->setAccessible(true);
|
||||||
|
|
||||||
|
$this->expectDeprecation('Since symfony/security-core 5.3: Not implementing method "loadUserByIdentifier()" in user provider "'.get_debug_type($userProvider).'" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.');
|
||||||
|
|
||||||
$method->invoke($provider, 'fabien', $this->getSupportedToken());
|
$method->invoke($provider, 'fabien', $this->getSupportedToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,12 +58,8 @@ class DaoAuthenticationProviderTest extends TestCase
|
|||||||
*/
|
*/
|
||||||
public function testRetrieveUserWhenUsernameIsNotFoundWithLegacyEncoderFactory()
|
public function testRetrieveUserWhenUsernameIsNotFoundWithLegacyEncoderFactory()
|
||||||
{
|
{
|
||||||
$this->expectException(UsernameNotFoundException::class);
|
$this->expectException(UserNotFoundException::class);
|
||||||
$userProvider = $this->createMock(UserProviderInterface::class);
|
$userProvider = new InMemoryUserProvider();
|
||||||
$userProvider->expects($this->once())
|
|
||||||
->method('loadUserByUsername')
|
|
||||||
->willThrowException(new UsernameNotFoundException())
|
|
||||||
;
|
|
||||||
|
|
||||||
$provider = new DaoAuthenticationProvider($userProvider, $this->createMock(UserCheckerInterface::class), 'key', $this->createMock(EncoderFactoryInterface::class));
|
$provider = new DaoAuthenticationProvider($userProvider, $this->createMock(UserCheckerInterface::class), 'key', $this->createMock(EncoderFactoryInterface::class));
|
||||||
$method = new \ReflectionMethod($provider, 'retrieveUser');
|
$method = new \ReflectionMethod($provider, 'retrieveUser');
|
||||||
@ -60,12 +70,8 @@ class DaoAuthenticationProviderTest extends TestCase
|
|||||||
|
|
||||||
public function testRetrieveUserWhenUsernameIsNotFound()
|
public function testRetrieveUserWhenUsernameIsNotFound()
|
||||||
{
|
{
|
||||||
$this->expectException(UsernameNotFoundException::class);
|
$this->expectException(UserNotFoundException::class);
|
||||||
$userProvider = $this->createMock(UserProviderInterface::class);
|
$userProvider = new InMemoryUserProvider();
|
||||||
$userProvider->expects($this->once())
|
|
||||||
->method('loadUserByUsername')
|
|
||||||
->willThrowException(new UsernameNotFoundException())
|
|
||||||
;
|
|
||||||
|
|
||||||
$provider = new DaoAuthenticationProvider($userProvider, $this->createMock(UserCheckerInterface::class), 'key', $this->createMock(PasswordHasherFactoryInterface::class));
|
$provider = new DaoAuthenticationProvider($userProvider, $this->createMock(UserCheckerInterface::class), 'key', $this->createMock(PasswordHasherFactoryInterface::class));
|
||||||
$method = new \ReflectionMethod($provider, 'retrieveUser');
|
$method = new \ReflectionMethod($provider, 'retrieveUser');
|
||||||
@ -77,9 +83,9 @@ class DaoAuthenticationProviderTest extends TestCase
|
|||||||
public function testRetrieveUserWhenAnExceptionOccurs()
|
public function testRetrieveUserWhenAnExceptionOccurs()
|
||||||
{
|
{
|
||||||
$this->expectException(AuthenticationServiceException::class);
|
$this->expectException(AuthenticationServiceException::class);
|
||||||
$userProvider = $this->createMock(UserProviderInterface::class);
|
$userProvider = $this->createMock(InMemoryUserProvider::class);
|
||||||
$userProvider->expects($this->once())
|
$userProvider->expects($this->once())
|
||||||
->method('loadUserByUsername')
|
->method('loadUserByIdentifier')
|
||||||
->willThrowException(new \RuntimeException())
|
->willThrowException(new \RuntimeException())
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -92,9 +98,9 @@ class DaoAuthenticationProviderTest extends TestCase
|
|||||||
|
|
||||||
public function testRetrieveUserReturnsUserFromTokenOnReauthentication()
|
public function testRetrieveUserReturnsUserFromTokenOnReauthentication()
|
||||||
{
|
{
|
||||||
$userProvider = $this->createMock(UserProviderInterface::class);
|
$userProvider = $this->createMock(InMemoryUserProvider::class);
|
||||||
$userProvider->expects($this->never())
|
$userProvider->expects($this->never())
|
||||||
->method('loadUserByUsername')
|
->method('loadUserByIdentifier')
|
||||||
;
|
;
|
||||||
|
|
||||||
$user = new TestUser();
|
$user = new TestUser();
|
||||||
@ -114,19 +120,13 @@ class DaoAuthenticationProviderTest extends TestCase
|
|||||||
|
|
||||||
public function testRetrieveUser()
|
public function testRetrieveUser()
|
||||||
{
|
{
|
||||||
$user = new TestUser();
|
$userProvider = new InMemoryUserProvider(['fabien' => []]);
|
||||||
|
|
||||||
$userProvider = $this->createMock(UserProviderInterface::class);
|
|
||||||
$userProvider->expects($this->once())
|
|
||||||
->method('loadUserByUsername')
|
|
||||||
->willReturn($user)
|
|
||||||
;
|
|
||||||
|
|
||||||
$provider = new DaoAuthenticationProvider($userProvider, $this->createMock(UserCheckerInterface::class), 'key', $this->createMock(PasswordHasherFactoryInterface::class));
|
$provider = new DaoAuthenticationProvider($userProvider, $this->createMock(UserCheckerInterface::class), 'key', $this->createMock(PasswordHasherFactoryInterface::class));
|
||||||
$method = new \ReflectionMethod($provider, 'retrieveUser');
|
$method = new \ReflectionMethod($provider, 'retrieveUser');
|
||||||
$method->setAccessible(true);
|
$method->setAccessible(true);
|
||||||
|
|
||||||
$this->assertSame($user, $method->invoke($provider, 'fabien', $this->getSupportedToken()));
|
$this->assertEquals('fabien', $method->invoke($provider, 'fabien', $this->getSupportedToken())->getUserIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCheckAuthenticationWhenCredentialsAreEmpty()
|
public function testCheckAuthenticationWhenCredentialsAreEmpty()
|
||||||
@ -323,15 +323,17 @@ class DaoAuthenticationProviderTest extends TestCase
|
|||||||
return $mock;
|
return $mock;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getProvider($user = null, $userChecker = null, $passwordHasher = null)
|
protected function getProvider($user = null, $userChecker = null, $passwordHasher = null, $userProvider = null)
|
||||||
{
|
{
|
||||||
|
if (null === $userProvider) {
|
||||||
$userProvider = $this->createMock(PasswordUpgraderProvider::class);
|
$userProvider = $this->createMock(PasswordUpgraderProvider::class);
|
||||||
if (null !== $user) {
|
if (null !== $user) {
|
||||||
$userProvider->expects($this->once())
|
$userProvider->expects($this->once())
|
||||||
->method('loadUserByUsername')
|
->method('loadUserByIdentifier')
|
||||||
->willReturn($user)
|
->willReturn($user)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (null === $userChecker) {
|
if (null === $userChecker) {
|
||||||
$userChecker = $this->createMock(UserCheckerInterface::class);
|
$userChecker = $this->createMock(UserCheckerInterface::class);
|
||||||
@ -374,6 +376,11 @@ class TestUser implements UserInterface
|
|||||||
return 'jane_doe';
|
return 'jane_doe';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getUserIdentifier(): string
|
||||||
|
{
|
||||||
|
return 'jane_doe';
|
||||||
|
}
|
||||||
|
|
||||||
public function eraseCredentials()
|
public function eraseCredentials()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -381,4 +388,10 @@ class TestUser implements UserInterface
|
|||||||
interface PasswordUpgraderProvider extends UserProviderInterface, PasswordUpgraderInterface
|
interface PasswordUpgraderProvider extends UserProviderInterface, PasswordUpgraderInterface
|
||||||
{
|
{
|
||||||
public function upgradePassword(UserInterface $user, string $newHashedPassword): void;
|
public function upgradePassword(UserInterface $user, string $newHashedPassword): void;
|
||||||
|
public function loadUserByIdentifier(string $identifier): UserInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DaoAuthenticationProviderTest_UserProvider extends UserProviderInterface
|
||||||
|
{
|
||||||
|
public function loadUserByUsername($username);
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ use Symfony\Component\Security\Core\Authentication\Provider\LdapBindAuthenticati
|
|||||||
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
||||||
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
||||||
use Symfony\Component\Security\Core\User\InMemoryUser;
|
use Symfony\Component\Security\Core\User\InMemoryUser;
|
||||||
|
use Symfony\Component\Security\Core\User\InMemoryUserProvider;
|
||||||
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||||
|
|
||||||
@ -81,10 +82,10 @@ class LdapBindAuthenticationProviderTest extends TestCase
|
|||||||
|
|
||||||
public function testRetrieveUser()
|
public function testRetrieveUser()
|
||||||
{
|
{
|
||||||
$userProvider = $this->createMock(UserProviderInterface::class);
|
$userProvider = $this->createMock(InMemoryUserProvider::class);
|
||||||
$userProvider
|
$userProvider
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('loadUserByUsername')
|
->method('loadUserByIdentifier')
|
||||||
->with('foo')
|
->with('foo')
|
||||||
;
|
;
|
||||||
$ldap = $this->createMock(LdapInterface::class);
|
$ldap = $this->createMock(LdapInterface::class);
|
||||||
|
@ -18,6 +18,7 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
|||||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
||||||
use Symfony\Component\Security\Core\Exception\LockedException;
|
use Symfony\Component\Security\Core\Exception\LockedException;
|
||||||
|
use Symfony\Component\Security\Core\User\InMemoryUserProvider;
|
||||||
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||||
@ -120,10 +121,10 @@ class PreAuthenticatedAuthenticationProviderTest extends TestCase
|
|||||||
|
|
||||||
protected function getProvider($user = null, $userChecker = null)
|
protected function getProvider($user = null, $userChecker = null)
|
||||||
{
|
{
|
||||||
$userProvider = $this->createMock(UserProviderInterface::class);
|
$userProvider = $this->createMock(InMemoryUserProvider::class);
|
||||||
if (null !== $user) {
|
if (null !== $user) {
|
||||||
$userProvider->expects($this->once())
|
$userProvider->expects($this->once())
|
||||||
->method('loadUserByUsername')
|
->method('loadUserByIdentifier')
|
||||||
->willReturn($user)
|
->willReturn($user)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,8 @@ use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
|||||||
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
|
||||||
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
||||||
use Symfony\Component\Security\Core\Exception\CredentialsExpiredException;
|
use Symfony\Component\Security\Core\Exception\CredentialsExpiredException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
|
use Symfony\Component\Security\Core\User\InMemoryUser;
|
||||||
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
|
|
||||||
@ -46,11 +47,11 @@ class UserAuthenticationProviderTest extends TestCase
|
|||||||
|
|
||||||
public function testAuthenticateWhenUsernameIsNotFound()
|
public function testAuthenticateWhenUsernameIsNotFound()
|
||||||
{
|
{
|
||||||
$this->expectException(UsernameNotFoundException::class);
|
$this->expectException(UserNotFoundException::class);
|
||||||
$provider = $this->getProvider(false, false);
|
$provider = $this->getProvider(false, false);
|
||||||
$provider->expects($this->once())
|
$provider->expects($this->once())
|
||||||
->method('retrieveUser')
|
->method('retrieveUser')
|
||||||
->willThrowException(new UsernameNotFoundException())
|
->willThrowException(new UserNotFoundException())
|
||||||
;
|
;
|
||||||
|
|
||||||
$provider->authenticate($this->getSupportedToken());
|
$provider->authenticate($this->getSupportedToken());
|
||||||
@ -62,7 +63,7 @@ class UserAuthenticationProviderTest extends TestCase
|
|||||||
$provider = $this->getProvider(false, true);
|
$provider = $this->getProvider(false, true);
|
||||||
$provider->expects($this->once())
|
$provider->expects($this->once())
|
||||||
->method('retrieveUser')
|
->method('retrieveUser')
|
||||||
->willThrowException(new UsernameNotFoundException())
|
->willThrowException(new UserNotFoundException())
|
||||||
;
|
;
|
||||||
|
|
||||||
$provider->authenticate($this->getSupportedToken());
|
$provider->authenticate($this->getSupportedToken());
|
||||||
@ -194,7 +195,7 @@ class UserAuthenticationProviderTest extends TestCase
|
|||||||
;
|
;
|
||||||
|
|
||||||
$originalToken = $this->createMock(TokenInterface::class);
|
$originalToken = $this->createMock(TokenInterface::class);
|
||||||
$token = new SwitchUserToken($this->createMock(UserInterface::class), 'foo', 'key', [], $originalToken);
|
$token = new SwitchUserToken(new InMemoryUser('wouter', null), 'foo', 'key', [], $originalToken);
|
||||||
$token->setAttributes(['foo' => 'bar']);
|
$token->setAttributes(['foo' => 'bar']);
|
||||||
|
|
||||||
$authToken = $provider->authenticate($token);
|
$authToken = $provider->authenticate($token);
|
||||||
|
@ -12,19 +12,33 @@
|
|||||||
namespace Symfony\Component\Security\Core\Tests\Authentication\RememberMe;
|
namespace Symfony\Component\Security\Core\Tests\Authentication\RememberMe;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
|
||||||
use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken;
|
use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken;
|
||||||
|
|
||||||
class PersistentTokenTest extends TestCase
|
class PersistentTokenTest extends TestCase
|
||||||
{
|
{
|
||||||
|
use ExpectDeprecationTrait;
|
||||||
|
|
||||||
public function testConstructor()
|
public function testConstructor()
|
||||||
{
|
{
|
||||||
$lastUsed = new \DateTime();
|
$lastUsed = new \DateTime();
|
||||||
$token = new PersistentToken('fooclass', 'fooname', 'fooseries', 'footokenvalue', $lastUsed);
|
$token = new PersistentToken('fooclass', 'fooname', 'fooseries', 'footokenvalue', $lastUsed);
|
||||||
|
|
||||||
$this->assertEquals('fooclass', $token->getClass());
|
$this->assertEquals('fooclass', $token->getClass());
|
||||||
$this->assertEquals('fooname', $token->getUsername());
|
$this->assertEquals('fooname', $token->getUserIdentifier());
|
||||||
$this->assertEquals('fooseries', $token->getSeries());
|
$this->assertEquals('fooseries', $token->getSeries());
|
||||||
$this->assertEquals('footokenvalue', $token->getTokenValue());
|
$this->assertEquals('footokenvalue', $token->getTokenValue());
|
||||||
$this->assertSame($lastUsed, $token->getLastUsed());
|
$this->assertSame($lastUsed, $token->getLastUsed());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
|
public function testLegacyGetUsername()
|
||||||
|
{
|
||||||
|
$token = new PersistentToken('fooclass', 'fooname', 'fooseries', 'footokenvalue', new \DateTime());
|
||||||
|
|
||||||
|
$this->expectDeprecation('Since symfony/security-core 5.3: Method "Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken::getUsername()" is deprecated, use getUserIdentifier() instead.');
|
||||||
|
$this->assertEquals('fooname', $token->getUsername());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,19 @@
|
|||||||
namespace Symfony\Component\Security\Core\Tests\Authentication\Token;
|
namespace Symfony\Component\Security\Core\Tests\Authentication\Token;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
|
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
|
||||||
|
use Symfony\Component\Security\Core\User\InMemoryUser;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
|
|
||||||
class AbstractTokenTest extends TestCase
|
class AbstractTokenTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testGetUsername()
|
use ExpectDeprecationTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
|
public function testLegacyGetUsername()
|
||||||
{
|
{
|
||||||
$token = new ConcreteToken(['ROLE_FOO']);
|
$token = new ConcreteToken(['ROLE_FOO']);
|
||||||
$token->setUser('fabien');
|
$token->setUser('fabien');
|
||||||
@ -26,10 +33,43 @@ class AbstractTokenTest extends TestCase
|
|||||||
$token->setUser(new TestUser('fabien'));
|
$token->setUser(new TestUser('fabien'));
|
||||||
$this->assertEquals('fabien', $token->getUsername());
|
$this->assertEquals('fabien', $token->getUsername());
|
||||||
|
|
||||||
$user = $this->createMock(UserInterface::class);
|
$legacyUser = new class implements UserInterface {
|
||||||
$user->expects($this->once())->method('getUsername')->willReturn('fabien');
|
public function getUsername()
|
||||||
$token->setUser($user);
|
{
|
||||||
|
return 'fabien';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRoles()
|
||||||
|
{}
|
||||||
|
|
||||||
|
public function getPassword()
|
||||||
|
{}
|
||||||
|
|
||||||
|
public function getSalt()
|
||||||
|
{}
|
||||||
|
|
||||||
|
public function eraseCredentials()
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
$token->setUser($legacyUser);
|
||||||
$this->assertEquals('fabien', $token->getUsername());
|
$this->assertEquals('fabien', $token->getUsername());
|
||||||
|
|
||||||
|
$token->setUser($legacyUser);
|
||||||
|
$this->assertEquals('fabien', $token->getUserIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetUserIdentifier()
|
||||||
|
{
|
||||||
|
$token = new ConcreteToken(['ROLE_FOO']);
|
||||||
|
$token->setUser('fabien');
|
||||||
|
$this->assertEquals('fabien', $token->getUserIdentifier());
|
||||||
|
|
||||||
|
$token->setUser(new TestUser('fabien'));
|
||||||
|
$this->assertEquals('fabien', $token->getUserIdentifier());
|
||||||
|
|
||||||
|
$user = new InMemoryUser('fabien', null);
|
||||||
|
$token->setUser($user);
|
||||||
|
$this->assertEquals('fabien', $token->getUserIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testEraseCredentials()
|
public function testEraseCredentials()
|
||||||
@ -106,10 +146,8 @@ class AbstractTokenTest extends TestCase
|
|||||||
|
|
||||||
public function getUsers()
|
public function getUsers()
|
||||||
{
|
{
|
||||||
$user = $this->createMock(UserInterface::class);
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
[$user],
|
[new InMemoryUser('foo', null)],
|
||||||
[new TestUser('foo')],
|
[new TestUser('foo')],
|
||||||
['foo'],
|
['foo'],
|
||||||
];
|
];
|
||||||
@ -210,6 +248,11 @@ class SerializableUser implements UserInterface, \Serializable
|
|||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getUserIdentifier()
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
public function getPassword()
|
public function getPassword()
|
||||||
{
|
{
|
||||||
return '***';
|
return '***';
|
||||||
|
@ -16,6 +16,7 @@ use Psr\Container\ContainerInterface;
|
|||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\RequestStack;
|
use Symfony\Component\HttpFoundation\RequestStack;
|
||||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\NullToken;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\UsageTrackingTokenStorage;
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\UsageTrackingTokenStorage;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
@ -46,7 +47,7 @@ class UsageTrackingTokenStorageTest extends TestCase
|
|||||||
$trackingStorage = new UsageTrackingTokenStorage($tokenStorage, $sessionLocator);
|
$trackingStorage = new UsageTrackingTokenStorage($tokenStorage, $sessionLocator);
|
||||||
|
|
||||||
$this->assertNull($trackingStorage->getToken());
|
$this->assertNull($trackingStorage->getToken());
|
||||||
$token = $this->createMock(TokenInterface::class);
|
$token = new NullToken();
|
||||||
|
|
||||||
$trackingStorage->setToken($token);
|
$trackingStorage->setToken($token);
|
||||||
$this->assertSame($token, $trackingStorage->getToken());
|
$this->assertSame($token, $trackingStorage->getToken());
|
||||||
|
@ -26,7 +26,7 @@ class SwitchUserTokenTest extends TestCase
|
|||||||
$unserializedToken = unserialize(serialize($token));
|
$unserializedToken = unserialize(serialize($token));
|
||||||
|
|
||||||
$this->assertInstanceOf(SwitchUserToken::class, $unserializedToken);
|
$this->assertInstanceOf(SwitchUserToken::class, $unserializedToken);
|
||||||
$this->assertSame('admin', $unserializedToken->getUsername());
|
$this->assertSame('admin', $unserializedToken->getUserIdentifier());
|
||||||
$this->assertSame('bar', $unserializedToken->getCredentials());
|
$this->assertSame('bar', $unserializedToken->getCredentials());
|
||||||
$this->assertSame('provider-key', $unserializedToken->getFirewallName());
|
$this->assertSame('provider-key', $unserializedToken->getFirewallName());
|
||||||
$this->assertEquals(['ROLE_USER'], $unserializedToken->getRoleNames());
|
$this->assertEquals(['ROLE_USER'], $unserializedToken->getRoleNames());
|
||||||
@ -35,7 +35,7 @@ class SwitchUserTokenTest extends TestCase
|
|||||||
$unserializedOriginalToken = $unserializedToken->getOriginalToken();
|
$unserializedOriginalToken = $unserializedToken->getOriginalToken();
|
||||||
|
|
||||||
$this->assertInstanceOf(UsernamePasswordToken::class, $unserializedOriginalToken);
|
$this->assertInstanceOf(UsernamePasswordToken::class, $unserializedOriginalToken);
|
||||||
$this->assertSame('user', $unserializedOriginalToken->getUsername());
|
$this->assertSame('user', $unserializedOriginalToken->getUserIdentifier());
|
||||||
$this->assertSame('foo', $unserializedOriginalToken->getCredentials());
|
$this->assertSame('foo', $unserializedOriginalToken->getCredentials());
|
||||||
$this->assertSame('provider-key', $unserializedOriginalToken->getFirewallName());
|
$this->assertSame('provider-key', $unserializedOriginalToken->getFirewallName());
|
||||||
$this->assertEquals(['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'], $unserializedOriginalToken->getRoleNames());
|
$this->assertEquals(['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'], $unserializedOriginalToken->getRoleNames());
|
||||||
@ -49,6 +49,11 @@ class SwitchUserTokenTest extends TestCase
|
|||||||
return 'impersonated';
|
return 'impersonated';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getUserIdentifier()
|
||||||
|
{
|
||||||
|
return 'impersonated';
|
||||||
|
}
|
||||||
|
|
||||||
public function getPassword()
|
public function getPassword()
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@ -92,7 +97,7 @@ class SwitchUserTokenTest extends TestCase
|
|||||||
|
|
||||||
self::assertInstanceOf(SwitchUserToken::class, $token);
|
self::assertInstanceOf(SwitchUserToken::class, $token);
|
||||||
self::assertInstanceOf(UsernamePasswordToken::class, $token->getOriginalToken());
|
self::assertInstanceOf(UsernamePasswordToken::class, $token->getOriginalToken());
|
||||||
self::assertSame('john', $token->getUsername());
|
self::assertSame('john', $token->getUserIdentifier());
|
||||||
self::assertSame(['foo' => 'bar'], $token->getCredentials());
|
self::assertSame(['foo' => 'bar'], $token->getCredentials());
|
||||||
self::assertSame('main', $token->getFirewallName());
|
self::assertSame('main', $token->getFirewallName());
|
||||||
self::assertEquals(['ROLE_USER'], $token->getRoleNames());
|
self::assertEquals(['ROLE_USER'], $token->getRoleNames());
|
||||||
|
@ -213,6 +213,10 @@ class SomeUser implements UserInterface
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getUserIdentifier(): string
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public function eraseCredentials()
|
public function eraseCredentials()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Security\Core\Tests\Exception;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
|
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
||||||
|
|
||||||
|
class UserNotFoundExceptionTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testGetMessageData()
|
||||||
|
{
|
||||||
|
$exception = new UserNotFoundException('Username could not be found.');
|
||||||
|
$this->assertEquals(['{{ username }}' => null, '{{ user_identifier }}' => null], $exception->getMessageData());
|
||||||
|
$exception->setUserIdentifier('username');
|
||||||
|
$this->assertEquals(['{{ username }}' => 'username', '{{ user_identifier }}' => 'username'], $exception->getMessageData());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
|
public function testUsernameNotFoundException()
|
||||||
|
{
|
||||||
|
$exception = new UsernameNotFoundException();
|
||||||
|
$this->assertInstanceOf(UserNotFoundException::class, $exception);
|
||||||
|
|
||||||
|
$exception->setUsername('username');
|
||||||
|
$this->assertEquals('username', $exception->getUserIdentifier());
|
||||||
|
}
|
||||||
|
}
|
@ -1,26 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of the Symfony package.
|
|
||||||
*
|
|
||||||
* (c) Fabien Potencier <fabien@symfony.com>
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Symfony\Component\Security\Core\Tests\Exception;
|
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
|
||||||
|
|
||||||
class UsernameNotFoundExceptionTest extends TestCase
|
|
||||||
{
|
|
||||||
public function testGetMessageData()
|
|
||||||
{
|
|
||||||
$exception = new UsernameNotFoundException('Username could not be found.');
|
|
||||||
$this->assertEquals(['{{ username }}' => null], $exception->getMessageData());
|
|
||||||
$exception->setUsername('username');
|
|
||||||
$this->assertEquals(['{{ username }}' => 'username'], $exception->getMessageData());
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,9 +13,10 @@ namespace Symfony\Component\Security\Core\Tests\User;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
use Symfony\Component\Security\Core\User\ChainUserProvider;
|
use Symfony\Component\Security\Core\User\ChainUserProvider;
|
||||||
use Symfony\Component\Security\Core\User\InMemoryUser;
|
use Symfony\Component\Security\Core\User\InMemoryUser;
|
||||||
|
use Symfony\Component\Security\Core\User\InMemoryUserProvider;
|
||||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||||
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
@ -25,59 +26,59 @@ class ChainUserProviderTest extends TestCase
|
|||||||
{
|
{
|
||||||
public function testLoadUserByUsername()
|
public function testLoadUserByUsername()
|
||||||
{
|
{
|
||||||
$provider1 = $this->createMock(UserProviderInterface::class);
|
$provider1 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider1
|
$provider1
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('loadUserByUsername')
|
->method('loadUserByIdentifier')
|
||||||
->with($this->equalTo('foo'))
|
->with($this->equalTo('foo'))
|
||||||
->willThrowException(new UsernameNotFoundException('not found'))
|
->willThrowException(new UserNotFoundException('not found'))
|
||||||
;
|
;
|
||||||
|
|
||||||
$provider2 = $this->createMock(UserProviderInterface::class);
|
$provider2 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider2
|
$provider2
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('loadUserByUsername')
|
->method('loadUserByIdentifier')
|
||||||
->with($this->equalTo('foo'))
|
->with($this->equalTo('foo'))
|
||||||
->willReturn($account = $this->createMock(UserInterface::class))
|
->willReturn($account = $this->createMock(UserInterface::class))
|
||||||
;
|
;
|
||||||
|
|
||||||
$provider = new ChainUserProvider([$provider1, $provider2]);
|
$provider = new ChainUserProvider([$provider1, $provider2]);
|
||||||
$this->assertSame($account, $provider->loadUserByUsername('foo'));
|
$this->assertSame($account, $provider->loadUserByIdentifier('foo'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadUserByUsernameThrowsUsernameNotFoundException()
|
public function testLoadUserByUsernameThrowsUserNotFoundException()
|
||||||
{
|
{
|
||||||
$this->expectException(UsernameNotFoundException::class);
|
$this->expectException(UserNotFoundException::class);
|
||||||
$provider1 = $this->createMock(UserProviderInterface::class);
|
$provider1 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider1
|
$provider1
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('loadUserByUsername')
|
->method('loadUserByIdentifier')
|
||||||
->with($this->equalTo('foo'))
|
->with($this->equalTo('foo'))
|
||||||
->willThrowException(new UsernameNotFoundException('not found'))
|
->willThrowException(new UserNotFoundException('not found'))
|
||||||
;
|
;
|
||||||
|
|
||||||
$provider2 = $this->createMock(UserProviderInterface::class);
|
$provider2 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider2
|
$provider2
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('loadUserByUsername')
|
->method('loadUserByIdentifier')
|
||||||
->with($this->equalTo('foo'))
|
->with($this->equalTo('foo'))
|
||||||
->willThrowException(new UsernameNotFoundException('not found'))
|
->willThrowException(new UserNotFoundException('not found'))
|
||||||
;
|
;
|
||||||
|
|
||||||
$provider = new ChainUserProvider([$provider1, $provider2]);
|
$provider = new ChainUserProvider([$provider1, $provider2]);
|
||||||
$provider->loadUserByUsername('foo');
|
$provider->loadUserByIdentifier('foo');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRefreshUser()
|
public function testRefreshUser()
|
||||||
{
|
{
|
||||||
$provider1 = $this->createMock(UserProviderInterface::class);
|
$provider1 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider1
|
$provider1
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('supportsClass')
|
->method('supportsClass')
|
||||||
->willReturn(false)
|
->willReturn(false)
|
||||||
;
|
;
|
||||||
|
|
||||||
$provider2 = $this->createMock(UserProviderInterface::class);
|
$provider2 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider2
|
$provider2
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('supportsClass')
|
->method('supportsClass')
|
||||||
@ -90,7 +91,7 @@ class ChainUserProviderTest extends TestCase
|
|||||||
->willThrowException(new UnsupportedUserException('unsupported'))
|
->willThrowException(new UnsupportedUserException('unsupported'))
|
||||||
;
|
;
|
||||||
|
|
||||||
$provider3 = $this->createMock(UserProviderInterface::class);
|
$provider3 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider3
|
$provider3
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('supportsClass')
|
->method('supportsClass')
|
||||||
@ -109,7 +110,7 @@ class ChainUserProviderTest extends TestCase
|
|||||||
|
|
||||||
public function testRefreshUserAgain()
|
public function testRefreshUserAgain()
|
||||||
{
|
{
|
||||||
$provider1 = $this->createMock(UserProviderInterface::class);
|
$provider1 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider1
|
$provider1
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('supportsClass')
|
->method('supportsClass')
|
||||||
@ -119,10 +120,10 @@ class ChainUserProviderTest extends TestCase
|
|||||||
$provider1
|
$provider1
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('refreshUser')
|
->method('refreshUser')
|
||||||
->willThrowException(new UsernameNotFoundException('not found'))
|
->willThrowException(new UserNotFoundException('not found'))
|
||||||
;
|
;
|
||||||
|
|
||||||
$provider2 = $this->createMock(UserProviderInterface::class);
|
$provider2 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider2
|
$provider2
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('supportsClass')
|
->method('supportsClass')
|
||||||
@ -142,7 +143,7 @@ class ChainUserProviderTest extends TestCase
|
|||||||
public function testRefreshUserThrowsUnsupportedUserException()
|
public function testRefreshUserThrowsUnsupportedUserException()
|
||||||
{
|
{
|
||||||
$this->expectException(UnsupportedUserException::class);
|
$this->expectException(UnsupportedUserException::class);
|
||||||
$provider1 = $this->createMock(UserProviderInterface::class);
|
$provider1 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider1
|
$provider1
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('supportsClass')
|
->method('supportsClass')
|
||||||
@ -155,7 +156,7 @@ class ChainUserProviderTest extends TestCase
|
|||||||
->willThrowException(new UnsupportedUserException('unsupported'))
|
->willThrowException(new UnsupportedUserException('unsupported'))
|
||||||
;
|
;
|
||||||
|
|
||||||
$provider2 = $this->createMock(UserProviderInterface::class);
|
$provider2 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider2
|
$provider2
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('supportsClass')
|
->method('supportsClass')
|
||||||
@ -174,7 +175,7 @@ class ChainUserProviderTest extends TestCase
|
|||||||
|
|
||||||
public function testSupportsClass()
|
public function testSupportsClass()
|
||||||
{
|
{
|
||||||
$provider1 = $this->createMock(UserProviderInterface::class);
|
$provider1 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider1
|
$provider1
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('supportsClass')
|
->method('supportsClass')
|
||||||
@ -182,7 +183,7 @@ class ChainUserProviderTest extends TestCase
|
|||||||
->willReturn(false)
|
->willReturn(false)
|
||||||
;
|
;
|
||||||
|
|
||||||
$provider2 = $this->createMock(UserProviderInterface::class);
|
$provider2 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider2
|
$provider2
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('supportsClass')
|
->method('supportsClass')
|
||||||
@ -196,7 +197,7 @@ class ChainUserProviderTest extends TestCase
|
|||||||
|
|
||||||
public function testSupportsClassWhenNotSupported()
|
public function testSupportsClassWhenNotSupported()
|
||||||
{
|
{
|
||||||
$provider1 = $this->createMock(UserProviderInterface::class);
|
$provider1 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider1
|
$provider1
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('supportsClass')
|
->method('supportsClass')
|
||||||
@ -204,7 +205,7 @@ class ChainUserProviderTest extends TestCase
|
|||||||
->willReturn(false)
|
->willReturn(false)
|
||||||
;
|
;
|
||||||
|
|
||||||
$provider2 = $this->createMock(UserProviderInterface::class);
|
$provider2 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider2
|
$provider2
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('supportsClass')
|
->method('supportsClass')
|
||||||
@ -218,7 +219,7 @@ class ChainUserProviderTest extends TestCase
|
|||||||
|
|
||||||
public function testAcceptsTraversable()
|
public function testAcceptsTraversable()
|
||||||
{
|
{
|
||||||
$provider1 = $this->createMock(UserProviderInterface::class);
|
$provider1 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider1
|
$provider1
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('supportsClass')
|
->method('supportsClass')
|
||||||
@ -231,7 +232,7 @@ class ChainUserProviderTest extends TestCase
|
|||||||
->willThrowException(new UnsupportedUserException('unsupported'))
|
->willThrowException(new UnsupportedUserException('unsupported'))
|
||||||
;
|
;
|
||||||
|
|
||||||
$provider2 = $this->createMock(UserProviderInterface::class);
|
$provider2 = $this->createMock(InMemoryUserProvider::class);
|
||||||
$provider2
|
$provider2
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('supportsClass')
|
->method('supportsClass')
|
||||||
|
@ -13,7 +13,7 @@ namespace Symfony\Component\Security\Core\Tests\User;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
|
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
use Symfony\Component\Security\Core\User\InMemoryUser;
|
use Symfony\Component\Security\Core\User\InMemoryUser;
|
||||||
use Symfony\Component\Security\Core\User\InMemoryUserProvider;
|
use Symfony\Component\Security\Core\User\InMemoryUserProvider;
|
||||||
use Symfony\Component\Security\Core\User\User;
|
use Symfony\Component\Security\Core\User\User;
|
||||||
@ -26,7 +26,7 @@ class InMemoryUserProviderTest extends TestCase
|
|||||||
{
|
{
|
||||||
$provider = $this->createProvider();
|
$provider = $this->createProvider();
|
||||||
|
|
||||||
$user = $provider->loadUserByUsername('fabien');
|
$user = $provider->loadUserByIdentifier('fabien');
|
||||||
$this->assertEquals('foo', $user->getPassword());
|
$this->assertEquals('foo', $user->getPassword());
|
||||||
$this->assertEquals(['ROLE_USER'], $user->getRoles());
|
$this->assertEquals(['ROLE_USER'], $user->getRoles());
|
||||||
$this->assertFalse($user->isEnabled());
|
$this->assertFalse($user->isEnabled());
|
||||||
@ -76,7 +76,7 @@ class InMemoryUserProviderTest extends TestCase
|
|||||||
$provider = new InMemoryUserProvider();
|
$provider = new InMemoryUserProvider();
|
||||||
$provider->createUser(new InMemoryUser('fabien', 'foo'));
|
$provider->createUser(new InMemoryUser('fabien', 'foo'));
|
||||||
|
|
||||||
$user = $provider->loadUserByUsername('fabien');
|
$user = $provider->loadUserByIdentifier('fabien');
|
||||||
$this->assertEquals('foo', $user->getPassword());
|
$this->assertEquals('foo', $user->getPassword());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,8 +90,8 @@ class InMemoryUserProviderTest extends TestCase
|
|||||||
|
|
||||||
public function testLoadUserByUsernameDoesNotExist()
|
public function testLoadUserByUsernameDoesNotExist()
|
||||||
{
|
{
|
||||||
$this->expectException(UsernameNotFoundException::class);
|
$this->expectException(UserNotFoundException::class);
|
||||||
$provider = new InMemoryUserProvider();
|
$provider = new InMemoryUserProvider();
|
||||||
$provider->loadUserByUsername('fabien');
|
$provider->loadUserByIdentifier('fabien');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,15 @@
|
|||||||
namespace Symfony\Component\Security\Core\Tests\User;
|
namespace Symfony\Component\Security\Core\Tests\User;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
|
||||||
use Symfony\Component\Security\Core\User\EquatableInterface;
|
use Symfony\Component\Security\Core\User\EquatableInterface;
|
||||||
use Symfony\Component\Security\Core\User\InMemoryUser;
|
use Symfony\Component\Security\Core\User\InMemoryUser;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
|
|
||||||
class InMemoryUserTest extends TestCase
|
class InMemoryUserTest extends TestCase
|
||||||
{
|
{
|
||||||
|
use ExpectDeprecationTrait;
|
||||||
|
|
||||||
public function testConstructorException()
|
public function testConstructorException()
|
||||||
{
|
{
|
||||||
$this->expectException(\InvalidArgumentException::class);
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
@ -39,12 +42,23 @@ class InMemoryUserTest extends TestCase
|
|||||||
$this->assertEquals('superpass', $user->getPassword());
|
$this->assertEquals('superpass', $user->getPassword());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testGetUsername()
|
public function testGetUsername()
|
||||||
{
|
{
|
||||||
$user = new InMemoryUser('fabien', 'superpass');
|
$user = new InMemoryUser('fabien', 'superpass');
|
||||||
|
|
||||||
|
$this->expectDeprecation('Since symfony/security-core 5.3: Method "Symfony\Component\Security\Core\User\User::getUsername()" is deprecated, use getUserIdentifier() instead.');
|
||||||
$this->assertEquals('fabien', $user->getUsername());
|
$this->assertEquals('fabien', $user->getUsername());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetUserIdentifier()
|
||||||
|
{
|
||||||
|
$user = new InMemoryUser('fabien', 'superpass');
|
||||||
|
$this->assertEquals('fabien', $user->getUserIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
public function testGetSalt()
|
public function testGetSalt()
|
||||||
{
|
{
|
||||||
$user = new InMemoryUser('fabien', 'superpass');
|
$user = new InMemoryUser('fabien', 'superpass');
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\Security\Core\Tests\User;
|
namespace Symfony\Component\Security\Core\Tests\User;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
|
||||||
use Symfony\Component\Security\Core\User\EquatableInterface;
|
use Symfony\Component\Security\Core\User\EquatableInterface;
|
||||||
use Symfony\Component\Security\Core\User\User;
|
use Symfony\Component\Security\Core\User\User;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
@ -21,6 +22,8 @@ use Symfony\Component\Security\Core\User\UserInterface;
|
|||||||
*/
|
*/
|
||||||
class UserTest extends TestCase
|
class UserTest extends TestCase
|
||||||
{
|
{
|
||||||
|
use ExpectDeprecationTrait;
|
||||||
|
|
||||||
public function testConstructorException()
|
public function testConstructorException()
|
||||||
{
|
{
|
||||||
$this->expectException(\InvalidArgumentException::class);
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
@ -42,12 +45,23 @@ class UserTest extends TestCase
|
|||||||
$this->assertEquals('superpass', $user->getPassword());
|
$this->assertEquals('superpass', $user->getPassword());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testGetUsername()
|
public function testGetUsername()
|
||||||
{
|
{
|
||||||
$user = new User('fabien', 'superpass');
|
$user = new User('fabien', 'superpass');
|
||||||
|
|
||||||
|
$this->expectDeprecation('Since symfony/security-core 5.3: Method "Symfony\Component\Security\Core\User\User::getUsername()" is deprecated, use getUserIdentifier() instead.');
|
||||||
$this->assertEquals('fabien', $user->getUsername());
|
$this->assertEquals('fabien', $user->getUsername());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetUserIdentifier()
|
||||||
|
{
|
||||||
|
$user = new User('fabien', 'superpass');
|
||||||
|
$this->assertEquals('fabien', $user->getUserIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
public function testGetSalt()
|
public function testGetSalt()
|
||||||
{
|
{
|
||||||
$user = new User('fabien', 'superpass');
|
$user = new User('fabien', 'superpass');
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
namespace Symfony\Component\Security\Core\User;
|
namespace Symfony\Component\Security\Core\User;
|
||||||
|
|
||||||
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chain User Provider.
|
* Chain User Provider.
|
||||||
@ -50,17 +50,31 @@ class ChainUserProvider implements UserProviderInterface, PasswordUpgraderInterf
|
|||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function loadUserByUsername(string $username)
|
public function loadUserByUsername(string $username)
|
||||||
|
{
|
||||||
|
trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use loadUserByIdentifier() instead.', __METHOD__);
|
||||||
|
|
||||||
|
return $this->loadUserByIdentifier($username);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadUserByIdentifier(string $userIdentifier): UserInterface
|
||||||
{
|
{
|
||||||
foreach ($this->providers as $provider) {
|
foreach ($this->providers as $provider) {
|
||||||
try {
|
try {
|
||||||
return $provider->loadUserByUsername($username);
|
// @deprecated since 5.3, change to $provider->loadUserByIdentifier() in 6.0
|
||||||
} catch (UsernameNotFoundException $e) {
|
if (!method_exists($provider, 'loadUserByIdentifier')) {
|
||||||
|
trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', \get_debug_type($provider));
|
||||||
|
|
||||||
|
return $provider->loadUserByUsername($userIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $provider->loadUserByIdentifier($userIdentifier);
|
||||||
|
} catch (UserNotFoundException $e) {
|
||||||
// try next one
|
// try next one
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$ex = new UsernameNotFoundException(sprintf('There is no user with name "%s".', $username));
|
$ex = new UserNotFoundException(sprintf('There is no user with identifier "%s".', $userIdentifier));
|
||||||
$ex->setUsername($username);
|
$ex->setUserIdentifier($userIdentifier);
|
||||||
throw $ex;
|
throw $ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,15 +94,17 @@ class ChainUserProvider implements UserProviderInterface, PasswordUpgraderInterf
|
|||||||
return $provider->refreshUser($user);
|
return $provider->refreshUser($user);
|
||||||
} catch (UnsupportedUserException $e) {
|
} catch (UnsupportedUserException $e) {
|
||||||
// try next one
|
// try next one
|
||||||
} catch (UsernameNotFoundException $e) {
|
} catch (UserNotFoundException $e) {
|
||||||
$supportedUserFound = true;
|
$supportedUserFound = true;
|
||||||
// try next one
|
// try next one
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($supportedUserFound) {
|
if ($supportedUserFound) {
|
||||||
$e = new UsernameNotFoundException(sprintf('There is no user with name "%s".', $user->getUsername()));
|
// @deprecated since 5.3, change to $user->getUserIdentifier() in 6.0
|
||||||
$e->setUsername($user->getUsername());
|
$username = method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername();
|
||||||
|
$e = new UserNotFoundException(sprintf('There is no user with name "%s".', $username));
|
||||||
|
$e->setUserIdentifier($username);
|
||||||
throw $e;
|
throw $e;
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedUserException(sprintf('There is no user provider for user "%s". Shouldn\'t the "supportsClass()" method of your user provider return true for this classname?', get_debug_type($user)));
|
throw new UnsupportedUserException(sprintf('There is no user provider for user "%s". Shouldn\'t the "supportsClass()" method of your user provider return true for this classname?', get_debug_type($user)));
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
namespace Symfony\Component\Security\Core\User;
|
namespace Symfony\Component\Security\Core\User;
|
||||||
|
|
||||||
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* InMemoryUserProvider is a simple non persistent user provider.
|
* InMemoryUserProvider is a simple non persistent user provider.
|
||||||
@ -51,11 +51,13 @@ class InMemoryUserProvider implements UserProviderInterface
|
|||||||
*/
|
*/
|
||||||
public function createUser(UserInterface $user)
|
public function createUser(UserInterface $user)
|
||||||
{
|
{
|
||||||
if (isset($this->users[strtolower($user->getUsername())])) {
|
// @deprecated since 5.3, change to $user->getUserIdentifier() in 6.0
|
||||||
|
$userIdentifier = strtolower(method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername());
|
||||||
|
if (isset($this->users[$userIdentifier])) {
|
||||||
throw new \LogicException('Another user with the same username already exists.');
|
throw new \LogicException('Another user with the same username already exists.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->users[strtolower($user->getUsername())] = $user;
|
$this->users[$userIdentifier] = $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,9 +65,17 @@ class InMemoryUserProvider implements UserProviderInterface
|
|||||||
*/
|
*/
|
||||||
public function loadUserByUsername(string $username)
|
public function loadUserByUsername(string $username)
|
||||||
{
|
{
|
||||||
$user = $this->getUser($username);
|
trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use loadUserByIdentifier() instead.', __METHOD__);
|
||||||
|
|
||||||
return new InMemoryUser($user->getUsername(), $user->getPassword(), $user->getRoles(), $user->isEnabled());
|
return $this->loadUserByIdentifier($username);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadUserByIdentifier(string $identifier): UserInterface
|
||||||
|
{
|
||||||
|
$user = $this->getUser($identifier);
|
||||||
|
|
||||||
|
// @deprecated since 5.3, change to $user->getUserIdentifier() in 6.0
|
||||||
|
return new InMemoryUser(method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername(), $user->getPassword(), $user->getRoles(), $user->isEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,7 +87,9 @@ class InMemoryUserProvider implements UserProviderInterface
|
|||||||
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_debug_type($user)));
|
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_debug_type($user)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$storedUser = $this->getUser($user->getUsername());
|
// @deprecated since 5.3, change to $user->getUserIdentifier() in 6.0
|
||||||
|
$storedUser = $this->getUser(method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername());
|
||||||
|
$userIdentifier = method_exists($storedUser, 'getUserIdentifier') ? $storedUser->getUserIdentifier() : $storedUser->getUsername();
|
||||||
|
|
||||||
// @deprecated since Symfony 5.3
|
// @deprecated since Symfony 5.3
|
||||||
if (User::class === \get_class($user)) {
|
if (User::class === \get_class($user)) {
|
||||||
@ -91,10 +103,10 @@ class InMemoryUserProvider implements UserProviderInterface
|
|||||||
$accountNonLocked = $storedUser->isAccountNonLocked();
|
$accountNonLocked = $storedUser->isAccountNonLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new User($storedUser->getUsername(), $storedUser->getPassword(), $storedUser->getRoles(), $storedUser->isEnabled(), $accountNonExpired, $credentialsNonExpired, $accountNonLocked);
|
return new User($userIdentifier, $storedUser->getPassword(), $storedUser->getRoles(), $storedUser->isEnabled(), $accountNonExpired, $credentialsNonExpired, $accountNonLocked);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new InMemoryUser($storedUser->getUsername(), $storedUser->getPassword(), $storedUser->getRoles(), $storedUser->isEnabled());
|
return new InMemoryUser($userIdentifier, $storedUser->getPassword(), $storedUser->getRoles(), $storedUser->isEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,13 +125,13 @@ class InMemoryUserProvider implements UserProviderInterface
|
|||||||
/**
|
/**
|
||||||
* Returns the user by given username.
|
* Returns the user by given username.
|
||||||
*
|
*
|
||||||
* @throws UsernameNotFoundException if user whose given username does not exist
|
* @throws UserNotFoundException if user whose given username does not exist
|
||||||
*/
|
*/
|
||||||
private function getUser(string $username)/*: InMemoryUser */
|
private function getUser(string $username)/*: InMemoryUser */
|
||||||
{
|
{
|
||||||
if (!isset($this->users[strtolower($username)])) {
|
if (!isset($this->users[strtolower($username)])) {
|
||||||
$ex = new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));
|
$ex = new UserNotFoundException(sprintf('Username "%s" does not exist.', $username));
|
||||||
$ex->setUsername($username);
|
$ex->setUserIdentifier($username);
|
||||||
|
|
||||||
throw $ex;
|
throw $ex;
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,11 @@ class MissingUserProvider implements UserProviderInterface
|
|||||||
throw new \BadMethodCallException();
|
throw new \BadMethodCallException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function loadUserByIdentifier(string $identifier): UserInterface
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -53,7 +53,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface, Equatab
|
|||||||
|
|
||||||
public function __toString(): string
|
public function __toString(): string
|
||||||
{
|
{
|
||||||
return $this->getUsername();
|
return $this->getUserIdentifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,6 +84,16 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface, Equatab
|
|||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function getUsername(): string
|
public function getUsername(): string
|
||||||
|
{
|
||||||
|
trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use getUserIdentifier() instead.', __METHOD__);
|
||||||
|
|
||||||
|
return $this->username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the identifier for this user (e.g. its username or e-mailaddress).
|
||||||
|
*/
|
||||||
|
public function getUserIdentifier(): string
|
||||||
{
|
{
|
||||||
return $this->username;
|
return $this->username;
|
||||||
}
|
}
|
||||||
@ -184,7 +194,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface, Equatab
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->getUsername() !== $user->getUsername()) {
|
if ($this->getUserIdentifier() !== $user->getUserIdentifier()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ namespace Symfony\Component\Security\Core\User;
|
|||||||
*
|
*
|
||||||
* @see UserProviderInterface
|
* @see UserProviderInterface
|
||||||
*
|
*
|
||||||
|
* @method string getUserIdentifier() returns the identifier for this user (e.g. its username or e-mailaddress)
|
||||||
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
*/
|
*/
|
||||||
interface UserInterface
|
interface UserInterface
|
||||||
@ -69,13 +71,6 @@ interface UserInterface
|
|||||||
*/
|
*/
|
||||||
public function getSalt();
|
public function getSalt();
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the username used to authenticate the user.
|
|
||||||
*
|
|
||||||
* @return string The username
|
|
||||||
*/
|
|
||||||
public function getUsername();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes sensitive data from the user.
|
* Removes sensitive data from the user.
|
||||||
*
|
*
|
||||||
|
@ -12,16 +12,16 @@
|
|||||||
namespace Symfony\Component\Security\Core\User;
|
namespace Symfony\Component\Security\Core\User;
|
||||||
|
|
||||||
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a class that loads UserInterface objects from some source for the authentication system.
|
* Represents a class that loads UserInterface objects from some source for the authentication system.
|
||||||
*
|
*
|
||||||
* In a typical authentication configuration, a username (i.e. some unique
|
* In a typical authentication configuration, a user identifier (e.g. a
|
||||||
* user identifier) credential enters the system (via form login, or any
|
* username or e-mailaddress) credential enters the system (via form login, or
|
||||||
* method). The user provider that is configured with that authentication
|
* any method). The user provider that is configured with that authentication
|
||||||
* method is asked to load the UserInterface object for the given username
|
* method is asked to load the UserInterface object for the given identifier (via
|
||||||
* (via loadUserByUsername) so that the rest of the process can continue.
|
* loadUserByIdentifier) so that the rest of the process can continue.
|
||||||
*
|
*
|
||||||
* Internally, a user provider can load users from any source (databases,
|
* Internally, a user provider can load users from any source (databases,
|
||||||
* configuration, web service). This is totally independent of how the authentication
|
* configuration, web service). This is totally independent of how the authentication
|
||||||
@ -29,22 +29,13 @@ use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
|||||||
*
|
*
|
||||||
* @see UserInterface
|
* @see UserInterface
|
||||||
*
|
*
|
||||||
|
* @method UserInterface loadUserByIdentifier(string $identifier) loads the user for the given user identifier (e.g. username or email).
|
||||||
|
* This method must throw UserNotFoundException if the user is not found.
|
||||||
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
*/
|
*/
|
||||||
interface UserProviderInterface
|
interface UserProviderInterface
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Loads the user for the given username.
|
|
||||||
*
|
|
||||||
* This method must throw UsernameNotFoundException if the user is not
|
|
||||||
* found.
|
|
||||||
*
|
|
||||||
* @return UserInterface
|
|
||||||
*
|
|
||||||
* @throws UsernameNotFoundException if the user is not found
|
|
||||||
*/
|
|
||||||
public function loadUserByUsername(string $username);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refreshes the user.
|
* Refreshes the user.
|
||||||
*
|
*
|
||||||
@ -56,7 +47,7 @@ interface UserProviderInterface
|
|||||||
* @return UserInterface
|
* @return UserInterface
|
||||||
*
|
*
|
||||||
* @throws UnsupportedUserException if the user is not supported
|
* @throws UnsupportedUserException if the user is not supported
|
||||||
* @throws UsernameNotFoundException if the user is not found
|
* @throws UserNotFoundException if the user is not found
|
||||||
*/
|
*/
|
||||||
public function refreshUser(UserInterface $user);
|
public function refreshUser(UserInterface $user);
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ use Symfony\Component\HttpFoundation\Request;
|
|||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||||
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
@ -98,7 +98,7 @@ class GuardBridgeAuthenticator implements InteractiveAuthenticatorInterface, Aut
|
|||||||
$user = $this->guard->getUser($credentials, $this->userProvider);
|
$user = $this->guard->getUser($credentials, $this->userProvider);
|
||||||
|
|
||||||
if (null === $user) {
|
if (null === $user) {
|
||||||
throw new UsernameNotFoundException(sprintf('Null returned from "%s::getUser()".', get_debug_type($this->guard)));
|
throw new UserNotFoundException(sprintf('Null returned from "%s::getUser()".', get_debug_type($this->guard)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$user instanceof UserInterface) {
|
if (!$user instanceof UserInterface) {
|
||||||
|
@ -70,7 +70,7 @@ interface AuthenticatorInterface extends AuthenticationEntryPointInterface
|
|||||||
* The *credentials* are the return value from getCredentials()
|
* The *credentials* are the return value from getCredentials()
|
||||||
*
|
*
|
||||||
* You may throw an AuthenticationException if you wish. If you return
|
* You may throw an AuthenticationException if you wish. If you return
|
||||||
* null, then a UsernameNotFoundException is thrown for you.
|
* null, then a UserNotFoundException is thrown for you.
|
||||||
*
|
*
|
||||||
* @param mixed $credentials
|
* @param mixed $credentials
|
||||||
*
|
*
|
||||||
|
@ -18,7 +18,7 @@ use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
|
|||||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
use Symfony\Component\Security\Core\Exception\AuthenticationExpiredException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationExpiredException;
|
||||||
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||||
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
||||||
@ -112,8 +112,9 @@ class GuardAuthenticationProvider implements AuthenticationProviderInterface
|
|||||||
$user = $guardAuthenticator->getUser($token->getCredentials(), $this->userProvider);
|
$user = $guardAuthenticator->getUser($token->getCredentials(), $this->userProvider);
|
||||||
|
|
||||||
if (null === $user) {
|
if (null === $user) {
|
||||||
$e = new UsernameNotFoundException(sprintf('Null returned from "%s::getUser()".', get_debug_type($guardAuthenticator)));
|
$e = new UserNotFoundException(sprintf('Null returned from "%s::getUser()".', get_debug_type($guardAuthenticator)));
|
||||||
$e->setUsername($token->getUsername());
|
// @deprecated since 5.3, change to $token->getUserIdentifier() in 6.0
|
||||||
|
$e->setUserIdentifier(method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername());
|
||||||
|
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
use Symfony\Component\Security\Core\User\InMemoryUser;
|
use Symfony\Component\Security\Core\User\InMemoryUser;
|
||||||
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||||
use Symfony\Component\Security\Guard\Authenticator\GuardBridgeAuthenticator;
|
use Symfony\Component\Security\Guard\Authenticator\GuardBridgeAuthenticator;
|
||||||
@ -97,7 +97,7 @@ class GuardBridgeAuthenticatorTest extends TestCase
|
|||||||
|
|
||||||
public function testAuthenticateNoUser()
|
public function testAuthenticateNoUser()
|
||||||
{
|
{
|
||||||
$this->expectException(UsernameNotFoundException::class);
|
$this->expectException(UserNotFoundException::class);
|
||||||
|
|
||||||
$request = new Request();
|
$request = new Request();
|
||||||
|
|
||||||
|
@ -70,7 +70,8 @@ class AuthenticatorManager implements AuthenticatorManagerInterface, UserAuthent
|
|||||||
public function authenticateUser(UserInterface $user, AuthenticatorInterface $authenticator, Request $request, array $badges = []): ?Response
|
public function authenticateUser(UserInterface $user, AuthenticatorInterface $authenticator, Request $request, array $badges = []): ?Response
|
||||||
{
|
{
|
||||||
// create an authenticated token for the User
|
// create an authenticated token for the User
|
||||||
$token = $authenticator->createAuthenticatedToken($passport = new SelfValidatingPassport(new UserBadge($user->getUsername(), function () use ($user) { return $user; }), $badges), $this->firewallName);
|
// @deprecated since 5.3, change to $user->getUserIdentifier() in 6.0
|
||||||
|
$token = $authenticator->createAuthenticatedToken($passport = new SelfValidatingPassport(new UserBadge(method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername(), function () use ($user) { return $user; }), $badges), $this->firewallName);
|
||||||
|
|
||||||
// announce the authenticated token
|
// announce the authenticated token
|
||||||
$token = $this->eventDispatcher->dispatch(new AuthenticationTokenCreatedEvent($token))->getAuthenticatedToken();
|
$token = $this->eventDispatcher->dispatch(new AuthenticationTokenCreatedEvent($token))->getAuthenticatedToken();
|
||||||
@ -215,6 +216,11 @@ class AuthenticatorManager implements AuthenticatorManagerInterface, UserAuthent
|
|||||||
|
|
||||||
private function handleAuthenticationSuccess(TokenInterface $authenticatedToken, PassportInterface $passport, Request $request, AuthenticatorInterface $authenticator): ?Response
|
private function handleAuthenticationSuccess(TokenInterface $authenticatedToken, PassportInterface $passport, Request $request, AuthenticatorInterface $authenticator): ?Response
|
||||||
{
|
{
|
||||||
|
// @deprecated since 5.3
|
||||||
|
if (!method_exists($authenticatedToken->getUser(), 'getUserIdentifier')) {
|
||||||
|
trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "getUserIdentifier(): string" in user class "%s" is deprecated. This method will replace "getUsername()" in Symfony 6.0.', get_debug_type($authenticatedToken->getUser()));
|
||||||
|
}
|
||||||
|
|
||||||
$this->tokenStorage->setToken($authenticatedToken);
|
$this->tokenStorage->setToken($authenticatedToken);
|
||||||
|
|
||||||
$response = $authenticator->onAuthenticationSuccess($request, $authenticatedToken, $this->firewallName);
|
$response = $authenticator->onAuthenticationSuccess($request, $authenticatedToken, $this->firewallName);
|
||||||
|
@ -87,9 +87,18 @@ abstract class AbstractPreAuthenticatedAuthenticator implements InteractiveAuthe
|
|||||||
|
|
||||||
public function authenticate(Request $request): PassportInterface
|
public function authenticate(Request $request): PassportInterface
|
||||||
{
|
{
|
||||||
return new SelfValidatingPassport(new UserBadge($request->attributes->get('_pre_authenticated_username'), function ($username) {
|
// @deprecated since 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0
|
||||||
return $this->userProvider->loadUserByUsername($username);
|
$method = 'loadUserByIdentifier';
|
||||||
}), [new PreAuthenticatedUserBadge()]);
|
if (!method_exists($this->userProvider, 'loadUserByIdentifier')) {
|
||||||
|
trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider));
|
||||||
|
|
||||||
|
$method = 'loadUserByUsername';
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SelfValidatingPassport(
|
||||||
|
new UserBadge($request->attributes->get('_pre_authenticated_username'), [$this->userProvider, $method]),
|
||||||
|
[new PreAuthenticatedUserBadge()]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface
|
public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface
|
||||||
|
@ -46,7 +46,7 @@ interface AuthenticatorInterface
|
|||||||
* presented password and the CSRF token value.
|
* presented password and the CSRF token value.
|
||||||
*
|
*
|
||||||
* You may throw any AuthenticationException in this method in case of error (e.g.
|
* You may throw any AuthenticationException in this method in case of error (e.g.
|
||||||
* a UsernameNotFoundException when the user cannot be found).
|
* a UserNotFoundException when the user cannot be found).
|
||||||
*
|
*
|
||||||
* @throws AuthenticationException
|
* @throws AuthenticationException
|
||||||
*/
|
*/
|
||||||
|
@ -84,14 +84,19 @@ class FormLoginAuthenticator extends AbstractLoginFormAuthenticator
|
|||||||
{
|
{
|
||||||
$credentials = $this->getCredentials($request);
|
$credentials = $this->getCredentials($request);
|
||||||
|
|
||||||
$passport = new Passport(new UserBadge($credentials['username'], function ($username) {
|
// @deprecated since 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0
|
||||||
$user = $this->userProvider->loadUserByUsername($username);
|
$method = 'loadUserByIdentifier';
|
||||||
if (!$user instanceof UserInterface) {
|
if (!method_exists($this->userProvider, 'loadUserByIdentifier')) {
|
||||||
throw new AuthenticationServiceException('The user provider must return a UserInterface object.');
|
trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider));
|
||||||
|
|
||||||
|
$method = 'loadUserByUsername';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $user;
|
$passport = new Passport(
|
||||||
}), new PasswordCredentials($credentials['password']), [new RememberMeBadge()]);
|
new UserBadge($credentials['username'], [$this->userProvider, $method]),
|
||||||
|
new PasswordCredentials($credentials['password']),
|
||||||
|
[new RememberMeBadge()]
|
||||||
|
);
|
||||||
if ($this->options['enable_csrf']) {
|
if ($this->options['enable_csrf']) {
|
||||||
$passport->addBadge(new CsrfTokenBadge($this->options['csrf_token_id'], $credentials['csrf_token']));
|
$passport->addBadge(new CsrfTokenBadge($this->options['csrf_token_id'], $credentials['csrf_token']));
|
||||||
}
|
}
|
||||||
|
@ -67,14 +67,18 @@ class HttpBasicAuthenticator implements AuthenticatorInterface, AuthenticationEn
|
|||||||
$username = $request->headers->get('PHP_AUTH_USER');
|
$username = $request->headers->get('PHP_AUTH_USER');
|
||||||
$password = $request->headers->get('PHP_AUTH_PW', '');
|
$password = $request->headers->get('PHP_AUTH_PW', '');
|
||||||
|
|
||||||
$passport = new Passport(new UserBadge($username, function ($username) {
|
// @deprecated since 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0
|
||||||
$user = $this->userProvider->loadUserByUsername($username);
|
$method = 'loadUserByIdentifier';
|
||||||
if (!$user instanceof UserInterface) {
|
if (!method_exists($this->userProvider, 'loadUserByIdentifier')) {
|
||||||
throw new AuthenticationServiceException('The user provider must return a UserInterface object.');
|
trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider));
|
||||||
|
|
||||||
|
$method = 'loadUserByUsername';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $user;
|
$passport = new Passport(
|
||||||
}), new PasswordCredentials($password));
|
new UserBadge($username, [$this->userProvider, $method]),
|
||||||
|
new PasswordCredentials($password)
|
||||||
|
);
|
||||||
if ($this->userProvider instanceof PasswordUpgraderInterface) {
|
if ($this->userProvider instanceof PasswordUpgraderInterface) {
|
||||||
$passport->addBadge(new PasswordUpgradeBadge($password, $this->userProvider));
|
$passport->addBadge(new PasswordUpgradeBadge($password, $this->userProvider));
|
||||||
}
|
}
|
||||||
|
@ -94,14 +94,18 @@ class JsonLoginAuthenticator implements InteractiveAuthenticatorInterface
|
|||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
$passport = new Passport(new UserBadge($credentials['username'], function ($username) {
|
// @deprecated since 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0
|
||||||
$user = $this->userProvider->loadUserByUsername($username);
|
$method = 'loadUserByIdentifier';
|
||||||
if (!$user instanceof UserInterface) {
|
if (!method_exists($this->userProvider, 'loadUserByIdentifier')) {
|
||||||
throw new AuthenticationServiceException('The user provider must return a UserInterface object.');
|
trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider));
|
||||||
|
|
||||||
|
$method = 'loadUserByUsername';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $user;
|
$passport = new Passport(
|
||||||
}), new PasswordCredentials($credentials['password']));
|
new UserBadge($credentials['username'], [$this->userProvider, $method]),
|
||||||
|
new PasswordCredentials($credentials['password'])
|
||||||
|
);
|
||||||
if ($this->userProvider instanceof PasswordUpgraderInterface) {
|
if ($this->userProvider instanceof PasswordUpgraderInterface) {
|
||||||
$passport->addBadge(new PasswordUpgradeBadge($credentials['password'], $this->userProvider));
|
$passport->addBadge(new PasswordUpgradeBadge($credentials['password'], $this->userProvider));
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Security\Http\Authenticator\Passport\Badge;
|
namespace Symfony\Component\Security\Http\Authenticator\Passport\Badge;
|
||||||
|
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
use Symfony\Component\Security\Http\EventListener\UserProviderListener;
|
use Symfony\Component\Security\Http\EventListener\UserProviderListener;
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ class UserBadge implements BadgeInterface
|
|||||||
* based on email *and* company name). This string can be used for e.g. login throttling.
|
* based on email *and* company name). This string can be used for e.g. login throttling.
|
||||||
*
|
*
|
||||||
* Optionally, you may pass a user loader. This callable receives the $userIdentifier
|
* Optionally, you may pass a user loader. This callable receives the $userIdentifier
|
||||||
* as argument and must return a UserInterface object (otherwise a UsernameNotFoundException
|
* as argument and must return a UserInterface object (otherwise an AuthenticationServiceException
|
||||||
* is thrown). If this is not set, the default user provider will be used with
|
* is thrown). If this is not set, the default user provider will be used with
|
||||||
* $userIdentifier as username.
|
* $userIdentifier as username.
|
||||||
*/
|
*/
|
||||||
@ -64,7 +64,7 @@ class UserBadge implements BadgeInterface
|
|||||||
|
|
||||||
$this->user = ($this->userLoader)($this->userIdentifier);
|
$this->user = ($this->userLoader)($this->userIdentifier);
|
||||||
if (!$this->user instanceof UserInterface) {
|
if (!$this->user instanceof UserInterface) {
|
||||||
throw new UsernameNotFoundException();
|
throw new AuthenticationServiceException(sprintf('The user provider must return a UserInterface object, "%s" given.', \get_debug_type($this->user)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,8 @@ class RememberMeAuthenticator implements InteractiveAuthenticatorInterface
|
|||||||
throw new \LogicException('No remember me token is set.');
|
throw new \LogicException('No remember me token is set.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SelfValidatingPassport(new UserBadge($token->getUsername(), [$token, 'getUser']));
|
// @deprecated since 5.3, change to $token->getUserIdentifier() in 6.0
|
||||||
|
return new SelfValidatingPassport(new UserBadge(method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername(), [$token, 'getUser']));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface
|
public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface
|
||||||
|
@ -46,6 +46,13 @@ class UserProviderListener
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @deprecated since 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0
|
||||||
|
if (method_exists($this->userProvider, 'loadUserByIdentifier')) {
|
||||||
|
$badge->setUserLoader([$this->userProvider, 'loadUserByIdentifier']);
|
||||||
|
} else {
|
||||||
|
trigger_deprecation('symfony/security-http', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider));
|
||||||
|
|
||||||
$badge->setUserLoader([$this->userProvider, 'loadUserByUsername']);
|
$badge->setUserLoader([$this->userProvider, 'loadUserByUsername']);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,8 @@ abstract class AbstractAuthenticationListener extends AbstractListener
|
|||||||
private function onSuccess(Request $request, TokenInterface $token): Response
|
private function onSuccess(Request $request, TokenInterface $token): Response
|
||||||
{
|
{
|
||||||
if (null !== $this->logger) {
|
if (null !== $this->logger) {
|
||||||
$this->logger->info('User has been authenticated successfully.', ['username' => $token->getUsername()]);
|
// @deprecated since 5.3, change to $token->getUserIdentifier() in 6.0
|
||||||
|
$this->logger->info('User has been authenticated successfully.', ['username' => method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->tokenStorage->setToken($token);
|
$this->tokenStorage->setToken($token);
|
||||||
|
@ -83,7 +83,8 @@ abstract class AbstractPreAuthenticatedListener extends AbstractListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $token = $this->tokenStorage->getToken()) {
|
if (null !== $token = $this->tokenStorage->getToken()) {
|
||||||
if ($token instanceof PreAuthenticatedToken && $this->providerKey == $token->getFirewallName() && $token->isAuthenticated() && $token->getUsername() === $user) {
|
// @deprecated since 5.3, change to $token->getUserIdentifier() in 6.0
|
||||||
|
if ($token instanceof PreAuthenticatedToken && $this->providerKey == $token->getFirewallName() && $token->isAuthenticated() && (method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername()) === $user) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,8 @@ class BasicAuthenticationListener extends AbstractListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $token = $this->tokenStorage->getToken()) {
|
if (null !== $token = $this->tokenStorage->getToken()) {
|
||||||
if ($token instanceof UsernamePasswordToken && $token->isAuthenticated() && $token->getUsername() === $username) {
|
// @deprecated since 5.3, change to $token->getUserIdentifier() in 6.0
|
||||||
|
if ($token instanceof UsernamePasswordToken && $token->isAuthenticated() && (method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername()) === $username) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInt
|
|||||||
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
|
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
||||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||||
use Symfony\Component\Security\Http\Event\DeauthenticatedEvent;
|
use Symfony\Component\Security\Http\Event\DeauthenticatedEvent;
|
||||||
@ -222,7 +222,8 @@ class ContextListener extends AbstractListener
|
|||||||
$userDeauthenticated = true;
|
$userDeauthenticated = true;
|
||||||
|
|
||||||
if (null !== $this->logger) {
|
if (null !== $this->logger) {
|
||||||
$this->logger->debug('Cannot refresh token because user has changed.', ['username' => $refreshedUser->getUsername(), 'provider' => \get_class($provider)]);
|
// @deprecated since 5.3, change to $refreshedUser->getUserIdentifier() in 6.0
|
||||||
|
$this->logger->debug('Cannot refresh token because user has changed.', ['username' => method_exists($refreshedUser, 'getUserIdentifier') ? $refreshedUser->getUserIdentifier() : $refreshedUser->getUsername(), 'provider' => \get_class($provider)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -231,10 +232,12 @@ class ContextListener extends AbstractListener
|
|||||||
$token->setUser($refreshedUser);
|
$token->setUser($refreshedUser);
|
||||||
|
|
||||||
if (null !== $this->logger) {
|
if (null !== $this->logger) {
|
||||||
$context = ['provider' => \get_class($provider), 'username' => $refreshedUser->getUsername()];
|
// @deprecated since 5.3, change to $refreshedUser->getUserIdentifier() in 6.0
|
||||||
|
$context = ['provider' => \get_class($provider), 'username' => method_exists($refreshedUser, 'getUserIdentifier') ? $refreshedUser->getUserIdentifier() : $refreshedUser->getUsername()];
|
||||||
|
|
||||||
if ($token instanceof SwitchUserToken) {
|
if ($token instanceof SwitchUserToken) {
|
||||||
$context['impersonator_username'] = $token->getOriginalToken()->getUsername();
|
// @deprecated since 5.3, change to $token->getUserIdentifier() in 6.0
|
||||||
|
$context['impersonator_username'] = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getOriginalToken()->getUsername();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->logger->debug('User was reloaded from a user provider.', $context);
|
$this->logger->debug('User was reloaded from a user provider.', $context);
|
||||||
@ -243,9 +246,9 @@ class ContextListener extends AbstractListener
|
|||||||
return $token;
|
return $token;
|
||||||
} catch (UnsupportedUserException $e) {
|
} catch (UnsupportedUserException $e) {
|
||||||
// let's try the next user provider
|
// let's try the next user provider
|
||||||
} catch (UsernameNotFoundException $e) {
|
} catch (UserNotFoundException $e) {
|
||||||
if (null !== $this->logger) {
|
if (null !== $this->logger) {
|
||||||
$this->logger->warning('Username could not be found in the selected user provider.', ['username' => $e->getUsername(), 'provider' => \get_class($provider)]);
|
$this->logger->warning('Username could not be found in the selected user provider.', ['username' => method_exists($e, 'getUserIdentifier') ? $e->getUserIdentifier() : $e->getUsername(), 'provider' => \get_class($provider)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$userNotFoundByProvider = true;
|
$userNotFoundByProvider = true;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user