Symfony4安全性中的两种认证方法

时间:2018-07-27 09:53:23

标签: symfony symfony4

我想要在应用程序中使用两种身份验证方法。

一个用于实体User,另一个用于(admin)具有明文。

非常简单。

因此,当我配置security.yaml时,我指定了提供程序:

security:
    providers:
        user:
            entity:
                class: App\Entity\User
                property: username
        in_memory: 
            memory: 
                users:
                    admin:
                        password: admin
                        roles: 'ROLE_ADMIN'

    encoders:
        App\Entity\User: bcrypt
        Symfony\Component\Security\Core\User\User: plaintext

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        admin: 
            provider: in_memory
            pattern: ^/admin/
            guard:
                provider: in_memory
            form_login:
                login_path: admin_login
                check_path: admin_login
            logout:
                path: /admin/logout
                target: /
        default:
            provider: user
            anonymous: ~
            guard:
                provider: user
            form_login:
                login_path: login
                check_path: login
                default_target_path: login_redirect
                use_referer: true
            logout:
                path: /logout
                target: /

    access_control:
        - { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin, roles: ROLE_ADMIN }
        - { path: ^/dashboard, roles: ROLE_USER }

并返回错误:

In GuardAuthenticationFactory.php line 121:

  Because you have multiple guard configurators, you need to set the "guard.e  
  ntry_point" key to one of your configurators ()     

然后,如果我必须设置guard.entry_point,则需要执行以下操作:

admin:
    entry_point: app.form_admin_authenticator
main:
    entry_point: app.form_user_authenticator

因此,如果我不感兴趣,则需要像下面这样配置身份验证侦听器:https://symfony.com/doc/current/components/security/authentication.html (顺便说一句,这个特定的帮助页面非常模糊且不完整)

有必要吗?对于我来说,这似乎太复杂了

1 个答案:

答案 0 :(得分:1)

我遇到了这个特殊错误。我的情况可能有所不同,但是根据应用程序的入口点,我也需要使用不同的身份验证策略进行身份验证。

您的配置不包含的一件事是对任何Guard Authenticator对象的引用。 See this documentation for an intro to what role those objects play, and how to define them. Symfony的Security程序包非常复杂,我发现使用Guard Authenticators使我的用例过程变得更加简单。

这里是一个security.yaml配置的示例,该配置引用了两个不同的身份验证器。 entry_point配置告诉Symfony 最先尝试哪个,因为在我的特殊情况下,Symfony否则将不知道首先对传入请求应用哪种身份验证策略。

security:
    providers:
        user:
            id: App\My\UserProviderClass

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: ~
            logout:
                path: app_logout

            guard:
                entry_point: App\My\MainAuthenticator
                authenticators:
                    - App\My\MainAuthenticator
                    - App\My\OtherAuthenticator

Custom Guard身份验证器contain a method called supports。此方法将传入请求作为唯一参数,并根据是否将给定的身份验证器应用于传入请求,返回true或false。常见的做法可能是检查请求的Symfony路由名称(由控制器定义),或者检查请求的完整URI。例如:

    /**
     * Does the authenticator support the given Request?
     *
     * If this returns false, the authenticator will be skipped.
     *
     * @param Request $request
     *
     * @return bool
     */
    public function supports(Request $request): bool
    {
        $matchesMyRoute = 'some_route_name' ===
            $request->attributes->get('_route');

        $matchesMyUri = '/path/to/secured/resource' ===
            $request->getUri();

        return $matchesMyRoute || $matchesMyUri;
    }

您可以想象,如果同一个应用程序中存在多个Guard Authenticator,则可能是仅希望它们应用于某种类型的请求,而区分是否基于所应用的auth的类型(例如, (带有API密钥的标头与有状态会话Cookie的标头),区别是否更多在于所命中的特定路由,或者可能是多种因素的组合。

在这种情况下,告诉Symfony首先尝试使用哪个Guard Authenticator可能对您的安全策略很重要,或者可能会对性能造成影响。例如,如果您有两个身份验证者,一个必须访问数据库以验证有状态会话,但是另一个可以无状态地验证请求的身份验证,例如。通过验证JWT的签名,您可能希望首先运行JWT身份验证器,因为它可能不需要往返数据库即可对请求进行身份验证。

请参阅本文以获取更深入的说明:https://symfonycasts.com/screencast/symfony-security/entry-point