[英]Symfony 3 - Add security.authorization_checker in my service 's args cause too many redirects
I try to create custom listener in my Symfony 3 app.我尝试在我的 Symfony 3 应用程序中创建自定义侦听器。
I want to check if user is IS_AUTHENTICATED_FULLY or not.我想检查用户是否是 IS_AUTHENTICATED_FULLY。
When I add @security.authorization_checker service as arg to mine I get "too many redirect error" to my login route当我将 @security.authorization_checker 服务作为 arg 添加到我的我的登录路由时,我收到“太多重定向错误”
Does anyone have a working solution in Symfony 3?有没有人在 Symfony 3 中有一个可行的解决方案?
security.yml:安全.yml:
security:
providers:
main:
entity:
class: Customer\CustomerBundle\Entity\utilisateur
property: loginUtil
encoders:
Customer\CustomerBundle\Entity\utilisateur:
algorithm: sha1
encode_as_base64: false
iterations: 1
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
Customer_firewall:
pattern: ^/
anonymous: true
provider: main
form_login:
login_path: /login
check_path: /login_check
logout:
path: /logout
target: Customer_standard_homepage
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/reset, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/profile, roles: ROLE_USER }
role_hierarchy:
ROLE_ADMIN : [ROLE_USER]
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
Services.yml服务.yml
services:
login_listener:
class: 'Customer\CustomerBundle\Listener\LoginListener'
arguments: ['@security.authorization_checker', '@doctrine']
tags:
- { name: 'kernel.event_listener', event: 'security.authentication.success', method: onSecurityAuthentication }
LoginListener.php登录监听器.php
<?php
namespace Customer\CustomerBundle\Listener;
use Symfony\Component\Security\Core\Event\AuthenticationEvent;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
/**
* Custom login listener.
*/
class LoginListener
{
private $authorizationChecker;
private $em;
public function __construct(AuthorizationChecker $authorizationChecker, Doctrine $doctrine)
{
$this->authorizationChecker = $authorizationChecker;
$this->em = $doctrine->getEntityManager();
}
/**
* Do the magic.
*
* @param InteractiveLoginEvent $event
*/
public function onSecurityAuthentication(AuthenticationEvent $event)
{
if ($this->authorizationChecker->isGranted('IS_AUTHENTICATED_FULLY')) {
// user has just logged in
error_log('here');
}
if ($this->authorizationChecker->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
// user has logged in using remember_me cookie
error_log('there');
}
// do some other magic here
$user = $event->getAuthenticationToken()->getUser();
error_log('FINALLY HERE');
// ...
}
}
You can use the access decission manager like this:您可以像这样使用访问决策管理器:
use Symfony\Bridge\Doctrine\RegistryInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Event\AuthenticationEvent;
class LoginListener
{
private $accessDecisionManager;
private $doctrine;
public function __construct(AccessDecisionManagerInterface $accessDecisionManager, RegistryInterface $doctrine)
{
$this->accessDecisionManager = $accessDecisionManager;
$this->doctrine = $doctrine;
}
/**
* Do the magic.
*
* @param AuthenticationEvent $event
*/
public function onSecurityAuthentication(AuthenticationEvent $event)
{
$em = $this->doctrine->getEntityManager();
if ($this->accessDecisionManager->decide($event->getAuthenticationToken(), ['IS_AUTHENTICATED_FULLY'])) {
error_log('here');
}
if ($this->accessDecisionManager->decide($event->getAuthenticationToken(), ['IS_AUTHENTICATED_REMEMBERED'])) {
// user has logged in using remember_me cookie
error_log('there');
}
// do some other magic here
$user = $event->getAuthenticationToken()->getUser();
error_log('FINALLY HERE');
// ...
}
}
And the service definition has to be changed to this:并且服务定义必须更改为:
login_listener:
class: 'Customer\CustomerBundle\Listener\LoginListener'
arguments: ['@security.access.decision_manager', '@doctrine']
tags:
- { name: 'kernel.event_listener', event: 'security.authentication.success', method: onSecurityAuthentication }
I also changed the constructor a bit, in general when using dependency injection it is good practice to reference an interface if possible.我还稍微改变了构造函数,一般来说,在使用依赖注入时,如果可能的话,最好引用一个接口。 Also the constructor should not do too much stuff (I removed the call to
getEntityManger()
and moved id into the listener).此外,构造函数不应做太多事情(我删除了对
getEntityManger()
的调用并将 id 移到侦听器中)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.