我有一种情况,如果用户尝试访问受保护的URL并且未经过身份验证/授权,我需要运行一些代码.
默认情况下,Symfony通过将用户重定向或转发到登录表单来处理未经身份验证的用户.如果请求方法是POST,我想阻止这种情况发生,而是回显JSON对象.
我能想到的最好的方法是创建一个自定义侦听器来侦听kernel.request事件并检查两件事:
如果它是POST请求,并且用户未完全通过身份验证,我将回显JSON对象.
但我的听众(预期)会针对所有请求进行解雇 - 我想将其限制为仅检查请求是否针对受防火墙保护的URL.有可能以编程方式检查这个吗?
我也有一种唠叨的怀疑,有一种更简单的方法可以解决这个问题,但无法弄明白,所以如果有人有任何提示,我很乐意听到他们:)
编辑
@Problematic - 仅检查防火墙请求的原因是因为我有一些没有防火墙的请求,如果我的代码被触发,我将收到上述JSON对象而不是请求的真实响应.
现在,如果我没有登录并发出POST请求api/get/something(位于防火墙后面),Symfony将返回描述登录页面的HTML.相反,我想回应一些类似的东西{error: 'User is not authorized'}.但我只希望这发生在POST请求中.
我想我的处理方式是错误的。我想知道某个 URL 是否位于防火墙后面,但我认为我应该尝试查明当前用户是否已获得该请求的授权。从本质上讲,知道用户被拒绝访问某个 URL 意味着该 URL 必须位于防火墙后面,否则访问不可能被拒绝。
记住这一点,我能够得到我想要的最终结果。一旦您了解安全机制的工作原理,事情就变得非常简单......
Symfony\Component\Security\Http\Firewall监听
kernel.request事件security.ymlAccessDeniedException抛出 并kernel.exception调度该事件。Symfony/Component/Security/Http/Firewall/ExceptionListener监听事件并触发其onKernelException方法来决定下一步是什么。就我而言,它将启动身份验证过程由于启动身份验证过程是我想要避免的,因此我编写了自己的事件监听器,kernel.exception在 Symfony 之前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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
只要用户未经授权,并且请求方法为 POST,就会返回一个 JSON 对象(这也会停止事件传播)而不是登录页面的 HTML。否则,其他听众kernel.exception将会做出反应,而 Symfony 可以继续其业务。
因此,最初的问题仍然没有得到解答,但我认为可以通过检查用户是否有权访问某个操作来完成。Symfony\Component\Security\Core\Authorization\AccessDecisionManager看起来这对此会有帮助。
编辑
我不知道这个方法是否只处理未登录的用户。我还没有测试它,但我认为如果(已登录)用户尝试访问需要他们的角色的操作,它也会触发尚未被授予。如果这导致问题,我会尝试将其修改为使用 的Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver方法 isFullFledged($token)来仅关心未登录的用户。
| 归档时间: |
|
| 查看次数: |
1237 次 |
| 最近记录: |