在使用警卫

时间:2016-07-05 06:35:49

标签: symfony authentication impersonation

使用Symfony 3我使用正确运行的自定义防护验证器直接验证用户。我现在想支持用户模拟,但在尝试使用_switch_user查询参数模拟用户时,getUser()对象始终是原始用户。

我的安全配置是



security:

    encoders:
        Symfony\Component\Security\Core\User\User: plaintext

    providers:
        app:
            entity:
                class: AppBundle:Authentication
                property: username

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

        main:
            anonymous: ~
            switch_user: true
            guard:
                authenticators:
                    - app.authenticator

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    access_control:
        - { path: ^/admin/, role: ROLE_ADMIN }
        - { path: ^/, role: ROLE_USER }
​




我的身份验证员



class AppAuthenticator extends AbstractGuardAuthenticator
{
    public function getCredentials(Request $request)
    {
        $username = $request->query->get('username');
        if (empty($username)) {
            return;
        }

        return array(
		    'username' => $username,
        );
    }

    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        $username = $credentials['username'];
       	return $userProvider->loadUserByUsername($username);
     }

    public function checkCredentials($credentials, UserInterface $user)
    {
        return true;
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
        return null;
    }

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
    {
		$data = array(
				'message' => strtr($exception->getMessageKey(), $exception->getMessageData())

				// or to translate this message
				// $this->translator->trans($exception->getMessageKey(), $exception->getMessageData())
		);

		return new JsonResponse($data, 403);
    }

    public function start(Request $request, AuthenticationException $authException = null)
    {
        return new RedirectResponse(
            ...
            )
    }

    public function supportsRememberMe()
    {
        return false;
    }

}




似乎总是调用身份验证器的getCredentials()方法,我看不到在这里检测模拟。所以,我的问题是用户在使用防护身份验证时是否会被模仿,如果是,我错过了什么?

1 个答案:

答案 0 :(得分:1)

我找到了一种方法,但它不依赖于原生的switch_user系统,并且依赖于您的应用程序逻辑。

原则是基本的,您可以根据User类的两个属性实现自己的切换系统:

  • 模拟:一个字符串值,用于存储要模拟的用户的用户名
  • impersonatedBy :包含(无数据存储空间)用户进行模拟的用户名的字符串值

注意:您还可以将用户存储在这些属性中(例如,使用Doctrine映射)

因此,当您告诉您的警卫验证员搜索用户( getUser )时,您要求UserProvider返回用户的模拟者($ user-> getImpersonate),并向其添加进行模仿的用户($ impersonatedUser-> setImpersonatedBy)。