【问题标题】:Is it possible to see if a URL / route is protected behind the firewall programatically?是否可以通过编程方式查看 URL / 路由是否受防火墙保护?
【发布时间】:2011-10-13 17:03:27
【问题描述】:

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

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

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

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

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

但我的侦听器(预计)会触发所有请求 - 我想将其限制为仅检查请求是否针对受防火墙保护的 URL。是否可以通过编程方式进行检查?

我也有一个挥之不去的怀疑有一个更简单的方法来解决这个问题,但无法弄清楚,所以如果有人有任何提示,我很想听听他们:)

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

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

【问题讨论】:

  • 只检查防火墙请求的原因是什么?
  • @Problematic,请看我的编辑

标签: symfony firewall


【解决方案1】:

我想我做错了。我想知道一个 URL 是否在防火墙后面,但我想我应该一直在尝试找出当前用户是否已获得请求的授权。从本质上讲,知道用户被拒绝访问某个 URL 意味着该 URL 必须位于防火墙之后,否则访问不会被拒绝。

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

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

由于我想避免启动身份验证过程,因此我编写了自己的事件侦听器,该侦听器在 Symfony 的 ExceptionListener 之前拦截 kernel.exception。我给了我的事件监听器 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\AuthenticationTrustResolverisFullFledged($token) 方法只关心未登录的用户。

【讨论】:

  • 如果您发送的是 json 响应,您应该使用以下命令添加检查以查看它是否是 ajax 请求:$request->isXmlHttpRequest()。这就是我用来将默认身份验证方法转换为 ajax 方法的方法。
  • @HappyDeveloper 感谢您的提示,但我仍在使用常规表单登录。如果对受保护的操作发出 POST 请求并且用户未登录,我只需要做出不同的反应。
猜你喜欢
  • 2014-11-26
  • 1970-01-01
  • 1970-01-01
  • 2021-11-02
  • 2021-03-22
  • 1970-01-01
  • 2015-11-26
  • 2011-11-06
  • 2011-05-11
相关资源
最近更新 更多