在access_control规则重定向后通知用户的最佳方式是什么?守则资源:

2022-08-30 18:50:18

来自 Symfony 2.3 安全文档:

如果访问被拒绝,系统将尝试对用户进行身份验证(如果尚未验证)(例如,将用户重定向到登录页面)。如果用户已登录,将显示 403“拒绝访问”错误页面。有关详细信息,请参阅如何自定义错误页。

我目前正在对几个路由使用规则。如果匿名用户被重定向到登录路由,并显示类似“您必须登录才能访问该页面”的消息,我想通知他们。我已经通读了几次安全文档,但没有找到与此相关的任何内容。我是否忽略了什么?access_control

如果不是,只有当用户被重定向到登录时,当他们被规则阻止时,通知用户的最佳方式是什么(即,如果他们只是处于未经授权的角色中),那么通知用户的最佳方式是什么?access_control

编辑:为了澄清,我专门询问如何检查重定向是否由规则引起(如果可能的话,最好是树枝)。access_control


答案 1

因此,经过相当多的研究,我找到了正确的方法。需要使用入口点服务并在防火墙配置中定义它。

此方法不会弄乱防火墙配置中指定用于登录的默认页面设置。


守则

security.yml:

firewalls:
    main:
        entry_point: entry_point.user_login #or whatever you name your service
        pattern: ^/
        form_login:
        # ...

src/Acme/UserBundle/config/services.yml

services:
    entry_point.user_login:
        class: Acme\UserBundle\Service\LoginEntryPoint
        arguments: [ @router ] #I am going to use this for URL generation since I will be redirecting in my service

src/Acme/UserBundle/Service/LoginEntryPoint.php:

namespace Acme\UserBundle\Service;

use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface,
    Symfony\Component\Security\Core\Exception\AuthenticationException,
    Symfony\Component\HttpFoundation\Request,
    Symfony\Component\HttpFoundation\RedirectResponse;

/**
 * When the user is not authenticated at all (i.e. when the security context has no token yet), 
 * the firewall's entry point will be called to start() the authentication process. 
 */
class LoginEntryPoint implements AuthenticationEntryPointInterface
{
    protected $router;

    public function __construct($router)
    {
        $this->router = $router;
    }

    /*
     * This method receives the current Request object and the exception by which the exception 
     * listener was triggered. 
     * 
     * The method should return a Response object
     */
    public function start(Request $request, AuthenticationException $authException = null)
    {
        $session = $request->getSession();

        // I am choosing to set a FlashBag message with my own custom message.
        // Alternatively, you could use AuthenticationException's generic message 
        // by calling $authException->getMessage()
        $session->getFlashBag()->add('warning', 'You must be logged in to access that page');

        return new RedirectResponse($this->router->generate('login'));
    }
}

登录.html.twig:

{# bootstrap ready for your convenience ;] #}
{% if app.session.flashbag.has('warning') %}
    {% for flashMessage in app.session.flashbag.get('warning') %}
        <div class="alert alert-warning">
            <button type="button" class="close" data-dismiss="alert">&times;</button>
            {{ flashMessage }}
        </div>
    {% endfor %}
{% endif %}

资源:


答案 2

我认为一个 kernel.exception 监听器和设置一个 flash 消息可以做到这一点。未经测试的示例:

use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

class My403ExceptionListener
{
    protected $session;

    public function __construct(SessionInterface $session)
    {
        $this->session = $session;
    }

    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        $exception = $event->getException();
        if ($exception instanceof AccessDeniedHttpException) {
            $this->session->getFlashBag()->set('warning', 'You must login to access that page.');
        }
    }
}

真的不知道它是否有效,或者它是否是正确的。您可以将其注册为 .或者,也许最好您编写一个专用服务,并将其设置为防火墙配置中的参数。我认为有很多可能的方法。kernel.event_listeneraccess_denied_handler


推荐