简体   繁体   English

Symfony 3 - 在我的服务参数中添加 security.authorization_checker 会导致重定向过多

[英]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');

    // ...
  }
}

ERR_TOO_MANY_REDIRECTS

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM