没有用户身份验证的开发环境的Symfony http basic auth

时间:2017-07-18 12:23:54

标签: php symfony security authentication http-basic-authentication

我有一个常见的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 basic auth,但您仍然是匿名的,并且仍然必须通过表单(例如)进行身份验证,并且可以访问其他受限制的内容。

编辑:我知道有很多方法可以在服务器配置中像在Apache中那样在Symfony之外配置它,但是我正在搜索Symfony解决方案(无需托管更改,包括本地,可以推送到源代码控制, ...)

编辑2:经过深度挖掘后,我发现所有身份验证过程都必须返回某种令牌。因此,它可能不仅仅是覆盖提供者并返回Anonymus令牌。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:-1)

显然,由于洞穴安全组件的构建方式,无法归档搜索结果。他们都认为有一个用户经过身份验证。如果没有它,所涉及的组件就没有意义。

经过数小时的追踪和错误,我找到了另一种解决方案。我为此用例添加了单独的环境debugging。它在debug中将AppKernel.php标志设置为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的所有组件。但就目前而言,这是我能提出的最佳解决方案。我仍然希望有更好的解决方案。