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

Commit8256c3d

Browse files
committed
Clarify authentication entry point and access denied handler
1 parent4d52670 commit8256c3d

File tree

1 file changed

+163
-16
lines changed

1 file changed

+163
-16
lines changed

‎security/access_denied_handler.rst‎

Lines changed: 163 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,117 @@
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
11-
:class:`Symfony\\Component\\Security\\Http\\Authorization\\AccessDeniedHandlerInterface`.
12-
This interface defines one method called ``handle()`` where you can implement whatever
13-
logic that should execute when access is denied for the current user (e.g. send a
14-
mail, log a message, or generally return a custom response)::
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+
To customize the handling of unauthenticated users, create a class that
22+
implements
23+
:class:`Symfony\\Component\\Security\\Http\\EntryPoint\\AuthenticationEntryPointInterface`.
24+
This interface has one method (``start()``) that is called whenever an
25+
unauthenticated user tries to access a protected resource::
26+
27+
namespace App\Security;
28+
29+
use Symfony\Component\HttpFoundation\Request;
30+
use Symfony\Component\HttpFoundation\RedirectResponse;
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 flashbag 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
109+
:class:`Symfony\\Component\\Security\\Http\\Authorization\\AccessDeniedHandlerInterface`
110+
to customize the access denied response for authenticated users. This
111+
interface defines one method called ``handle()`` where you can implement
112+
whatever logic that should execute when access is denied for the current
113+
user (e.g. send a mail, log a message, or generally return a custom
114+
response)::
15115

16116
namespace App\Security;
17117

@@ -49,11 +149,21 @@ configure it under your firewall:
49149
..code-block::xml
50150
51151
<!-- config/packages/security.xml-->
52-
<config>
53-
<firewallname="main">
54-
<access-denied-handler>App\Security\AccessDeniedHandler</access-denied-handler>
55-
</firewall>
56-
</config>
152+
<?xml version="1.0" encoding="UTF-8"?>
153+
<srv:containerxmlns="http://symfony.com/schema/dic/security"
154+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
155+
xmlns:srv="http://symfony.com/schema/dic/services"
156+
xsi:schemaLocation="http://symfony.com/schema/dic/services
157+
https://symfony.com/schema/dic/services/services-1.0.xsd">
158+
159+
<config>
160+
<firewallname="main"
161+
access-denied-handler="App\Security\AccessDeniedHandler"
162+
>
163+
<!-- ...-->
164+
</firewall>
165+
</config>
166+
</srv:container>
57167
58168
..code-block::php
59169
@@ -69,5 +179,42 @@ configure it under your firewall:
69179
],
70180
]);
71181
72-
That's it! Any ``AccessDeniedException`` thrown by code under the ``main`` firewall
73-
will now be handled by your service.
182+
Customizing All Access Denied Responses
183+
---------------------------------------
184+
185+
In some cases, you might want to customize both responses or do a specific
186+
action (e.g. logging) for each ``AccessDeniedException``. In this case,
187+
configure a:ref:`kernel.exception listener<use-kernel-exception-event>`::
188+
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 >1, to make sure it's called before
203+
// the default exception listener
204+
KernelEvents::EXCEPTION => ['onKernelException', 2],
205+
];
206+
}
207+
208+
public function onKernelException(ExceptionEvent $event): void
209+
{
210+
$exception = $event->getException();
211+
if (!$exception instanceof AccessDeniedException) {
212+
return;
213+
}
214+
215+
// ... perform some action (e.g. logging)
216+
217+
// optionally set the custom response
218+
$event->setResponse(new Response(null, 403));
219+
}
220+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp