Symfony2.1: 找不到路径“/login_check”的控制器。

14

我使用了symfony.com上的"使用传统登录表单"教程来验证我的用户。通过简单的http身份验证,它非常有效。

在提交登录后,我收到了以下异常:

无法找到路径“/login_check”的控制器。也许您忘记在路由配置中添加匹配的路由了?

好吧,在我阅读的教程中:

您不需要为/login_check URL实现一个控制器,因为防火墙会自动捕获和处理提交到该URL的任何表单。

我定义了路由并设置了防火墙设置:

security.yml

firewalls:
    dev:
        pattern:  ^/(_(profiler|wdt)|css|images|js)/
        security: false
    backend:
        pattern:    ^/backend
        anonymous: ~
        form_login:
            provider: entity
            login_path: /login
            check_path: /login_check
            #use_forward: true
        logout:
            path:   /logout
            target: /

routing.yml

login:
    pattern:   /login
    defaults:  { _controller: VitaSecurityBundle:Default:login }
login_check:
    pattern:   /login_check
logout:
    pattern:   /logout

登录表单只是用来允许访问后端吗? - Bgi
是的,这仅适用于后端用户。 - falsch
不错的解决方案。我也遇到了完全相同的问题。你应该将你的解决方案发布为答案并接受它,这样更容易找到。 :) - insertusernamehere
5个回答

18
您遇到的问题在这里进行了描述:
请参阅http://symfony.com/doc/current/book/security.html,查看“避免常见陷阱”一节。
  1. 确保/login_check位于防火墙后面
  2. 接下来,请确保您的check_path URL(例如/login_check)位于您表单登录使用的防火墙后面(在本例中,单个防火墙匹配所有URL,包括/login_check)。 如果/login_check不匹配任何防火墙,则会收到“无法找到路径“/login_check”的控制器”的异常。
在此示例中,您的模式指定受保护路径的前缀为/backend。 为使其有效,请将登录检查放置在相同的防火墙后面。
因此,为了匹配您在防火墙中指定的模式,请将login_check放置在以下url路径上:/backend/login_check

不错的发现。来自Google Groups帖子的Christophe Coevoet也说:“安全侦听器仅在请求与防火墙的模式匹配时附加。因此,您需要使用形式为/admin/logout的URL才能处于侦听器的范围内。” - targnation
新手错误/陷阱:请注意,如果您有^/和^/admin并且需要两个登录表单,则更具体的模式(^/admin)必须在文件中位于更一般的模式^/之上,否则它不会优先考虑,因为^/仍然可以匹配^/admin - 至少,在我的应用程序中,这是最终使其工作的原因,我需要两个登录表单,并且已经在security.yml中有了一个^/模式,而我没有意识到这就是yml处理正则表达式优先级的方式。 - Mick

8

我找到了解决问题的方法

我在路径中添加了“/backend”前缀,删除了“anonymous: ~”行并注释掉了后端的ACL。

security.yml

    firewalls:
    dev:
        pattern:  ^/(_(profiler|wdt)|css|images|js)/
        security: false
    login_firewall:
        pattern:    ^/backend/login$
        anonymous:  ~
    backend:
        pattern:    ^/backend
        form_login:
            provider: entity
            login_path: /backend/login
            check_path: /backend/login_check
            #use_forward: true
        logout:
            path:   /backend/logout
            target: /

access_control:
    #- { path: ^/backend, roles: ROLE_USER }

routing.yml

login:
    pattern:   /backend/login
    defaults:  { _controller: VitaSecurityBundle:Default:login }
login_check:
    pattern:   /backend/login_check
logout:
    pattern:   /backend/logout

1
问题也经常会发生在您拥有两个具有相同模式的防火墙时。例如:
....
 backend:
            pattern:        ^/*
....
 frontend:
            pattern:        ^/*

你必须按以下方式更改其中之一:

....
 backend:
            pattern:        ^/(administrador|backend)/*
....
frontend:
            pattern:        ^/*

0

这是我在一个真实项目中使用的示例代码:

firewalls:
    dev:
        pattern:  ^/(_(profiler|wdt)|css|images|js)/
        security: false

    secured_area:
        pattern:    ^/cmd
        anonymous: ~
        form_login:
            check_path: /cmd/login_check
            login_path: /cmd/login
        remember_me:
            always_remember_me: true
            key:      "%secret%"
            path:     /cmd
            domain:   ~ # Defaults to the current domain from $_SERVER
        logout:
            path:   /cmd/logout
            target: /

    admin:
        pattern: ^/admin
        http_basic:
            realm: "Administration"

    free_area:
        pattern: ^/
        anonymous: ~

在我的情况下,只有/cmd/部分是安全的,/admin/部分也是安全的,但是使用HTTP安全性。
也许你应该尝试: security.yml
firewalls:
    dev:
        pattern:  ^/(_(profiler|wdt)|css|images|js)/
        security: false
    backend:
        pattern:    ^/backend
        anonymous: ~
        form_login:
            provider: entity
            login_path: /backend/login
            check_path: /backend/login_check
            #use_forward: true
        logout:
            path:   /backend/logout
            target: /

至于routing.yml:

login:
    pattern:   /backend/login
    defaults:  { _controller: VitaSecurityBundle:Default:login }
login_check:
    pattern:   /backend/login_check
logout:
    pattern:   /backend/logout

我认为你的问题可能是因为你的 / 部分没有激活安全性(你的安全区域模式是 ^/backend)


谢谢!我尝试了一下,已经找到一个解决方案(我编辑了我的初始帖子)。 - falsch

0

这对我没有用,我尝试了其他方法:

firewalls:
    dev:
        pattern:    ^/(_profiler|_wdt|css|js)
        security:   false

    login:
        pattern: ^/login$
        security: false

    secured_area:
        pattern: /(admin/.*|login_check)
        provider: in_memory
        form_login:
            check_path: /login_check
            login_path: /login
            default_target_path: /admin
            always_use_default_target_path: true
        logout:
            path:   /logout
            target: /

access_control:
    - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/, roles: ROLE_ADMIN }

通过以下的解释,比zabojad的解释更简单。 重要的是将login_check路由放在防火墙内,并让登录在外面。使用或模式可以成功。
Max

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接