Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a172bac

Browse filesBrowse files
committed
Added FormLogin and Anonymous authenticators
1 parent 9b7fddd commit a172bac
Copy full SHA for a172bac

File tree

9 files changed

+262
-6
lines changed
Filter options

9 files changed

+262
-6
lines changed

‎src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AnonymousFactory.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AnonymousFactory.php
+15-1Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
/**
2020
* @author Wouter de Jong <wouter@wouterj.nl>
2121
*/
22-
class AnonymousFactory implements SecurityFactoryInterface
22+
class AnonymousFactory implements SecurityFactoryInterface, GuardFactoryInterface
2323
{
2424
public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint)
2525
{
@@ -42,6 +42,20 @@ public function create(ContainerBuilder $container, $id, $config, $userProvider,
4242
return [$providerId, $listenerId, $defaultEntryPoint];
4343
}
4444

45+
public function createGuard(ContainerBuilder $container, string $id, array $config, ?string $userProviderId): string
46+
{
47+
if (null === $config['secret']) {
48+
$config['secret'] = new Parameter('container.build_hash');
49+
}
50+
51+
$authenticatorId = 'security.authenticator.anonymous.'.$id;
52+
$container
53+
->setDefinition($authenticatorId, new ChildDefinition('security.authenticator.anonymous'))
54+
->replaceArgument(0, $config['secret']);
55+
56+
return $authenticatorId;
57+
}
58+
4559
public function getPosition()
4660
{
4761
return 'anonymous';

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php
+14-1Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* @author Fabien Potencier <fabien@symfony.com>
2323
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
2424
*/
25-
class FormLoginFactory extends AbstractFactory
25+
class FormLoginFactory extends AbstractFactory implements GuardFactoryInterface
2626
{
2727
public function __construct()
2828
{
@@ -96,4 +96,17 @@ protected function createEntryPoint(ContainerBuilder $container, string $id, arr
9696

9797
return $entryPointId;
9898
}
99+
100+
public function createGuard(ContainerBuilder $container, string $id, array $config, ?string $userProviderId): string
101+
{
102+
$authenticatorId = 'security.authenticator.form_login.'.$id;
103+
$defaultOptions = array_merge($this->defaultSuccessHandlerOptions, $this->options);
104+
$options = array_merge($defaultOptions, array_intersect_key($config, $defaultOptions));
105+
$container
106+
->setDefinition($authenticatorId, new ChildDefinition('security.authenticator.form_login'))
107+
->replaceArgument(1, isset($config['csrf_token_generator']) ? new Reference($config['csrf_token_generator']) : null)
108+
->replaceArgument(3, $options);
109+
110+
return $authenticatorId;
111+
}
99112
}

‎src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/GuardFactoryInterface.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/GuardFactoryInterface.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ interface GuardFactoryInterface
2323
*
2424
* @return string|string[] The Guard service ID(s) to be used by the firewall
2525
*/
26-
public function createGuard(ContainerBuilder $container, string $id, array $config, string $userProviderId);
26+
public function createGuard(ContainerBuilder $container, string $id, array $config, ?string $userProviderId);
2727
}

‎src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public function create(ContainerBuilder $container, string $id, array $config, s
4646
return [$provider, $listenerId, $entryPointId];
4747
}
4848

49-
public function createGuard(ContainerBuilder $container, string $id, array $config, string $userProviderId): string
49+
public function createGuard(ContainerBuilder $container, string $id, array $config, ?string $userProviderId): string
5050
{
5151
$authenticatorId = 'security.authenticator.http_basic.'.$id;
5252
$container

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,9 @@ public function load(array $configs, ContainerBuilder $container)
138138
$container->setParameter('security.access.always_authenticate_before_granting', $config['always_authenticate_before_granting']);
139139
$container->setParameter('security.authentication.hide_user_not_found', $config['hide_user_not_found']);
140140

141-
$this->guardAuthenticationManagerEnabled = $config['guard_authentication_manager'];
141+
if ($this->guardAuthenticationManagerEnabled = $config['guard_authentication_manager']) {
142+
$loader->load('authenticators.xml');
143+
}
142144

143145
$this->createFirewalls($config, $container);
144146
$this->createAuthorization($config, $container);

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Resources/config/authenticators.xml
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,20 @@
1212
<argument type="service" id="security.encoder_factory" />
1313
<argument type="service" id="logger" on-invalid="null" />
1414
</service>
15+
16+
<service id="security.authenticator.form_login"
17+
class="Symfony\Component\Security\Core\Authentication\Authenticator\FormLoginAuthenticator"
18+
abstract="true">
19+
<argument type="service" id="security.http_utils" />
20+
<argument /> <!-- csrf token generator -->
21+
<argument type="service" id="security.encoder_factory" />
22+
<argument type="abstract">options</argument>
23+
</service>
24+
25+
<service id="security.authenticator.anonymous"
26+
class="Symfony\Component\Security\Core\Authentication\Authenticator\AnonymousAuthenticator"
27+
abstract="true">
28+
<argument /> <!-- secret -->
29+
</service>
1530
</services>
1631
</container>

‎src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
</service>
5555
<service id="security.authentication.manager.guard" class="Symfony\Component\Security\Core\Authentication\GuardAuthenticationManager">
5656
<argument /> <!-- guard authenticators -->
57-
<argument /> <!-- User Checker -->
57+
<argument type="service" id="Symfony\Component\Security\Core\User\UserCheckerInterface" /> <!-- User Checker -->
5858
<argument>%security.authentication.manager.erase_credentials%</argument>
5959
<call method="setEventDispatcher">
6060
<argument type="service" id="event_dispatcher" />
+70Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
namespace Symfony\Component\Security\Core\Authentication\Authenticator;
4+
5+
use Symfony\Component\HttpFoundation\Request;
6+
use Symfony\Component\HttpFoundation\Response;
7+
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
8+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
9+
use Symfony\Component\Security\Core\Exception\AuthenticationException;
10+
use Symfony\Component\Security\Core\User\User;
11+
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;
15+
16+
/**
17+
* @author Wouter de Jong <wouter@wouterj.nl>
18+
*/
19+
class AnonymousAuthenticator implements AuthenticatorInterface
20+
{
21+
private $secret;
22+
23+
public function __construct(string $secret)
24+
{
25+
$this->secret = $secret;
26+
}
27+
28+
public function start(Request $request, AuthenticationException $authException = null)
29+
{
30+
return new Response(null, Response::HTTP_UNAUTHORIZED);
31+
}
32+
33+
public function supports(Request $request): ?bool
34+
{
35+
return true;
36+
}
37+
38+
public function getCredentials(Request $request)
39+
{
40+
return [];
41+
}
42+
43+
public function getUser($credentials, UserProviderInterface $userProvider)
44+
{
45+
return new User('anon.', null);
46+
}
47+
48+
public function checkCredentials($credentials, UserInterface $user)
49+
{
50+
return true;
51+
}
52+
53+
public function createAuthenticatedToken(UserInterface $user, string $providerKey)
54+
{
55+
return new AnonymousToken($this->secret, 'anon.', []);
56+
}
57+
58+
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
59+
{
60+
}
61+
62+
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
63+
{
64+
}
65+
66+
public function supportsRememberMe(): bool
67+
{
68+
return false;
69+
}
70+
}
+142Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<?php
2+
3+
namespace Symfony\Component\Security\Core\Authentication\Authenticator;
4+
5+
use Symfony\Component\HttpFoundation\Request;
6+
use Symfony\Component\HttpFoundation\Response;
7+
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
8+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
9+
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
10+
use Symfony\Component\Security\Core\Exception\AuthenticationException;
11+
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
12+
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
13+
use Symfony\Component\Security\Core\Security;
14+
use Symfony\Component\Security\Core\User\UserInterface;
15+
use Symfony\Component\Security\Core\User\UserProviderInterface;
16+
use Symfony\Component\Security\Csrf\CsrfToken;
17+
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
18+
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
19+
use Symfony\Component\Security\Http\HttpUtils;
20+
use Symfony\Component\Security\Http\ParameterBagUtils;
21+
use Symfony\Component\Security\Http\Util\TargetPathTrait;
22+
23+
/**
24+
* @author Wouter de Jong <wouter@wouterj.nl>
25+
*/
26+
class FormLoginAuthenticator extends AbstractFormLoginAuthenticator
27+
{
28+
use TargetPathTrait, UsernamePasswordTrait, UserProviderTrait {
29+
UsernamePasswordTrait::checkCredentials as checkPassword;
30+
}
31+
32+
private $options;
33+
private $httpUtils;
34+
private $csrfTokenManager;
35+
private $encoderFactory;
36+
37+
public function __construct(HttpUtils $httpUtils, ?CsrfTokenManagerInterface $csrfTokenManager, EncoderFactoryInterface $encoderFactory, array $options)
38+
{
39+
$this->httpUtils = $httpUtils;
40+
$this->csrfTokenManager = $csrfTokenManager;
41+
$this->encoderFactory = $encoderFactory;
42+
$this->options = array_merge([
43+
'username_parameter' => '_username',
44+
'password_parameter' => '_password',
45+
'csrf_parameter' => '_csrf_token',
46+
'csrf_token_id' => 'authenticate',
47+
'post_only' => true,
48+
49+
'always_use_default_target_path' => false,
50+
'default_target_path' => '/',
51+
'login_path' => '/login',
52+
'target_path_parameter' => '_target_path',
53+
'use_referer' => false,
54+
], $options);
55+
}
56+
57+
protected function getLoginUrl(): string
58+
{
59+
return $this->options['login_path'];
60+
}
61+
62+
public function supports(Request $request): bool
63+
{
64+
return ($this->options['post_only'] ? $request->isMethod('POST') : true)
65+
&& $this->httpUtils->checkRequestPath($request, $this->options['check_path']);
66+
}
67+
68+
public function getCredentials(Request $request): array
69+
{
70+
$credentials = [];
71+
72+
if (null !== $this->csrfTokenManager) {
73+
$credentials['csrf_token'] = ParameterBagUtils::getRequestParameterValue($request, $this->options['csrf_parameter']);
74+
}
75+
76+
if ($this->options['post_only']) {
77+
$credentials['username'] = ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']);
78+
$credentials['password'] = ParameterBagUtils::getParameterBagValue($request->request, $this->options['password_parameter']);
79+
} else {
80+
$credentials['username'] = ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']);
81+
$credentials['password'] = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']);
82+
}
83+
84+
if (!\is_string($credentials['username']) && (!\is_object($credentials['username']) || !method_exists($credentials['username'], '__toString'))) {
85+
throw new BadRequestHttpException(sprintf('The key "%s" must be a string, "%s" given.', $this->options['username_parameter'], \gettype($credentials['username'])));
86+
}
87+
88+
$credentials['username'] = trim($credentials['username']);
89+
90+
if (\strlen($credentials['username']) > Security::MAX_USERNAME_LENGTH) {
91+
throw new BadCredentialsException('Invalid username.');
92+
}
93+
94+
$request->getSession()->set(Security::LAST_USERNAME, $username);
95+
96+
return $credentials;
97+
}
98+
99+
public function checkCredentials($credentials, UserInterface $user): bool
100+
{
101+
if (null !== $this->csrfTokenManager) {
102+
if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken($this->options['csrf_token_id'], $credentials['csrf_token']))) {
103+
throw new InvalidCsrfTokenException('Invalid CSRF token.');
104+
}
105+
}
106+
107+
return $this->checkPassword($credentials, $user);
108+
}
109+
110+
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
111+
{
112+
return $this->httpUtils->createRedirectResponse($request, $this->determineTargetUrl($request, $providerKey));
113+
}
114+
115+
private function determineTargetUrl(Request $request, string $providerKey)
116+
{
117+
if ($this->options['always_use_default_target_path']) {
118+
return $this->options['default_target_path'];
119+
}
120+
121+
if ($targetUrl = ParameterBagUtils::getRequestParameterValue($request, $this->options['target_path_parameter'])) {
122+
return $targetUrl;
123+
}
124+
125+
if ($targetUrl = $this->getTargetPath($request->getSession(), $providerKey)) {
126+
$this->removeTargetPath($request->getSession(), $providerKey);
127+
128+
return $targetUrl;
129+
}
130+
131+
if ($this->options['use_referer'] && $targetUrl = $request->headers->get('Referer')) {
132+
if (false !== $pos = strpos($targetUrl, '?')) {
133+
$targetUrl = substr($targetUrl, 0, $pos);
134+
}
135+
if ($targetUrl && $targetUrl !== $this->httpUtils->generateUri($request, $this->options['login_path'])) {
136+
return $targetUrl;
137+
}
138+
}
139+
140+
return $this->options['default_target_path'];
141+
}
142+
}

0 commit comments

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