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 a7ace88

Browse filesBrowse files
committed
add security.firewalls.not_full_fledged_handler option
if not authenticated at all
1 parent 8f71c8d commit a7ace88
Copy full SHA for a7ace88

File tree

13 files changed

+255
-14
lines changed
Filter options

13 files changed

+255
-14
lines changed

‎src/Symfony/Bundle/SecurityBundle/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
---
66

77
* Allow configuring the secret used to sign login links
8+
* Add `security.firewalls.not_full_fledged_handler` option to configure behavior where user is not full fledged
89

910
7.1
1011
---

‎src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ public function collect(Request $request, Response $response, ?\Throwable $excep
175175
'access_denied_url' => $firewallConfig->getAccessDeniedUrl(),
176176
'user_checker' => $firewallConfig->getUserChecker(),
177177
'authenticators' => $firewallConfig->getAuthenticators(),
178+
'not_full_fledged_handler' => $firewallConfig->getNotFullFledgedHandler(),
178179
];
179180

180181
// generate exit impersonation path from current request

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
2020
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
2121
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy;
22+
use Symfony\Component\Security\Http\Authorization\SameAsNotFullFledgedHandle;
2223

2324
/**
2425
* SecurityExtension configuration structure.
@@ -214,6 +215,14 @@ private function addFirewallsSection(ArrayNodeDefinition $rootNode, array $facto
214215
->booleanNode('stateless')->defaultFalse()->end()
215216
->booleanNode('lazy')->defaultFalse()->end()
216217
->scalarNode('context')->cannotBeEmpty()->end()
218+
->scalarNode('not_full_fledged_handler')
219+
->beforeNormalization()
220+
->ifTrue(fn ($v): bool => $v == 'original')
221+
->then(fn ($v) => null)
222+
->ifTrue(fn ($v): bool => $v == 'same')
223+
->then(fn ($v) => SameAsNotFullFledgedHandle::class)
224+
->end()
225+
->end()
217226
->arrayNode('logout')
218227
->treatTrueLike([])
219228
->canBeUnset()

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ private function createFirewall(ContainerBuilder $container, string $id, array $
578578

579579
$config->replaceArgument(10, $listenerKeys);
580580
$config->replaceArgument(11, $firewall['switch_user'] ?? null);
581+
$config->replaceArgument(13, $firewall['not_full_fledged_handler'] ?? null);
581582

582583
return [$matcher, $listeners, $exceptionListener, null !== $logoutListenerId ? new Reference($logoutListenerId) : null, $firewallAuthenticationProviders];
583584
}
@@ -875,6 +876,11 @@ private function createExceptionListener(ContainerBuilder $container, array $con
875876
$listener->replaceArgument(5, $config['access_denied_url']);
876877
}
877878

879+
// not full fledged handler setup
880+
if (isset($config['not_full_fledged_handler'])) {
881+
$listener->replaceArgument(9, new Reference($config['not_full_fledged_handler']));
882+
}
883+
878884
return $exceptionListenerId;
879885
}
880886

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Resources/config/security.php
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
use Symfony\Component\Security\Core\User\MissingUserProvider;
4343
use Symfony\Component\Security\Core\Validator\Constraints\UserPasswordValidator;
4444
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
45+
use Symfony\Component\Security\Http\Authorization\SameAsNotFullFledgedHandle;
4546
use Symfony\Component\Security\Http\Controller\SecurityTokenValueResolver;
4647
use Symfony\Component\Security\Http\Controller\UserValueResolver;
4748
use Symfony\Component\Security\Http\EventListener\IsGrantedAttributeListener;
@@ -218,6 +219,7 @@
218219
[], // listeners
219220
null, // switch_user
220221
null, // logout
222+
null, //not_full_fledged_handler
221223
])
222224

223225
->set('security.logout_url_generator', LogoutUrlGenerator::class)
@@ -310,5 +312,7 @@
310312
->set('cache.security_is_csrf_token_valid_attribute_expression_language')
311313
->parent('cache.system')
312314
->tag('cache.pool')
315+
316+
->set('security.same_as_not_full_fledged_handle', SameAsNotFullFledgedHandle::class)
313317
;
314318
};

‎src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@
139139
service('security.access.denied_handler')->nullOnInvalid(),
140140
service('logger')->nullOnInvalid(),
141141
false, // Stateless
142+
service('security.not.full.fledged_handler')->nullOnInvalid(),
142143
])
143144
->tag('monolog.logger', ['channel' => 'security'])
144145

‎src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,10 @@
282282
<th>authenticators</th>
283283
<td>{{ collector.firewall.authenticators is empty ? '(none)' : profiler_dump(collector.firewall.authenticators, maxDepth=1) }}</td>
284284
</tr>
285+
<tr>
286+
<th>not_full_fledged_handler</th>
287+
<td>{{ collector.firewall.not_full_fledged_handler ?: '(none)' }}</td>
288+
</tr>
285289
</tbody>
286290
</table>
287291
{% endif %}

‎src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public function __construct(
3030
private readonly array $authenticators = [],
3131
private readonly ?array $switchUser = null,
3232
private readonly ?array $logout = null,
33+
private readonly ?string $notFullFledgedHandler = null,
3334
) {
3435
}
3536

@@ -104,4 +105,9 @@ public function getLogout(): ?array
104105
{
105106
return $this->logout;
106107
}
108+
109+
public function getNotFullFledgedHandler(): ?string
110+
{
111+
return $this->notFullFledgedHandler;
112+
}
107113
}

‎src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTestCase.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTestCase.php
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ public function testFirewalls()
149149
[],
150150
null,
151151
null,
152+
null,
152153
],
153154
[
154155
'secure',
@@ -184,6 +185,7 @@ public function testFirewalls()
184185
'enable_csrf' => null,
185186
'clear_site_data' => [],
186187
],
188+
null,
187189
],
188190
[
189191
'host',
@@ -201,6 +203,7 @@ public function testFirewalls()
201203
],
202204
null,
203205
null,
206+
null,
204207
],
205208
[
206209
'with_user_checker',
@@ -218,6 +221,7 @@ public function testFirewalls()
218221
],
219222
null,
220223
null,
224+
null,
221225
],
222226
], $configs);
223227

+34Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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\Authorization;
13+
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\HttpFoundation\Response;
16+
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
17+
18+
/**
19+
* This is used by the ExceptionListener to translate an AccessDeniedException
20+
* to a Response object.
21+
*
22+
* @author Roman JOLY <eltharin18@outlook.fr>
23+
*/
24+
interface NotFullFledgedHandlerInterface
25+
{
26+
/**
27+
* Handles a not full fledged case for acces denied failure.
28+
* @return bool|Response : bool|Response
29+
* true : user have to be fully authenticated, continu to startAuthentication
30+
* false : user have'nt to be fully authenticated, throw original AcessDeniedException
31+
* Response: you can return your own response, AccesDeniedException wil be ignored
32+
*/
33+
public function handle(Request $request, AccessDeniedException $accessDeniedException): bool|Response;
34+
}
+37Lines 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\Authorization;
13+
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\HttpFoundation\Response;
16+
use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter;
17+
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
18+
19+
/**
20+
* This is a basic NotFullFledgedHandle
21+
* If IS_AUTHENTICATED_FULLY is in access denied Exception Attrribute, behavior will be as before,
22+
* Otherwise The original AccessDeniedException is throw
23+
*
24+
* @author Roman JOLY <eltharin18@outlook.fr>
25+
*/
26+
class SameAsNotFullFledgedHandle implements NotFullFledgedHandlerInterface
27+
{
28+
public function handle(Request $request, AccessDeniedException $accessDeniedException): bool|Response
29+
{
30+
foreach($accessDeniedException->getAttributes() as $attribute) {
31+
if(in_array($attribute, [AuthenticatedVoter::IS_AUTHENTICATED_FULLY])) {
32+
return true;
33+
}
34+
}
35+
return false;
36+
}
37+
}

