我在symfony 3中的防火墙有问题。从 3 天开始,我一直在为此苦苦挣扎。我已经阅读了文档并根据它做了所有事情,但是应用程序没有按我预期工作。
目标:所有页面(登录页面除外)都需要登录用户。如果用户未登录,则应重定向到/login页面。就这样。
根据此页面:
- http://symfony.com/doc/current/book/security.html
- http://symfony.com/doc/current/cookbook/security/form_login_setup.html
我已经创建了具有登录操作和表单的控制器。 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,
)
);
}
?>
问题:
- 使用此配置,我无法登录。请求使用登录操作,但系统不想对我进行身份验证。
- 如果我在防火墙中取消注释form_login login_firewall身份验证,身份验证工作正常(我已登录),但我无法访问主页(尽管我已通过身份验证,但系统会将我重定向到登录页面。
- 我尝试使用access_control,但行为与 2 点相同。
请帮我。我确定这是一件简单的事情,但我是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 }
修复:
我建议:
- 完全删除login_firewall。
- 允许匿名用户进入您的secured_area(匿名:~)
- 取消注释access_control部分(内容看起来不错)
让我知道它是否有效。
替代修复:
(这可能有效,但我不是 100% 确定)。
- 将您的check_path更改为其他内容(例如/check_login)
- 为/check_login 创建一个空路由(类似于注销路由,如下所述:安全性 - 注销)
- (确保此新路径位于"secured_area"防火墙后面!
一些解释:
您的问题可能可以通过此页面来解释:如何构建传统的登录表单。那里说:
如果使用多个防火墙,并且针对一个防火墙进行身份验证,则不会自动针对任何其他防火墙进行身份验证。不同的防火墙就像不同的安全系统。
这解释了您的一些问题:如果您取消注释login_firewall中的form_login,您将仅对登录页面进行身份验证!一旦转到另一个页面,您将不再进行身份验证,因为它是不同的安全上下文。
我不是 100% 确定您的问题 1,但它可能会发生,因为您的"check_path"也在防火墙后面login_firewall而不是secured_area。由于您的login_firewall中没有form_login,因此无法识别提交的登录表单。