我正在使用 Symfony 2.8.x 应用程序,我需要设置两个安全区域:chat
和admin
. 这意味着chat
并且admin
将使用相同的登录模板(如果可能并且我不需要为此设置不同的登录模板)。我在这里问之前用谷歌搜索过,有一些相关的东西出现了,我读了很多关于这个话题的帖子:1 , 2 , 3 , 4只是作为其中的一个例子,但我做错了,因为我不能让它正常工作。这是/app/config/security.yml
看起来的样子(只是防火墙和 access_control 一段代码):
security:
....
firewalls:
admin:
pattern: /admin/(.*)
anonymous: ~
form_login:
provider: fos_userbundle
csrf_provider: security.csrf.token_manager
login_path: fos_user_security_login
check_path: fos_user_security_check
use_forward: true
always_use_default_target_path: true
default_target_path: /admin
target_path_parameter: _target_path
use_referer: true
remember_me: true
logout:
target: /admin
remember_me:
secret: '%secret%'
lifetime: 604800 # 1 week in seconds
path: /
chat:
pattern: ^/chat/(.*)
anonymous: ~
form_login:
provider: fos_userbundle
csrf_provider: security.csrf.token_manager
login_path: fos_user_security_login
check_path: fos_user_security_check
use_forward: true
always_use_default_target_path: true
default_target_path: /chat
target_path_parameter: _target_path
use_referer: true
remember_me: true
logout: ~
remember_me:
secret: '%secret%'
lifetime: 604800 # 1 week in seconds
path: /
access_control:
- { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/resetting$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/chat/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/chat/resetting$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/chat/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/chat/, role: ROLE_CHATTER }
- { path: ^/admin/, role: ROLE_ADMIN }
现在这是我的捆绑包的配置app/config/routing.yml
:
platform_chat:
resource: "@PlatformChatBundle/Controller/"
type: annotation
prefix: /chat/
options:
expose: true
platform_admin:
resource: "@PlatformAdminBundle/Controller/"
type: annotation
prefix: /admin/
options:
expose: true
因为FOSUserBundle
我已经尝试了这两个(都没有成功,而且一次都没有):
#FOSUser
fos_user:
resource: "@FOSUserBundle/Resources/config/routing/all.xml"
#FOSUser
# this second causes doubts to me since I think I will need
# to repeat the same routes for chat prefix but I'm not sure at all
fos_user_security:
resource: "@FOSUserBundle/Resources/config/routing/security.xml"
prefix: /admin
fos_user_profile:
resource: "@FOSUserBundle/Resources/config/routing/profile.xml"
prefix: /admin/profile
fos_user_register:
resource: "@FOSUserBundle/Resources/config/routing/registration.xml"
prefix: /admin/register
fos_user_resetting:
resource: "@FOSUserBundle/Resources/config/routing/resetting.xml"
prefix: /admin/resetting
fos_user_change_password:
resource: "@FOSUserBundle/Resources/config/routing/change_password.xml"
prefix: /admin/profile
我已经覆盖了登录模板app/Resources/FOSUserBundle/views/Security/login.html.twig
。(如果需要来源,我可以只提供 ommit 以使帖子不再比现在长)。
当我调用 URL:http://domain.tld/app_dev.php/admin
并尝试登录时,出现此错误:
找不到翻译。上下文:{“id”:“Symfony\Component\Security\Core\Exception\BadCredentialsException:凭据错误。在 /var/www/html/platform-cm/vendor/symfony/symfony/src/Symfony/Component/Security/Core /Authentication/Provider/UserAuthenticationProvider.php:90\n堆栈跟踪:\n#0
(如果需要,我可以提供完整的堆栈跟踪)
这对我来说很奇怪,但可能是由于我仔细检查了凭据而导致配置错误。
当我调用 URL:http://domain.tld/app_dev.php/chat
并尝试登录时,我得到了Access Denied
但这是正确的,因为我被重定向到http://domain.tld/app_dev.php/admin/
. 任何人都可以给我一些关于这个配置的帮助吗?我被卡住了,因此无法前进
第二种方法
这是基于@heah 建议使用侦听器的第二种方法,但也不起作用我仍然收到相同的“错误凭据”消息并且根本无法登录。我改回了routing.yml
这个:
#FOSUser
fos_user:
resource: "@FOSUserBundle/Resources/config/routing/all.xml"
我改回了security.yml
这个:
安全性:...防火墙:管理员:模式:^/匿名:〜form_login:提供者:fos_userbundle csrf_provider:security.csrf.token_manager login_path:fos_user_security_login check_path:fos_user_security_check
# if true, forward the user to the login form instead of redirecting
use_forward: true
# login success redirecting options (read further below)
always_use_default_target_path: true
default_target_path: /admin
target_path_parameter: _target_path
use_referer: true
remember_me: true
logout:
target: /admin
remember_me:
secret: '%secret%'
lifetime: 604800 # 1 week in seconds
path: /
access_control:
- { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/resetting$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/chat/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/chat/resetting$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/chat/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/chat/, role: ROLE_CHATTER }
- { path: ^/admin/, role: ROLE_ADMIN }
security.interactive_login
然后我按照以下建议为事件定义了一个侦听器app/config/config.yml
:
parameters:
account.security_listener.class: PlatformAdminBundle\Listener\SecurityListener
然后在app/config/services.yml
:
services:
account.security_listener:
class: %account.security_listener.class%
arguments: ['@security.context', '@session']
tags:
- { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin }
最后是类定义src/PlatformAdminBundle/Listener/SecurityListener.php
:
namespace PlatformAdminBundle\Listener;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class SecurityListener
{
public function __construct(SecurityContextInterface $security, Session $session)
{
$this->security = $security;
$this->session = $session;
}
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
$user = $this->security->getToken()->getUser();
var_export($user);
}
}
我再次遇到同样的问题,也许我做错了什么,我没有看到,但我接受任何想法。这里有什么问题?
第三种方法
我已经对我的代码进行了审查,并根据@heah 的建议对其进行了轻微更改。所以,现在security.yml
如下:
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/chat/, role: ROLE_CHATTER }
- { path: ^/admin/, role: ROLE_ADMIN }
尽管我根本没有使用它,但在 Symfony 2.6+ 中的更改services.yml
基本上是修复了参数:security.context
services:
...
account.security_listener:
class: %account.security_listener.class%
arguments: ['@security.authorization_checker']
tags:
- { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin }
最后是课堂上的变化PlatformAdminBundle/Listener/SecurityListener.php
:
namespace Clanmovil\PlatformAdminBundle\Listener;
use Symfony\Component\Finder\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class SecurityListener
{
public function __construct(AuthorizationCheckerInterface $authorizationChecker)
{
$this->security = $authorizationChecker;
}
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
if ($this->security->isGranted('ROLE_ADMIN')) {
// this is something for testing
throw new AccessDeniedException(
'Access Denied. You are ADMIN'
);
} elseif ($this->security->isGranted('ROLE_CHATTER')) {
// this is something for testing
throw new AccessDeniedException(
'Access Denied. You are CHATTER'
);
}
}
}
当我以用户身份登录时ROLE_CHATTER
似乎一切正常,因为我得到了 AccessDenied 异常,但是当我尝试以用户身份登录时ROLE_ADMIN
它停止工作,我回到最初的错误:Bad credentials
,这是为什么?我快疯了!!