2016-07-05 3 views
1

С Symfony 3 Я использую собственный аутентификатор защиты, который работает правильно, чтобы аутентифицировать пользователя напрямую. Теперь я хочу поддерживать олицетворение пользователей, но при попытке олицетворять пользователя, используя параметр запроса _switch_user, объект getUser() всегда является исходным пользователем.Одобрение пользователей в Symfony при аутентификации с помощью защитника

Моя конфигурация безопасности

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(
 
\t \t  'username' => $username, 
 
     ); 
 
    } 
 

 
    public function getUser($credentials, UserProviderInterface $userProvider) 
 
    { 
 
     $username = $credentials['username']; 
 
     \t 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) 
 
    { 
 
\t \t $data = array(
 
\t \t \t \t 'message' => strtr($exception->getMessageKey(), $exception->getMessageData()) 
 

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

 
\t \t return new JsonResponse($data, 403); 
 
    } 
 

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

 
    public function supportsRememberMe() 
 
    { 
 
     return false; 
 
    } 
 

 
}

Кажется, что getCredentials() мне тод аутентификатора всегда называется, и я не вижу способа обнаружить олицетворение в этом. Итак, мой вопрос заключается в том, могут ли пользователи выдавать себя за использование защитной аутентификации, и если да, то что мне не хватает?

ответ

1

Я нашел способ сделать это, но не полагается на собственную систему switch_user и имеет зависимость от вашей логики приложения.

Принцип является основным, вы реализуете свою собственную систему коммутации на основе два свойств на классе User:

  • IMPERSONATE: значение строки, которая хранит имя пользователя, чтобы быть олицетворением
  • impersonatedBy: строковое значение, которое содержит (без хранения дб) имя пользователя, пользователь делает олицетворения

NB: Вы также может хранить пользователя в этих свойствах (например, сопоставляются с доктриной)

Итак, когда вы говорите ваш охранник аутентификатору для поиска пользователя (GetUser), вы просите UserProvider вернуть пользователь изображал один ($ user-> getImpersonate), добавляя к нему пользователю который делает олицетворение ($ impersonatedUser-> setImpersonatedBy).