Skip to content

Commit 2ee64d4

Browse files
committed
Moved new authenticator to the HTTP namespace
This removes the introduced dependency on Guard from core. It also allows an easier migration path, as the complete Guard subcomponent can now be deprecated later in the 5.x life.
1 parent f5a19a9 commit 2ee64d4

13 files changed

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

0 commit comments

Comments
 (0)