Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commitba824f7

Browse files
committed
Clarify authentication entry point and access denied handler
1 parent8672801 commitba824f7

File tree

1 file changed

+166
-15
lines changed

1 file changed

+166
-15
lines changed

‎security/access_denied_handler.rst‎

Lines changed: 166 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,116 @@
11
..index::
22
single: Security; Creating a Custom Access Denied Handler
33

4-
How toCreate a CustomAccess DeniedHandler
5-
============================================
4+
How toCustomizeAccess DeniedResponses
5+
========================================
66

7-
When your application throws an ``AccessDeniedException``, you can handle this exception
8-
with a service to return a custom response.
7+
In Symfony, you can throw an
8+
:class:`Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException`
9+
to disallow access to the user. Symfony will handle this exception and
10+
generates a response based on the authentication state:
911

10-
First, create a class that implements
12+
* **If the user is not authenticated** (or authenticated anonymously), an
13+
authentication entry point is used to generated a response (typically
14+
a redirect to the login page or an *401 Unauthorized* response);
15+
* **If the user is authenticated, but does not have the required
16+
permissions**, a *403 Forbidden* response is generated.
17+
18+
Customize the Unauthorized Response
19+
-----------------------------------
20+
21+
You need to create a class that implements
22+
:class:`Symfony\\Component\\Security\\Http\\EntryPoint\\AuthenticationEntryPointInterface`.
23+
This interface has one method (``start()``) that is called whenever an
24+
unauthenticated user tries to access a protected resource::
25+
26+
// src/Security/AuthenticationEntryPoint.php
27+
namespace App\Security;
28+
29+
use Symfony\Component\HttpFoundation\RedirectResponse;
30+
use Symfony\Component\HttpFoundation\Request;
31+
use Symfony\Component\HttpFoundation\Session\SessionInterface;
32+
use Symfony\Component\Security\Core\Exception\AuthenticationException;
33+
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
34+
35+
class AuthenticationEntryPoint implements AuthenticationEntryPointInterface
36+
{
37+
private $urlGenerator;
38+
private $session;
39+
40+
public function __construct(UrlGeneratorInterface $urlGenerator, SessionInterface $session)
41+
{
42+
$this->urlGenerator = $urlGenerator;
43+
$this->session = $session;
44+
}
45+
46+
public function start(Request $request, AuthenticationException $authException = null): RedirectResponse
47+
{
48+
// add a custom flash message and redirect to the login page
49+
$this->session->getFlashBag()->add('note', 'You have to login in order to access this page.');
50+
51+
return new RedirectResponse($this->urlGenerator->generate('security_login'));
52+
}
53+
}
54+
55+
That's it if you're using the:ref:`default services.yaml configuration<service-container-services-load-example>`.
56+
Otherwise, you have to register this service in the container.
57+
58+
Now, configure this service ID as the entry point for the firewall:
59+
60+
..configuration-block::
61+
62+
..code-block::yaml
63+
64+
# config/packages/security.yaml
65+
firewalls:
66+
# ...
67+
68+
main:
69+
# ...
70+
entry_point:App\Security\AuthenticationEntryPoint
71+
72+
..code-block::xml
73+
74+
<!-- config/packages/security.xml-->
75+
<?xml version="1.0" encoding="UTF-8"?>
76+
<srv:containerxmlns="http://symfony.com/schema/dic/security"
77+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
78+
xmlns:srv="http://symfony.com/schema/dic/services"
79+
xsi:schemaLocation="http://symfony.com/schema/dic/services
80+
https://symfony.com/schema/dic/services/services-1.0.xsd">
81+
82+
<config>
83+
<firewallname="main"
84+
entry-point="App\Security\AuthenticationEntryPoint"
85+
>
86+
<!-- ...-->
87+
</firewall>
88+
</config>
89+
</srv:container>
90+
91+
..code-block::php
92+
93+
// config/packages/security.php
94+
use App\Security\AuthenticationEntryPoint;
95+
96+
$container->loadFromExtension('security', [
97+
'firewalls' => [
98+
'main' => [
99+
// ...
100+
'entry_point' => AuthenticationEntryPoint::class,
101+
],
102+
],
103+
]);
104+
105+
Customize the Forbidden Response
106+
--------------------------------
107+
108+
Create a class that implements
11109
:class:`Symfony\\Component\\Security\\Http\\Authorization\\AccessDeniedHandlerInterface`.
12-
This interface defines one method called ``handle()`` where you can implement whatever
13-
logic that should run when access is denied for the current user (e.g. send a
14-
mail, log a message, or generally return a custom response)::
110+
This interface defines one method called ``handle()`` where you can
111+
implement whatever logic that should execute when access is denied for the
112+
current user (e.g. send a mail, log a message, or generally return a custom
113+
response)::
15114

16115
namespace App\Security;
17116

@@ -49,11 +148,21 @@ configure it under your firewall:
49148
..code-block::xml
50149
51150
<!-- config/packages/security.xml-->
52-
<config>
53-
<firewallname="main">
54-
<access-denied-handler>App\Security\AccessDeniedHandler</access-denied-handler>
55-
</firewall>
56-
</config>
151+
<?xml version="1.0" encoding="UTF-8"?>
152+
<srv:containerxmlns="http://symfony.com/schema/dic/security"
153+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
154+
xmlns:srv="http://symfony.com/schema/dic/services"
155+
xsi:schemaLocation="http://symfony.com/schema/dic/services
156+
https://symfony.com/schema/dic/services/services-1.0.xsd">
157+
158+
<config>
159+
<firewallname="main"
160+
access-denied-handler="App\Security\AccessDeniedHandler"
161+
>
162+
<!-- ...-->
163+
</firewall>
164+
</config>
165+
</srv:container>
57166
58167
..code-block::php
59168
@@ -69,5 +178,47 @@ configure it under your firewall:
69178
],
70179
]);
71180
72-
That's it! Any ``AccessDeniedException`` thrown by code under the ``main`` firewall
73-
will now be handled by your service.
181+
Customizing All Access Denied Responses
182+
---------------------------------------
183+
184+
In some cases, you might want to customize both responses or do a specific
185+
action (e.g. logging) for each ``AccessDeniedException``. In this case,
186+
configure a:ref:`kernel.exception listener<use-kernel-exception-event>`::
187+
188+
// src/EventListener/AccessDeniedListener.php
189+
namespace App\EventListener;
190+
191+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
192+
use Symfony\Component\HttpFoundation\Response;
193+
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
194+
use Symfony\Component\HttpKernel\KernelEvents;
195+
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
196+
197+
class AccessDeniedListener implements EventSubscriberInterface
198+
{
199+
public static function getSubscribedEvents(): array
200+
{
201+
return [
202+
// the priority must be greater than the Security HTTP
203+
// ExceptionListener (1), to make sure it's called before
204+
// the default exception listener
205+
KernelEvents::EXCEPTION => ['onKernelException', 2],
206+
];
207+
}
208+
209+
public function onKernelException(ExceptionEvent $event): void
210+
{
211+
$exception = $event->getException();
212+
if (!$exception instanceof AccessDeniedException) {
213+
return;
214+
}
215+
216+
// ... perform some action (e.g. logging)
217+
218+
// optionally set the custom response
219+
$event->setResponse(new Response(null, 403));
220+
221+
// or stop propagation (prevents the other exception listeners from being called)
222+
//$event->stopPropagation();
223+
}
224+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp