在身份验证之前侦听请求或在symfony3

时间:2017-05-05 06:45:21

标签: php symfony fosuserbundle

我正在尝试注册一个eventListener,它会在/ login_check尝试登录用户之前调用。

我正在编写DDoS保护,iIlog在数据库中每次尝试(date,user_id,is_failure),如果用户有多于N个错误的登录尝试,我会生成通过电子邮件发送到正确的用户电子邮件的令牌。没有此令牌的任何人都将被禁止在10分钟内尝试其他登录。

要继续,我需要:

  • 能够在/ login_check
  • 的开头注册一个eventListener
  • 能够重写/ login_check以添加事件

我没有发现任何关于“pre_authentication”的事件,你有解决方案吗?

我不会在存储库方法中编写代码来管理用户,这不是它的位置。

由于

1 个答案:

答案 0 :(得分:2)

几天前我遇到过类似的问题。就像你说的那样,我找不到合适的" pre_authentication"要么在此之前我甚至可以在尝试进行身份验证之前执行我的检查。 (AuthenticationSuccess和AuthenticationFailure Handler在我的情况下不是一个选项,因为我想在尝试之前阻止尝试)

但最后我发现了一种在我的情况下有效的方法(尽管可能有更好的方法,但我无法找到它)。

如果您的应用程序使用默认的用户名/密码身份验证,则可以执行以下操作:

  1. 扩展UsernamePasswordFormAuthenticationListener

    class UsernamePasswordFormAuthenticationListener extends \Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener
    
    {
        /** @var EntityManagerInterface */
        protected $entityManager;
    
        /**
         * setter is called through DI container
         *
         * @param EntityManagerInterface $entityManager
         */
        public function setEntityManager(EntityManagerInterface $entityManager)
        {
            $this->entityManager = $entityManager;
        }
    
        /**
         *
         * @param Request $request
         *
         * @return null|RedirectResponse|\Symfony\Component\HttpFoundation\Response|\Symfony\Component\Security\Core\Authentication\Token\TokenInterface
         */
        protected function attemptAuthentication(Request $request)
        {
            //do your logic and whatnot here
            // i.E. return a redirect repsonse if the token is needed but missing 
    
            return parent::attemptAuthentication($request);
        }
    
    }
    
  2. 覆盖services.yml中的原始服务

    security.authentication.listener.form:
        class: AppBundle\Listener\UsernamePasswordFormAuthenticationListener
        parent: security.authentication.listener.abstract
        abstract: true
        calls: [ [setEntityManager, ["@doctrine.orm.entity_manager"]] ] 
    
  3. (这里使用setter注入,因为构造函数需要大量的参数)

    也许这种方法可以满足您的需求,没有人有更好的主意