一个应用程序中的Symfony 3,2防火墙

时间:2016-03-03 19:20:34

标签: php symfony

我在symfony 3中遇到防火墙问题。从3天开始,我一直在努力解决这个问题。我已经阅读了文档并根据它完成了所有工作,但应用程序并不像我期望的那样工作。

目标:所有页面(登录页面除外)都需要登录用户。如果用户未登录,则应重定向到/登录页面。就是这样。

根据这个页面:

我已经使用登录操作和表单创建了控制器。 login_path和check_path使用相同的操作(根据文档)。 security.yml中的某些内容可能是错误的,因为它无法正常工作。我的设置:

security:
providers:
    in_memory:
        memory:
            users:
                aaa:
                    password: aaa
                    roles: 'ROLE_ADMIN'
encoders:
    Symfony\Component\Security\Core\User\User: plaintext
firewalls:
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false
    login_firewall:
        pattern:    ^/login
        anonymous: ~
#       form_login:
#           login_path: /login
#           check_path: /login
    secured_area:
        pattern:    ^/
        form_login:
            login_path: /login
            check_path: /login
            default_target_path: homepage
        logout:
            path:   /logout
            target: /login
#    access_control:
#        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
#        - { path: ^/, roles: IS_AUTHENTICATED_FULLY }

我的登录操作:

<?php
/**
 * @Route("/login", name="login")
 */
public function loginAction(Request $request)
{
    $authenticationUtils = $this->get('security.authentication_utils');
    // get the login error if there is one
    $error = $authenticationUtils->getLastAuthenticationError();
    // last username entered by the user
    $lastUsername = $authenticationUtils->getLastUsername();

    return $this->render(
        'security/login.html.twig',
        array(
            // last username entered by the user
            'last_username' => $lastUsername,
            'error'         => $error,
        )
    );
}
?>

问题:

  1. 使用此配置我无法登录。请求使用登录操作,但系统不想验证我。
  2. 如果我在login_firewall防火墙中取消注释form_login,身份验证工作正常(我已登录),但我无法访问主页(系统会将我重定向到登录页面,虽然我已经过身份验证。
  3. 我尝试过使用access_control,但行为与2点相同。
  4. 请帮助我。我确信这很简单,但我是Symfony的新手,我看不到它。

    更新

    感谢Tobias Xy我更正了security.yml。工作版:

    security:
        providers:
            in_memory:
                memory:
                    users:
                        smt:
                            password: smt
                            roles: 'ROLE_ADMIN'
        encoders:
            Symfony\Component\Security\Core\User\User: plaintext
        firewalls:
            dev:
                pattern: ^/(_(profiler|wdt)|css|images|js)/
                security: false
            main:
                anonymous: ~
                form_login:
                    login_path: /login
                    check_path: /login
                    default_target_path: /
                logout:
                    path:   /logout
                    target: /login
        access_control:
            - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
            - { path: ^/, roles: IS_AUTHENTICATED_FULLY }
    

1 个答案:

答案 0 :(得分:0)

<强>修正:

我建议:

  1. 完全删除login_firewall。
  2. 允许您的secured_area中的匿名用户(匿名:〜)
  3. 取消注释access_control部分(内容看起来不错)
  4. 让我知道它是否有效。

    替代方案:

    (这可能有用,但我不是百分之百确定)。

    1. 将check_path更改为其他内容(例如/ check_login)
    2. 为/ check_login创建一个空路由(类似于注销路由,如下所述:Security - Logging out
    3. (确保此新路径位于“secured_area”防火墙后面!)
    4. 一些解释

      您可以通过此页面解释您的问题:How to Build a Traditional Login Form。它说:

        

      如果您使用多个防火墙并对一个防火墙进行身份验证,则不会自动对任何其他防火墙进行身份验证。不同的防火墙就像不同的安全系统。

      这解释了您的一些问题:如果您取消注释login_firewall中的form_login,您将只对登录页面进行身份验证!只要您转到另一个页面,就不再进行身份验证,因为它是一个不同的安全上下文。

      我对你的问题1并不是100%肯定,但可能会发生这种情况,因为你的“check_path”也在防火墙login_firewall之后,而不是secure_area。由于您的login_firewall中没有form_login,因此无法识别提交的登录表单。