Symfony 3,一个应用程序中的 2 个防火墙
Posted
技术标签:
【中文标题】Symfony 3,一个应用程序中的 2 个防火墙【英文标题】:Symfony 3, 2 firewalls in one app 【发布时间】:2016-06-17 07:22:20 【问题描述】:我在 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,
)
);
?>
问题:
-
使用此配置,我无法登录。请求使用登录操作,但系统不想对我进行身份验证。
如果我在 login_firewall 防火墙中取消注释 form_login,身份验证工作正常(我已登录),但我无法访问主页(系统将我重定向到登录页面,尽管我已通过身份验证。
我尝试使用 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
【问题讨论】:
【参考方案1】:修复:
我建议:
-
完全删除 login_firewall。
在您的安全区域中允许匿名用户(匿名:~)
取消注释 access_control 部分(内容看起来不错)
让我知道它是否有效。
替代修复:
(这可能有效,但我不能 100% 确定)。
-
将您的 check_path 更改为其他内容(例如 /check_login)
为 /check_login 创建一个空路由(类似于注销路由,此处描述:Security - Logging out)
(确保这条新路径位于“secured_area”防火墙后面!)
一些解释:
您的问题可能可以通过这个页面来解释:How to Build a Traditional Login Form。上面写着:
如果您使用多个防火墙并针对一个防火墙进行身份验证,则不会自动针对任何其他防火墙进行身份验证。不同的防火墙就像不同的安全系统。
这解释了您的一些问题:如果您在 login_firewall 中取消注释 form_login,您将仅对登录页面进行身份验证!一旦您转到另一个页面,您就不再经过身份验证,因为它是一个不同的安全上下文。
我不能 100% 确定您的问题 1,但它可能会发生,因为您的“check_path”也在防火墙 login_firewall 后面,而不是 secure_area。由于您的 login_firewall 中没有 form_login,因此无法识别提交的登录表单。
【讨论】:
感谢您的第一次修复。一切都很完美。你让我开心:)以上是关于Symfony 3,一个应用程序中的 2 个防火墙的主要内容,如果未能解决你的问题,请参考以下文章