Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5efa892

Browse files
committed
Create a new core AuthenticatorInterface
This is an iteration on the AuthenticatorInterface of the Guard, to allow more flexibility so it can be used as a real replaced of the authentication providers and listeners.
1 parent 5013258 commit 5efa892

19 files changed

+379
-80
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory;
13+
14+
use Symfony\Component\DependencyInjection\ContainerBuilder;
15+
16+
/**
17+
* @author Wouter de Jong <[email protected]>
18+
*/
19+
interface EntryPointFactoryInterface
20+
{
21+
/**
22+
* Creates the entry point and returns the service ID.
23+
*/
24+
public function createEntryPoint(ContainerBuilder $container, string $id, array $config, ?string $defaultEntryPointId): string;
25+
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* @author Fabien Potencier <[email protected]>
2323
* @author Johannes M. Schmitt <[email protected]>
2424
*/
25-
class FormLoginFactory extends AbstractFactory implements GuardFactoryInterface
25+
class FormLoginFactory extends AbstractFactory implements GuardFactoryInterface, EntryPointFactoryInterface
2626
{
2727
public function __construct()
2828
{
@@ -84,7 +84,7 @@ protected function createListener(ContainerBuilder $container, string $id, array
8484
return $listenerId;
8585
}
8686

87-
protected function createEntryPoint(ContainerBuilder $container, string $id, array $config, ?string $defaultEntryPoint)
87+
public function createEntryPoint(ContainerBuilder $container, string $id, array $config, ?string $defaultEntryPoint): string
8888
{
8989
$entryPointId = 'security.authentication.form_entry_point.'.$id;
9090
$container
@@ -105,7 +105,8 @@ public function createGuard(ContainerBuilder $container, string $id, array $conf
105105
$container
106106
->setDefinition($authenticatorId, new ChildDefinition('security.authenticator.form_login'))
107107
->replaceArgument(1, isset($config['csrf_token_generator']) ? new Reference($config['csrf_token_generator']) : null)
108-
->replaceArgument(3, $options);
108+
->replaceArgument(2, new Reference($userProviderId))
109+
->replaceArgument(4, $options);
109110

110111
return $authenticatorId;
111112
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\SecurityBundle\DependencyInjection;
1313

14+
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\EntryPointFactoryInterface;
1415
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\GuardFactoryInterface;
1516
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\RememberMeFactory;
1617
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface;
@@ -516,6 +517,10 @@ private function createAuthenticationListeners(ContainerBuilder $container, stri
516517
} else {
517518
$authenticationProviders[$id.'_'.$key] = $authenticators;
518519
}
520+
521+
if ($factory instanceof EntryPointFactoryInterface) {
522+
$defaultEntryPoint = $factory->createEntryPoint($container, $id, $firewall[$key], $defaultEntryPoint);
523+
}
519524
} else {
520525
list($provider, $listenerId, $defaultEntryPoint) = $factory->create($container, $id, $firewall[$key], $userProvider, $defaultEntryPoint);
521526

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
abstract="true">
3434
<argument type="service" id="security.http_utils" />
3535
<argument /> <!-- csrf token generator -->
36+
<argument type="abstract">user provider</argument>
3637
<argument type="service" id="security.encoder_factory" />
3738
<argument type="abstract">options</argument>
3839
</service>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Core\Authentication\Authenticator;
13+
14+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
15+
use Symfony\Component\Security\Core\User\UserInterface;
16+
use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
17+
18+
/**
19+
* An optional base class that creates the necessary tokens for you.
20+
*
21+
* @author Ryan Weaver <[email protected]>
22+
*/
23+
abstract class AbstractAuthenticator implements AuthenticatorInterface
24+
{
25+
/**
26+
* Shortcut to create a PostAuthenticationGuardToken for you, if you don't really
27+
* care about which authenticated token you're using.
28+
*
29+
* @return PostAuthenticationGuardToken
30+
*/
31+
public function createAuthenticatedToken(UserInterface $user, string $providerKey): TokenInterface
32+
{
33+
return new PostAuthenticationGuardToken($user, $providerKey, $user->getRoles());
34+
}
35+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Core\Authentication\Authenticator;
13+
14+
use Symfony\Component\HttpFoundation\RedirectResponse;
15+
use Symfony\Component\HttpFoundation\Request;
16+
use Symfony\Component\HttpFoundation\Response;
17+
use Symfony\Component\Security\Core\Exception\AuthenticationException;
18+
use Symfony\Component\Security\Core\Security;
19+
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
20+
21+
/**
22+
* A base class to make form login authentication easier!
23+
*
24+
* @author Ryan Weaver <[email protected]>
25+
*/
26+
abstract class AbstractFormLoginAuthenticator extends AbstractAuthenticator implements AuthenticationEntryPointInterface
27+
{
28+
/**
29+
* Return the URL to the login page.
30+
*/
31+
abstract protected function getLoginUrl(): string;
32+
33+
/**
34+
* Override to change what happens after a bad username/password is submitted.
35+
*/
36+
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): Response
37+
{
38+
if ($request->hasSession()) {
39+
$request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
40+
}
41+
42+
$url = $this->getLoginUrl();
43+
44+
return new RedirectResponse($url);
45+
}
46+
47+
public function supportsRememberMe(): bool
48+
{
49+
return true;
50+
}
51+
52+
/**
53+
* Override to control what happens when the user hits a secure page
54+
* but isn't logged in yet.
55+
*/
56+
public function start(Request $request, AuthenticationException $authException = null): Response
57+
{
58+
$url = $this->getLoginUrl();
59+
60+
return new RedirectResponse($url);
61+
}
62+
}

src/Symfony/Component/Security/Core/Authentication/Authenticator/AnonymousAuthenticator.php

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
<?php
22

3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
312
namespace Symfony\Component\Security\Core\Authentication\Authenticator;
413

514
use Symfony\Component\HttpFoundation\Request;
@@ -9,9 +18,6 @@
918
use Symfony\Component\Security\Core\Exception\AuthenticationException;
1019
use Symfony\Component\Security\Core\User\User;
1120
use Symfony\Component\Security\Core\User\UserInterface;
12-
use Symfony\Component\Security\Core\User\UserProviderInterface;
13-
use Symfony\Component\Security\Guard\AuthenticatorInterface;
14-
use Symfony\Component\Security\Guard\Token\GuardTokenInterface;
1521

1622
/**
1723
* @author Wouter de Jong <[email protected]>
@@ -25,11 +31,6 @@ public function __construct(string $secret)
2531
$this->secret = $secret;
2632
}
2733

28-
public function start(Request $request, AuthenticationException $authException = null)
29-
{
30-
return new Response(null, Response::HTTP_UNAUTHORIZED);
31-
}
32-
3334
public function supports(Request $request): ?bool
3435
{
3536
return true;
@@ -40,27 +41,29 @@ public function getCredentials(Request $request)
4041
return [];
4142
}
4243

43-
public function getUser($credentials, UserProviderInterface $userProvider)
44+
public function getUser($credentials): ?UserInterface
4445
{
4546
return new User('anon.', null);
4647
}
4748

48-
public function checkCredentials($credentials, UserInterface $user)
49+
public function checkCredentials($credentials, UserInterface $user): bool
4950
{
5051
return true;
5152
}
5253

53-
public function createAuthenticatedToken(UserInterface $user, string $providerKey)
54+
public function createAuthenticatedToken(UserInterface $user, string $providerKey): TokenInterface
5455
{
5556
return new AnonymousToken($this->secret, 'anon.', []);
5657
}
5758

58-
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
59+
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
5960
{
61+
return null;
6062
}
6163

62-
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
64+
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey): ?Response
6365
{
66+
return null;
6467
}
6568

6669
public function supportsRememberMe(): bool
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Core\Authentication\Authenticator;
13+
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\HttpFoundation\Response;
16+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
17+
use Symfony\Component\Security\Core\Exception\AuthenticationException;
18+
use Symfony\Component\Security\Core\User\UserInterface;
19+
20+
/**
21+
* The interface for all authenticators.
22+
*
23+
* @author Ryan Weaver <[email protected]>
24+
* @author Amaury Leroux de Lens <[email protected]>
25+
* @author Wouter de Jong <[email protected]>
26+
*/
27+
interface AuthenticatorInterface
28+
{
29+
/**
30+
* Does the authenticator support the given Request?
31+
*
32+
* If this returns false, the authenticator will be skipped.
33+
*/
34+
public function supports(Request $request): ?bool;
35+
36+
/**
37+
* Get the authentication credentials from the request and return them
38+
* as any type (e.g. an associate array).
39+
*
40+
* Whatever value you return here will be passed to getUser() and checkCredentials()
41+
*
42+
* For example, for a form login, you might:
43+
*
44+
* return [
45+
* 'username' => $request->request->get('_username'),
46+
* 'password' => $request->request->get('_password'),
47+
* ];
48+
*
49+
* Or for an API token that's on a header, you might use:
50+
*
51+
* return ['api_key' => $request->headers->get('X-API-TOKEN')];
52+
*
53+
* @return mixed Any non-null value
54+
*
55+
* @throws \UnexpectedValueException If null is returned
56+
*/
57+
public function getCredentials(Request $request);
58+
59+
/**
60+
* Return a UserInterface object based on the credentials.
61+
*
62+
* You may throw an AuthenticationException if you wish. If you return
63+
* null, then a UsernameNotFoundException is thrown for you.
64+
*
65+
* @param mixed $credentials the value returned from getCredentials()
66+
*
67+
* @throws AuthenticationException
68+
*/
69+
public function getUser($credentials): ?UserInterface;
70+
71+
/**
72+
* Returns true if the credentials are valid.
73+
*
74+
* If false is returned, authentication will fail. You may also throw
75+
* an AuthenticationException if you wish to cause authentication to fail.
76+
*
77+
* @param mixed $credentials the value returned from getCredentials()
78+
*
79+
* @throws AuthenticationException
80+
*/
81+
public function checkCredentials($credentials, UserInterface $user): bool;
82+
83+
/**
84+
* Create an authenticated token for the given user.
85+
*
86+
* If you don't care about which token class is used or don't really
87+
* understand what a "token" is, you can skip this method by extending
88+
* the AbstractAuthenticator class from your authenticator.
89+
*
90+
* @see AbstractAuthenticator
91+
*/
92+
public function createAuthenticatedToken(UserInterface $user, string $providerKey): TokenInterface;
93+
94+
/**
95+
* Called when authentication executed, but failed (e.g. wrong username password).
96+
*
97+
* This should return the Response sent back to the user, like a
98+
* RedirectResponse to the login page or a 403 response.
99+
*
100+
* If you return null, the request will continue, but the user will
101+
* not be authenticated. This is probably not what you want to do.
102+
*/
103+
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response;
104+
105+
/**
106+
* Called when authentication executed and was successful!
107+
*
108+
* This should return the Response sent back to the user, like a
109+
* RedirectResponse to the last page they visited.
110+
*
111+
* If you return null, the current request will continue, and the user
112+
* will be authenticated. This makes sense, for example, with an API.
113+
*/
114+
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey): ?Response;
115+
116+
/**
117+
* Does this method support remember me cookies?
118+
*
119+
* Remember me cookie will be set if *all* of the following are met:
120+
* A) This method returns true
121+
* B) The remember_me key under your firewall is configured
122+
* C) The "remember me" functionality is activated. This is usually
123+
* done by having a _remember_me checkbox in your form, but
124+
* can be configured by the "always_remember_me" and "remember_me_parameter"
125+
* parameters under the "remember_me" firewall key
126+
* D) The onAuthenticationSuccess method returns a Response object
127+
*/
128+
public function supportsRememberMe(): bool;
129+
}

0 commit comments

Comments
 (0)