【问题标题】:Symfony http basic auth for dev environment without user authentication无需用户身份验证的开发环境的 Symfony http 基本身份验证
【发布时间】:2017-07-18 12:23:54
【问题描述】:

我有一个常用的 Symfony 应用程序,包括防火墙、用户提供程序和通过表单登录 (FOSUserBundle)、自定义令牌身份验证(对于应用程序),甚至还有一个用于应用程序一部分的 http 基本身份验证。当然,一次只使用其中一个。特定区域由连接到这些提供商的不同防火墙保护。

security.yml 的摘录

security:

    encoders:
        FOS\UserBundle\Model\UserInterface: sha512

    providers:
        authentication_provider:
            entity:
                class: MyAppBundle:User
                property: apiKey
        fos_userbundle:
            id: fos_user.user_provider.username

...

通常在实时系统上没有app_dev.php,因为这是一个巨大的安全漏洞。但如果需要,它也是在实时系统上进行调试的好方法。我的想法是通过额外的 http 基本身份验证来保护开发环境。这样开发环境仍然是安全的,但您可以在需要时访问它。

但不幸的是,我无法让它工作,因为一旦您将 http 基本身份验证添加到站点并登录,您的用户就会通过 Symfony 应用程序的身份验证。这当然是首先进行身份验证的漏洞点,但是对于这个想法来说是一个交易破坏者,因为应用程序无法区分表单登录用户和基本身份验证用户(我知道我可以区分用户类型但是这将是一个额外的复杂层,我不愿意添加,因为它必须在洞应用程序中进行检查)。

我的问题是是否可以在没有身份验证部分的情况下使用 Symfony 原生 http 基本身份验证。因此,在完成基本身份验证后,浏览器仍在发送 http 基本身份验证,但您仍然是匿名的,并且仍然必须通过表单(例如)登录才能进行身份验证并访问其他受限内容。

编辑:我知道有一些方法可以在 Symfony 之外的服务器配置中进行配置,例如在 Apache 中,但我正在寻找一个 Symfony 解决方案(无需托管更改,包括在本地工作,可以推送到源代码控制, ...)

编辑 2:经过深入研究,我发现所有身份验证过程都必须返回某种令牌。所以它可能不像仅仅覆盖一个提供者并返回一个匿名令牌那么简单。

【问题讨论】:

    标签: php symfony security authentication basic-authentication


    【解决方案1】:

    这里是如何配置它:

    security:
        providers:
            api_users_in_memory:
               memory:
                  users:
                      test:
                          password: qwerty
        encoders:
            Symfony\Component\Security\Core\User\User: plaintext
        firewalls:
            api:
              pattern: ^/api
              stateless: true
              http_basic:
                provider: api_users_in_memory
    

    【讨论】:

      【解决方案2】:

      显然,由于漏洞安全组件的构建方式,无法存档搜索结果。他们都扭转了有一个经过身份验证的用户的想法。没有它,所涉及的组件就没有任何意义。

      经过数小时的反复试验,我找到了替代解决方案。我为此用例添加了一个单独的环境debugging。它在AppKernel.php 中将debug 标志设置为true。配置和安全组件看起来类似于dev 环境,但有以下更改:

      ``

      config_debugging.yml

      imports:
          - { resource: config.yml }
          - { resource: security_debugging.yml }
          - ...
      
      services:
          my.debugging.exception_listener:
              class: My\Bundle\AppBundle\EventListener\DebuggingExceptionListener
              tags:
                  - { name: kernel.event_listener, event: kernel.exception }
          my.debugging.access_listener:
              class: My\Bundle\AppBundle\EventListener\DebuggingAccessListener
              tags:
                  - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
              arguments: [ '@security.authorization_checker', '@security.token_storage' ]
      

      security_debugging.yml

      security:
          firewalls:
              app_resources:
                  pattern:  ^/(_(profiler|wdt)|css|images|js)/
                  security: false
              ...
              main:
                  pattern: ^/
                  http_basic:
                      provider: fos_userbundle
      
      
          access_control:
              - { path: ^/admin/, role: ROLE_ADMIN }
              - { path: ^/, role: ROLE_DEBUGGING }
      
          role_hierarchy:
              ROLE_ADMIN:         [ROLE_USER,ROLE_DEBUGGING,ROLE_SONATA_ADMIN]
              ROLE_SUPER_ADMIN:   ROLE_ADMIN
      

      两个监听器在那里检查正确的角色ROLE_DEBUGGING。然后每个管理员都可以登录,并且在调试特定用户时,必须为该用户设置特定的角色。

      DebuggingExceptionListener.php

      ...
      public function onKernelException(GetResponseForExceptionEvent $event)
      {
          // You get the exception object from the received event
          $exception = $event->getException();
      
          if ($exception instanceof AccessDeniedHttpException) {
              $event->setResponse(new RedirectResponse('/'));
          }
      }
      ...
      

      DebuggingAccessListener.php

      ...
      public function onKernelRequest(GetResponseEvent $event)
      {
          if (!$event->isMasterRequest()) {
              return;
          }
      
          if ($this->tokenStorage->getToken() === null) {
              return;
          }
      
          if ($this->authorizationChecker->isGranted('ROLE_DEBUGGING')) {
              return;
          }
      
          $event->setResponse(new RedirectResponse('/'));
      }
      ...
      

      通过这种方式,几乎可以检查仍然由登录保护的漏洞应用程序。不可能调试所有涉及常用登录组件或任何 AccessDeniedHttpExceptions 的组件。但就目前而言,这是我能想到的最佳解决方案。我仍然希望有更好的解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-03
        • 2021-10-10
        • 2019-03-01
        • 1970-01-01
        • 2021-03-21
        • 2011-11-12
        • 2011-05-05
        • 1970-01-01
        相关资源
        最近更新 更多