‎src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php
+19-11Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use Symfony\Component\Security\Core\Exception\LazyResponseException;
3030
use Symfony\Component\Security\Core\Exception\LogoutException;
3131
use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;
32+
use Symfony\Component\Security\Http\Authorization\NotFullFledgedHandlerInterface;
3233
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
3334
use Symfony\Component\Security\Http\EntryPoint\Exception\NotAnEntryPointException;
3435
use Symfony\Component\Security\Http\HttpUtils;
@@ -57,6 +58,7 @@ public function __construct(
5758
private ?AccessDeniedHandlerInterface $accessDeniedHandler = null,
5859
private ?LoggerInterface $logger = null,
5960
private bool $stateless = false,
61+
private ?NotFullFledgedHandlerInterface $notFullFledgedHandler = null,
6062
) {
6163
}
6264

@@ -127,20 +129,26 @@ private function handleAccessDeniedException(ExceptionEvent $event, AccessDenied
127129

128130
$token = $this->tokenStorage->getToken();
129131
if (!$this->authenticationTrustResolver->isFullFledged($token)) {
130-
$this->logger?->debug('Access denied, the user is not fully authenticated; redirecting to authentication entry point.', ['exception' => $exception]);
131-
132-
try {
133-
$insufficientAuthenticationException = new InsufficientAuthenticationException('Full authentication is required to access this resource.', 0, $exception);
134-
if (null !== $token) {
135-
$insufficientAuthenticationException->setToken($token);
132+
$response = ((!$this->authenticationTrustResolver->isAuthenticated($token)) || (null === $this->notFullFledgedHandler) ? true : $this->notFullFledgedHandler->handle($event->getRequest(), $exception));
133+
134+
if ($response instanceof Response) {
135+
$event->setResponse($response);
136+
} elseif ($response === true) {
137+
$this->logger?->debug('Access denied, the user is not fully authenticated; redirecting to authentication entry point.', ['exception' => $exception]);
138+
139+
try {
140+
$insufficientAuthenticationException = new InsufficientAuthenticationException('Full authentication is required to access this resource.', 0, $exception);
141+
if (null !== $token) {
142+
$insufficientAuthenticationException->setToken($token);
143+
}
144+
145+
$event->setResponse($this->startAuthentication($event->getRequest(), $insufficientAuthenticationException));
146+
} catch (\Exception $e) {
147+
$event->setThrowable($e);
136148
}
137149

138-
$event->setResponse($this->startAuthentication($event->getRequest(), $insufficientAuthenticationException));
139-
} catch (\Exception $e) {
140-
$event->setThrowable($e);
150+
return;
141151
}
142-
143-
return;
144152
}
145153

146154
$this->logger?->debug('Access denied, the user is neither anonymous, nor remember-me.', ['exception' => $exception]);

0 commit comments

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