是否可以通过编程方式查看防火墙后面的URL /路由是否受到保护?

时间:2011-10-13 17:03:28

标签: symfony firewall

如果用户尝试访问受保护的网址并且经过身份验证/授权,我需要运行一些代码。

默认情况下,Symfony通过将用户重定向或转发到登录表单来处理未经身份验证的用户。如果请求方法是POST,我想阻止这种情况发生,而是回显JSON对象。

我能想到的最好的方法是创建一个自定义侦听器来侦听kernel.request事件并检查两件事:

  • 检查请求方法是否为POST
  • 检查用户是否完整 认证

如果是POST请求,并且用户未完全通过身份验证,我会回显JSON对象。

但我的听众(预期)会针对所有请求进行解雇 - 我想将其限制为仅检查请求是否针对受防火墙保护的URL。是否可以以编程方式检查这个?

我也有一种唠叨的怀疑,有一种更简单的方法可以解决这个问题,但无法弄清楚,所以如果有人有任何提示,我很乐意听到它们:)

修改
@Problematic - 仅检查防火墙请求的原因是因为我有一些没有防火墙的请求,如果我的代码被触发,我将收到上述JSON对象而不是请求的真实响应。

现在,如果我没有登录并向api/get/something(位于防火墙后面)发出POST请求,Symfony将返回描述登录页面的HTML。相反,我想回应像{error: 'User is not authorized'}这样的东西。但我只希望在POST请求中发生这种情况。

1 个答案:

答案 0 :(得分:3)

我想我是以错误的方式解决这个问题。我想知道一个URL是否在防火墙后面,但我想我应该一直试图找出当前用户是否获得了该请求的授权。在本质上,知道用户被拒绝访问URL意味着URL必须位于防火墙后面,否则访问权限不会被拒绝。

记住这一点,我能够得到我想要的最终结果。一旦你意识到安全机制是如何工作的,这很简单......

  • Symfony\Component\Security\Http\Firewall听取了 kernel.request活动
  • 防火墙会调用许多在security.yml
  • 中注册的事件侦听器
  • 如果检测到任何安全违规(即用户尝试访问某些内容但未登录),则会引发AccessDeniedException,并调度kernel.exception事件。
  • Symfony/Component/Security/Http/Firewall/ExceptionListener侦听事件并触发其onKernelException方法,该方法决定下一步是什么。就我而言,它将启动身份验证过程

由于启动身份验证过程是我想要避免的,我编写了自己的事件监听器,在Symfony的kernel.exception之前拦截ExceptionListener。我给我的事件监听器优先级为1。

这是我写的方法:

public function handleException(GetResponseForExceptionEvent $event) {
        $exception = $event->getException();
        $request = $event->getRequest();
        if ($request->getMethod() == 'POST') {
            if ($exception instanceof AccessDeniedException) {
                $response = new Response({err: 'not logged in'});
                $event->setResponse($response);
            }
        }
    }

只要用户未获得授权,并且请求方法是POST,就会返回JSON对象(这也会停止事件传播),而不是登录页面的HTML。否则,kernel.exception的其他听众将做出反应,Symfony可以开展业务。

因此,原始问题仍然没有答案,但我认为可以通过检查用户是否有权访问某个操作来完成。 Symfony\Component\Security\Core\Authorization\AccessDecisionManager看起来对此有帮助。

修改
我不知道这个方法是否处理未登录的用户。我还没有测试过,但我认为如果(已登录)用户尝试访问需要他们尚未授予角色的行动。如果这会导致问题,我会尝试修改它以使用Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver的{​​{1}}方法来关心未登录的用户。

相关问题