我正在尝试在使用 Apache 的 auth_kerb 进行身份验证的应用程序上设置 switch_user 功能。REMOTE_USER
正确返回并能够登录。但是,当我尝试伪装成其他用户时,我无法登录。我希望切换到的用户确实存在于应用程序中。发生切换用户的尝试,但再次调用预身份验证并REMOTE_USER
加载初始身份验证。
关于如何使用 remote_user 和自定义用户提供程序让 switch_user 工作的任何想法?
安全.yml
security:
providers:
webservice_user_provider:
id: webservice_user_provider
...
firewalls:
secured_area:
switch_user: { role: ROLE_ALLOWED_TO_SWITCH, parameter: _masquerade }
pattern: ^/
remote_user:
provider: webservice_user_provider
...
服务.yml
parameters:
account.security_listener.class: Acme\MyUserBundle\Listener\SecurityListener
services:
account.security_listener:
class: %account.security_listener.class%
arguments: ['@security.authorization_checker', '@session', '@doctrine.orm.entity_manager', '@router', '@event_dispatcher']
tags:
- { name: kernel.event_listener, event: security.authentication.failure, method: onAuthenticationFailure }
- { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin }
- { name: kernel.event_listener, event: security.switch_user, method: onSecuritySwitchUser }
webservice_user_provider:
class: Acme\MyUserBundle\Security\User\WebserviceUserProvider
calls:
- [setEntityManager , ['@logger', '@doctrine.orm.entity_manager']]
...
安全监听器.php
namespace Acme\MyUserBundle\Listener;
use ...
/**
* Class SecurityListener
* @package Acme\MyUserBundle\Listener
*/
class SecurityListener {
protected $session;
protected $security;
protected $em;
protected $router;
protected $dispatcher;
public function __construct(
AuthorizationCheckerInterface $security,
Session $session,
EntityManager $em,
UrlGeneratorInterface $router,
EventDispatcherInterface $dispatcher
// TraceableEventDispatcher $dispatcher
// ContainerAwareEventDispatcher $dispatcher
) {
$this->security = $security;
$this->session = $session;
$this->em = $em;
$this->router = $router;
$this->dispatcher = $dispatcher;
}
/**
*
* @param AuthenticationFailureEvent $event
* @throws AuthenticationException
*/
public function onAuthenticationFailure(AuthenticationFailureEvent $event) {
throw new AuthenticationException($event->getAuthenticationException());
}
/**
* @param InteractiveLoginEvent $event
*/
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) {
// set some defaults...
}
/**
* @param SwitchUserEvent $event
*/
public function onSecuritySwitchUser(SwitchUserEvent $event) {
$this->dispatcher->addListener(KernelEvents::RESPONSE, array($this, 'onSwitchUserResponse'));
}
/**
* @param FilterResponseEvent $event
*/
public function onSwitchUserResponse(FilterResponseEvent $event) {
$response = new RedirectResponse($this->router->generate('acme_mybundle_default_index'));
$event->setResponse($response);
}
}
WebServiceProvider.php
namespace Acme\MyUserBundle\Security\User;
use ...
class WebserviceUserProvider implements UserProviderInterface {
protected $entityManager;
protected $logger;
/**
*
* @param LoggerInterface $logger
* @param EntityManager $em
*/
public function setEntityManager(LoggerInterface $logger, EntityManager $em) {
$this->logger = $logger;
$this->entityManager = $em;
}
/**
*
* @param string $username
* @return Person
* @throws UsernameNotFoundException
*/
public function loadUserByUsername($username) {
# Find the person
$person = $this->entityManager->getRepository('AcmeMyBundle:Person')
->find($username);
if ($person) {
$this->logger->debug("Logged in, finding person: " . $person->getUsername());
return $person;
}
throw new UsernameNotFoundException(
sprintf('Username "%s" does not exist.', $username)
);
}
/**
*
* @param \Symfony\Component\Security\Core\User\UserInterface $person
* @throws \Symfony\Component\Security\Core\Exception\UnsupportedUserException
* @internal param \Symfony\Component\Security\Core\User\UserInterface $user
* @return Person
*/
public function refreshUser(UserInterface $person) {
if (!$person instanceof Person) {
throw new UnsupportedUserException(
sprintf('Instances of "%s" are not supported.', get_class($person))
);
}
return $this->loadUserByUsername($person->getUsername());
}
/**
*
* @param type $class
* @return type
*/
public function supportsClass($class) {
return $class === 'Acme\MyBundle\Entity\Person';
}
}