如何摆脱";您必须配置要由防火墙处理的检查路径“;GET请求出错


How to get rid of "You must configure the check path to be handled by the firewall" error with GET requests?

当我以通常的方式(使用登录表单)进行身份验证时,它可以正常工作。只有当通过GET方法直接访问/check_form时,我才会得到这个错误,在这种情况下会抛出异常:

您必须在安全防火墙配置中使用form_login配置要由防火墙处理的检查路径。

以下是相关的security.yml部分:

firewalls:
    acme_area:
        pattern:    ^/(acme|admin)/
        provider: fos_userbundle
        form_login:
            provider: fos_userbundle
            csrf_provider: form.csrf_provider
            login_path: acme_login
            check_path: /acme/login_check
        logout:
            path: /acme/logout
            target: acme_login
        anonymous: true

我使用的是2.3,因此没有适用的methods选项(尽管我不知道它是否有帮助)。

这并不是一个真正的问题,因为这个错误不会破坏正确的使用,但当一些勤奋的机器人访问网站时,它会污染错误日志,而且它只是不整洁。所以,我想知道我可以更改哪个配置选项来消除这个错误。

简而言之,我似乎希望抛出一些4xx错误,而不是500。理想情况下应该是405 Method Not Allowed,但404冷也可以。

编辑:

正如我从下面Alex的回答中了解到的那样,之所以会发生这种情况,是因为POST请求由防火墙处理,GET请求由Controller处理。因此,似乎必须扩展默认checkAction()才能处理两种情况:

  1. 当请求是POST但不存在防火墙条目时(已禁用)
  2. 当防火墙条目存在但请求为GET时(我的情况)

没有配置选项。如果请求到达控制器,则无条件抛出异常:可信源。

POST对路由的请求由防火墙处理:官方文档;GET和往常一样进入控制器。

如果您不关心此类事件,那么几乎没有选项可以消除日志中的错误。在我看来,最简单的方法是重写SecurityController::checkAction以返回500错误,而不引发异常。官方文档介绍了如何实现:覆盖默认FOSUserBundle控制器。

编辑:

在控制器中,您可以返回任何您喜欢的代码:

public function checkAction()
{
    return new Response('', 418); // or better use Response constants 
}

另一种方法是在路由配置中禁用对/acme/login_check的GET方法,让路由器完成它的工作并像往常一样返回正常的405 Method Not Allowed

第2版:

您可以在操作中分析请求,但仍然抛出异常:

public function checkAction(Request $request)
{
    if ($request->getMethod() == Request::METHOD_POST) {
        throw new 'RuntimeException('You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.');
    } else {
        return new Response('', Response::HTTP_METHOD_NOT_ALLOWED);
    }
}

但我建议您改为调试路由。这个逻辑应该属于路由器,而不是控制器。从长远来看,您的路由配置会误导维护此代码的开发人员,他们将花几个小时的时间进行艰难的调试,试图弄清楚为什么它会返回405,而app/console debug:router明确表示允许使用GET方法。