Upgrade 1-11.38

This commit is contained in:
xesmyd
2026-03-30 14:10:30 +02:00
parent f2a7e6d1fc
commit ac648ef29d
24665 changed files with 69682 additions and 2205004 deletions
+6 -8
View File
@@ -11,8 +11,8 @@
namespace Symfony\Component\Security\Http;
use Symfony\Component\HttpFoundation\RequestMatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestMatcherInterface;
/**
* AccessMap allows configuration of different access control rules for
@@ -22,18 +22,16 @@ use Symfony\Component\HttpFoundation\Request;
*/
class AccessMap implements AccessMapInterface
{
private $map = array();
private $map = [];
/**
* Constructor.
*
* @param RequestMatcherInterface $requestMatcher A RequestMatcherInterface instance
* @param array $attributes An array of attributes to pass to the access decision manager (like roles)
* @param string|null $channel The channel to enforce (http, https, or null)
*/
public function add(RequestMatcherInterface $requestMatcher, array $attributes = array(), $channel = null)
public function add(RequestMatcherInterface $requestMatcher, array $attributes = [], $channel = null)
{
$this->map[] = array($requestMatcher, $attributes, $channel);
$this->map[] = [$requestMatcher, $attributes, $channel];
}
/**
@@ -43,10 +41,10 @@ class AccessMap implements AccessMapInterface
{
foreach ($this->map as $elements) {
if (null === $elements[0] || $elements[0]->matches($request)) {
return array($elements[1], $elements[2]);
return [$elements[1], $elements[2]];
}
}
return array(null, null);
return [null, null];
}
}
-2
View File
@@ -25,8 +25,6 @@ interface AccessMapInterface
/**
* Returns security attributes and required channel for the supplied request.
*
* @param Request $request The current request
*
* @return array A tuple of security attributes and the required channel
*/
public function getPatterns(Request $request);
@@ -11,9 +11,9 @@
namespace Symfony\Component\Security\Http\Authentication;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
/**
* Interface for custom authentication failure handlers.
@@ -31,9 +31,6 @@ interface AuthenticationFailureHandlerInterface
* called by authentication listeners inheriting from
* AbstractAuthenticationListener.
*
* @param Request $request
* @param AuthenticationException $exception
*
* @return Response The response to return, never null
*/
public function onAuthenticationFailure(Request $request, AuthenticationException $exception);
@@ -11,9 +11,9 @@
namespace Symfony\Component\Security\Http\Authentication;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
/**
* Interface for a custom authentication success handler.
@@ -31,10 +31,7 @@ interface AuthenticationSuccessHandlerInterface
* is called by authentication listeners inheriting from
* AbstractAuthenticationListener.
*
* @param Request $request
* @param TokenInterface $token
*
* @return Response never null
* @return Response
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token);
}
@@ -23,14 +23,8 @@ use Symfony\Component\Security\Core\Security;
*/
class AuthenticationUtils
{
/**
* @var RequestStack
*/
private $requestStack;
/**
* @param RequestStack $requestStack
*/
public function __construct(RequestStack $requestStack)
{
$this->requestStack = $requestStack;
@@ -49,7 +43,7 @@ class AuthenticationUtils
if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) {
$authenticationException = $request->attributes->get(Security::AUTHENTICATION_ERROR);
} elseif ($session !== null && $session->has(Security::AUTHENTICATION_ERROR)) {
} elseif (null !== $session && $session->has(Security::AUTHENTICATION_ERROR)) {
$authenticationException = $session->get(Security::AUTHENTICATION_ERROR);
if ($clearSession) {
@@ -22,8 +22,6 @@ class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler
private $handler;
/**
* Constructor.
*
* @param AuthenticationFailureHandlerInterface $handler An AuthenticationFailureHandlerInterface instance
* @param array $options Options for processing a successful authentication attempt
*/
@@ -11,8 +11,8 @@
namespace Symfony\Component\Security\Http\Authentication;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
/**
* @author Fabien Potencier <fabien@symfony.com>
@@ -22,8 +22,6 @@ class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler
private $handler;
/**
* Constructor.
*
* @param AuthenticationSuccessHandlerInterface $handler An AuthenticationSuccessHandlerInterface instance
* @param array $options Options for processing a successful authentication attempt
* @param string $providerKey The provider key
@@ -11,9 +11,9 @@
namespace Symfony\Component\Security\Http\Authentication;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\HttpUtils;
@@ -22,8 +22,8 @@ use Symfony\Component\Security\Http\ParameterBagUtils;
/**
* Class with the default authentication failure handling logic.
*
* Can be optionally be extended from by the developer to alter the behaviour
* while keeping the default behaviour.
* Can be optionally be extended from by the developer to alter the behavior
* while keeping the default behavior.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
@@ -35,22 +35,14 @@ class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandle
protected $httpUtils;
protected $logger;
protected $options;
protected $defaultOptions = array(
protected $defaultOptions = [
'failure_path' => null,
'failure_forward' => false,
'login_path' => '/login',
'failure_path_parameter' => '_failure_path',
);
];
/**
* Constructor.
*
* @param HttpKernelInterface $httpKernel
* @param HttpUtils $httpUtils
* @param array $options Options for processing a failed authentication attempt
* @param LoggerInterface $logger Optional logger
*/
public function __construct(HttpKernelInterface $httpKernel, HttpUtils $httpUtils, array $options = array(), LoggerInterface $logger = null)
public function __construct(HttpKernelInterface $httpKernel, HttpUtils $httpUtils, array $options = [], LoggerInterface $logger = null)
{
$this->httpKernel = $httpKernel;
$this->httpUtils = $httpUtils;
@@ -68,11 +60,6 @@ class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandle
return $this->options;
}
/**
* Sets the options.
*
* @param array $options An array of options
*/
public function setOptions(array $options)
{
$this->options = array_merge($this->defaultOptions, $options);
@@ -93,7 +80,7 @@ class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandle
if ($this->options['failure_forward']) {
if (null !== $this->logger) {
$this->logger->debug('Authentication failure, forward triggered.', array('failure_path' => $this->options['failure_path']));
$this->logger->debug('Authentication failure, forward triggered.', ['failure_path' => $this->options['failure_path']]);
}
$subRequest = $this->httpUtils->createRequest($request, $this->options['failure_path']);
@@ -103,7 +90,7 @@ class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandle
}
if (null !== $this->logger) {
$this->logger->debug('Authentication failure, redirect triggered.', array('failure_path' => $this->options['failure_path']));
$this->logger->debug('Authentication failure, redirect triggered.', ['failure_path' => $this->options['failure_path']]);
}
$request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
@@ -11,11 +11,11 @@
namespace Symfony\Component\Security\Http\Authentication;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\ParameterBagUtils;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
/**
* Class with the default authentication success handling logic.
@@ -31,21 +31,18 @@ class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandle
protected $httpUtils;
protected $options;
protected $providerKey;
protected $defaultOptions = array(
protected $defaultOptions = [
'always_use_default_target_path' => false,
'default_target_path' => '/',
'login_path' => '/login',
'target_path_parameter' => '_target_path',
'use_referer' => false,
);
];
/**
* Constructor.
*
* @param HttpUtils $httpUtils
* @param array $options Options for processing a successful authentication attempt
* @param array $options Options for processing a successful authentication attempt
*/
public function __construct(HttpUtils $httpUtils, array $options = array())
public function __construct(HttpUtils $httpUtils, array $options = [])
{
$this->httpUtils = $httpUtils;
$this->setOptions($options);
@@ -69,11 +66,6 @@ class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandle
return $this->options;
}
/**
* Sets the options.
*
* @param array $options An array of options
*/
public function setOptions(array $options)
{
$this->options = array_merge($this->defaultOptions, $options);
@@ -102,8 +94,6 @@ class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandle
/**
* Builds the target URL according to the defined options.
*
* @param Request $request
*
* @return string
*/
protected function determineTargetUrl(Request $request)
@@ -122,12 +112,11 @@ class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandle
return $targetUrl;
}
if ($this->options['use_referer']) {
$targetUrl = $request->headers->get('Referer');
if ($this->options['use_referer'] && $targetUrl = $request->headers->get('Referer')) {
if (false !== $pos = strpos($targetUrl, '?')) {
$targetUrl = substr($targetUrl, 0, $pos);
}
if ($targetUrl !== $this->httpUtils->generateUri($request, $this->options['login_path'])) {
if ($targetUrl && $targetUrl !== $this->httpUtils->generateUri($request, $this->options['login_path'])) {
return $targetUrl;
}
}
@@ -11,12 +11,12 @@
namespace Symfony\Component\Security\Http\Authentication;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
/**
* Class to proxy authentication success/failure handlers.
@@ -35,8 +35,6 @@ class SimpleAuthenticationHandler implements AuthenticationFailureHandlerInterfa
protected $logger;
/**
* Constructor.
*
* @param SimpleAuthenticatorInterface $authenticator SimpleAuthenticatorInterface instance
* @param AuthenticationSuccessHandlerInterface $successHandler Default success handler
* @param AuthenticationFailureHandlerInterface $failureHandler Default failure handler
@@ -57,7 +55,7 @@ class SimpleAuthenticationHandler implements AuthenticationFailureHandlerInterfa
{
if ($this->simpleAuthenticator instanceof AuthenticationSuccessHandlerInterface) {
if ($this->logger) {
$this->logger->debug('Selected an authentication success handler.', array('handler' => get_class($this->simpleAuthenticator)));
$this->logger->debug('Selected an authentication success handler.', ['handler' => \get_class($this->simpleAuthenticator)]);
}
$response = $this->simpleAuthenticator->onAuthenticationSuccess($request, $token);
@@ -66,7 +64,7 @@ class SimpleAuthenticationHandler implements AuthenticationFailureHandlerInterfa
}
if (null !== $response) {
throw new \UnexpectedValueException(sprintf('The %s::onAuthenticationSuccess method must return null to use the default success handler, or a Response object', get_class($this->simpleAuthenticator)));
throw new \UnexpectedValueException(sprintf('The "%s::onAuthenticationSuccess()" method must return null to use the default success handler, or a Response object.', \get_class($this->simpleAuthenticator)));
}
}
@@ -84,7 +82,7 @@ class SimpleAuthenticationHandler implements AuthenticationFailureHandlerInterfa
{
if ($this->simpleAuthenticator instanceof AuthenticationFailureHandlerInterface) {
if ($this->logger) {
$this->logger->debug('Selected an authentication failure handler.', array('handler' => get_class($this->simpleAuthenticator)));
$this->logger->debug('Selected an authentication failure handler.', ['handler' => \get_class($this->simpleAuthenticator)]);
}
$response = $this->simpleAuthenticator->onAuthenticationFailure($request, $exception);
@@ -93,7 +91,7 @@ class SimpleAuthenticationHandler implements AuthenticationFailureHandlerInterfa
}
if (null !== $response) {
throw new \UnexpectedValueException(sprintf('The %s::onAuthenticationFailure method must return null to use the default failure handler, or a Response object', get_class($this->simpleAuthenticator)));
throw new \UnexpectedValueException(sprintf('The "%s::onAuthenticationFailure()" method must return null to use the default failure handler, or a Response object.', \get_class($this->simpleAuthenticator)));
}
}
@@ -26,10 +26,7 @@ interface AccessDeniedHandlerInterface
/**
* Handles an access denied failure.
*
* @param Request $request
* @param AccessDeniedException $accessDeniedException
*
* @return Response may return null
* @return Response|null
*/
public function handle(Request $request, AccessDeniedException $accessDeniedException);
}
@@ -11,9 +11,9 @@
namespace Symfony\Component\Security\Http\EntryPoint;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
/**
* Implement this interface for any classes that will be called to "start"
@@ -31,10 +31,14 @@ interface AuthenticationEntryPointInterface
* response that "helps" the user start into the authentication process.
*
* Examples:
* A) For a form login, you might redirect to the login page
* return new RedirectResponse('/login');
* B) For an API token authentication system, you return a 401 response
* return new Response('Auth header required', 401);
*
* - For a form login, you might redirect to the login page
*
* return new RedirectResponse('/login');
*
* - For an API token authentication system, you return a 401 response
*
* return new Response('Auth header required', 401);
*
* @param Request $request The request that resulted in an AuthenticationException
* @param AuthenticationException $authException The exception that started the authentication process
@@ -11,9 +11,9 @@
namespace Symfony\Component\Security\Http\EntryPoint;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
/**
* BasicAuthenticationEntryPoint starts an HTTP Basic authentication.
@@ -11,16 +11,18 @@
namespace Symfony\Component\Security\Http\EntryPoint;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\NonceExpiredException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Psr\Log\LoggerInterface;
/**
* DigestAuthenticationEntryPoint starts an HTTP Digest authentication.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @deprecated since 3.4, to be removed in 4.0
*/
class DigestAuthenticationEntryPoint implements AuthenticationEntryPointInterface
{
@@ -31,6 +33,8 @@ class DigestAuthenticationEntryPoint implements AuthenticationEntryPointInterfac
public function __construct($realmName, $secret, $nonceValiditySeconds = 300, LoggerInterface $logger = null)
{
@trigger_error(sprintf('The %s class and the whole HTTP digest authentication system is deprecated since Symfony 3.4 and will be removed in 4.0.', __CLASS__), \E_USER_DEPRECATED);
$this->realmName = $realmName;
$this->secret = $secret;
$this->nonceValiditySeconds = $nonceValiditySeconds;
@@ -54,7 +58,7 @@ class DigestAuthenticationEntryPoint implements AuthenticationEntryPointInterfac
}
if (null !== $this->logger) {
$this->logger->debug('WWW-Authenticate header sent.', array('header' => $authenticateHeader));
$this->logger->debug('WWW-Authenticate header sent.', ['header' => $authenticateHeader]);
}
$response = new Response();
@@ -12,9 +12,9 @@
namespace Symfony\Component\Security\Http\EntryPoint;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\HttpKernel\HttpKernelInterface;
/**
* FormAuthenticationEntryPoint starts an authentication via a login form.
@@ -29,12 +29,9 @@ class FormAuthenticationEntryPoint implements AuthenticationEntryPointInterface
private $httpUtils;
/**
* Constructor.
*
* @param HttpKernelInterface $kernel
* @param HttpUtils $httpUtils An HttpUtils instance
* @param string $loginPath The path to the login form
* @param bool $useForward Whether to forward or redirect to the login form
* @param HttpUtils $httpUtils An HttpUtils instance
* @param string $loginPath The path to the login form
* @param bool $useForward Whether to forward or redirect to the login form
*/
public function __construct(HttpKernelInterface $kernel, HttpUtils $httpUtils, $loginPath, $useForward = false)
{
@@ -54,7 +51,7 @@ class FormAuthenticationEntryPoint implements AuthenticationEntryPointInterface
$response = $this->httpKernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
if (200 === $response->getStatusCode()) {
$response->headers->set('X-Status-Code', 401);
$response->setStatusCode(401);
}
return $response;
@@ -11,9 +11,9 @@
namespace Symfony\Component\Security\Http\EntryPoint;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
/**
* RetryAuthenticationEntryPoint redirects URL based on the configured scheme.
@@ -11,13 +11,11 @@
namespace Symfony\Component\Security\Http\Event;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
/**
* InteractiveLoginEvent.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class InteractiveLoginEvent extends Event
@@ -25,12 +23,6 @@ class InteractiveLoginEvent extends Event
private $request;
private $authenticationToken;
/**
* Constructor.
*
* @param Request $request A Request instance
* @param TokenInterface $authenticationToken A TokenInterface instance
*/
public function __construct(Request $request, TokenInterface $authenticationToken)
{
$this->request = $request;
+19 -3
View File
@@ -11,9 +11,10 @@
namespace Symfony\Component\Security\Http\Event;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* SwitchUserEvent.
@@ -24,11 +25,13 @@ class SwitchUserEvent extends Event
{
private $request;
private $targetUser;
private $token;
public function __construct(Request $request, UserInterface $targetUser)
public function __construct(Request $request, UserInterface $targetUser, TokenInterface $token = null)
{
$this->request = $request;
$this->targetUser = $targetUser;
$this->token = $token;
}
/**
@@ -46,4 +49,17 @@ class SwitchUserEvent extends Event
{
return $this->targetUser;
}
/**
* @return TokenInterface|null
*/
public function getToken()
{
return $this->token;
}
public function setToken(TokenInterface $token)
{
$this->token = $token;
}
}
+45 -24
View File
@@ -11,11 +11,12 @@
namespace Symfony\Component\Security\Http;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Http\Firewall\AccessListener;
/**
* Firewall uses a FirewallMap to register security listeners for the given
@@ -33,12 +34,6 @@ class Firewall implements EventSubscriberInterface
private $dispatcher;
private $exceptionListeners;
/**
* Constructor.
*
* @param FirewallMapInterface $map A FirewallMapInterface instance
* @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
*/
public function __construct(FirewallMapInterface $map, EventDispatcherInterface $dispatcher)
{
$this->map = $map;
@@ -46,11 +41,6 @@ class Firewall implements EventSubscriberInterface
$this->exceptionListeners = new \SplObjectStorage();
}
/**
* Handles security.
*
* @param GetResponseEvent $event An GetResponseEvent instance
*/
public function onKernelRequest(GetResponseEvent $event)
{
if (!$event->isMasterRequest()) {
@@ -58,20 +48,40 @@ class Firewall implements EventSubscriberInterface
}
// register listeners for this firewall
list($listeners, $exceptionListener) = $this->map->getListeners($event->getRequest());
$listeners = $this->map->getListeners($event->getRequest());
$authenticationListeners = $listeners[0];
$exceptionListener = $listeners[1];
$logoutListener = isset($listeners[2]) ? $listeners[2] : null;
if (null !== $exceptionListener) {
$this->exceptionListeners[$event->getRequest()] = $exceptionListener;
$exceptionListener->register($this->dispatcher);
}
// initiate the listener chain
foreach ($listeners as $listener) {
$listener->handle($event);
$authenticationListeners = function () use ($authenticationListeners, $logoutListener) {
$accessListener = null;
if ($event->hasResponse()) {
break;
foreach ($authenticationListeners as $listener) {
if ($listener instanceof AccessListener) {
$accessListener = $listener;
continue;
}
yield $listener;
}
}
if (null !== $logoutListener) {
yield $logoutListener;
}
if (null !== $accessListener) {
yield $accessListener;
}
};
$this->handleRequest($event, $authenticationListeners());
}
public function onKernelFinishRequest(FinishRequestEvent $event)
@@ -89,9 +99,20 @@ class Firewall implements EventSubscriberInterface
*/
public static function getSubscribedEvents()
{
return array(
KernelEvents::REQUEST => array('onKernelRequest', 8),
return [
KernelEvents::REQUEST => ['onKernelRequest', 8],
KernelEvents::FINISH_REQUEST => 'onKernelFinishRequest',
);
];
}
protected function handleRequest(GetResponseEvent $event, $listeners)
{
foreach ($listeners as $listener) {
$listener->handle($event);
if ($event->hasResponse()) {
break;
}
}
}
}
@@ -11,25 +11,25 @@
namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Core\Security;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\SessionUnavailableException;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
/**
* The AbstractAuthenticationListener is the preferred base class for all
@@ -64,23 +64,18 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
private $rememberMeServices;
/**
* Constructor.
*
* @param TokenStorageInterface $tokenStorage A TokenStorageInterface instance
* @param AuthenticationManagerInterface $authenticationManager An AuthenticationManagerInterface instance
* @param SessionAuthenticationStrategyInterface $sessionStrategy
* @param HttpUtils $httpUtils An HttpUtils instance
* @param string $providerKey
* @param AuthenticationSuccessHandlerInterface $successHandler
* @param AuthenticationFailureHandlerInterface $failureHandler
* @param array $options An array of options for the processing of a
* successful, or failed authentication attempt
* @param LoggerInterface|null $logger A LoggerInterface instance
* @param EventDispatcherInterface|null $dispatcher An EventDispatcherInterface instance
* @param TokenStorageInterface $tokenStorage A TokenStorageInterface instance
* @param AuthenticationManagerInterface $authenticationManager An AuthenticationManagerInterface instance
* @param HttpUtils $httpUtils An HttpUtils instance
* @param string $providerKey
* @param array $options An array of options for the processing of a
* successful, or failed authentication attempt
* @param LoggerInterface|null $logger A LoggerInterface instance
* @param EventDispatcherInterface|null $dispatcher An EventDispatcherInterface instance
*
* @throws \InvalidArgumentException
*/
public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = [], LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
{
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
@@ -92,7 +87,7 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
$this->providerKey = $providerKey;
$this->successHandler = $successHandler;
$this->failureHandler = $failureHandler;
$this->options = array_merge(array(
$this->options = array_merge([
'check_path' => '/login_check',
'login_path' => '/login',
'always_use_default_target_path' => false,
@@ -102,7 +97,7 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
'failure_path' => null,
'failure_forward' => false,
'require_previous_session' => true,
), $options);
], $options);
$this->logger = $logger;
$this->dispatcher = $dispatcher;
$this->httpUtils = $httpUtils;
@@ -110,8 +105,6 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
/**
* Sets the RememberMeServices implementation to use.
*
* @param RememberMeServicesInterface $rememberMeServices
*/
public function setRememberMeServices(RememberMeServicesInterface $rememberMeServices)
{
@@ -121,8 +114,6 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
/**
* Handles form based authentication.
*
* @param GetResponseEvent $event A GetResponseEvent instance
*
* @throws \RuntimeException
* @throws SessionUnavailableException
*/
@@ -170,8 +161,6 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
* but a subclass could change this to only authenticate requests where a
* certain parameters is present.
*
* @param Request $request
*
* @return bool
*/
protected function requiresAuthentication(Request $request)
@@ -182,8 +171,6 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
/**
* Performs authentication.
*
* @param Request $request A Request instance
*
* @return TokenInterface|Response|null The authenticated token, null if full authentication is not possible, or a Response
*
* @throws AuthenticationException if the authentication fails
@@ -193,7 +180,7 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
private function onFailure(Request $request, AuthenticationException $failed)
{
if (null !== $this->logger) {
$this->logger->info('Authentication request failed.', array('exception' => $failed));
$this->logger->info('Authentication request failed.', ['exception' => $failed]);
}
$token = $this->tokenStorage->getToken();
@@ -213,7 +200,7 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
private function onSuccess(Request $request, TokenInterface $token)
{
if (null !== $this->logger) {
$this->logger->info('User has been authenticated successfully.', array('username' => $token->getUsername()));
$this->logger->info('User has been authenticated successfully.', ['username' => $token->getUsername()]);
}
$this->tokenStorage->setToken($token);
@@ -11,17 +11,19 @@
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
/**
* AbstractPreAuthenticatedListener is the base class for all listener that
@@ -37,6 +39,7 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface
private $authenticationManager;
private $providerKey;
private $dispatcher;
private $sessionStrategy;
public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, $providerKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
{
@@ -49,8 +52,6 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface
/**
* Handles pre-authentication.
*
* @param GetResponseEvent $event A GetResponseEvent instance
*/
final public function handle(GetResponseEvent $event)
{
@@ -65,7 +66,7 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface
}
if (null !== $this->logger) {
$this->logger->debug('Checking current security token.', array('token' => (string) $this->tokenStorage->getToken()));
$this->logger->debug('Checking current security token.', ['token' => (string) $this->tokenStorage->getToken()]);
}
if (null !== $token = $this->tokenStorage->getToken()) {
@@ -75,15 +76,18 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface
}
if (null !== $this->logger) {
$this->logger->debug('Trying to pre-authenticate user.', array('username' => (string) $user));
$this->logger->debug('Trying to pre-authenticate user.', ['username' => (string) $user]);
}
try {
$token = $this->authenticationManager->authenticate(new PreAuthenticatedToken($user, $credentials, $this->providerKey));
if (null !== $this->logger) {
$this->logger->info('Pre-authentication successful.', array('token' => (string) $token));
$this->logger->info('Pre-authentication successful.', ['token' => (string) $token]);
}
$this->migrateSession($request, $token);
$this->tokenStorage->setToken($token);
if (null !== $this->dispatcher) {
@@ -96,9 +100,17 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface
}
/**
* Clears a PreAuthenticatedToken for this provider (if present).
* Call this method if your authentication token is stored to a session.
*
* @param AuthenticationException $exception
* @final
*/
public function setSessionAuthenticationStrategy(SessionAuthenticationStrategyInterface $sessionStrategy)
{
$this->sessionStrategy = $sessionStrategy;
}
/**
* Clears a PreAuthenticatedToken for this provider (if present).
*/
private function clearToken(AuthenticationException $exception)
{
@@ -107,7 +119,7 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface
$this->tokenStorage->setToken(null);
if (null !== $this->logger) {
$this->logger->info('Cleared security token due to an exception.', array('exception' => $exception));
$this->logger->info('Cleared security token due to an exception.', ['exception' => $exception]);
}
}
}
@@ -115,9 +127,16 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface
/**
* Gets the user and credentials from the Request.
*
* @param Request $request A Request instance
*
* @return array An array composed of the user and the credentials
*/
abstract protected function getPreAuthenticatedData(Request $request);
private function migrateSession(Request $request, TokenInterface $token)
{
if (!$this->sessionStrategy || !$request->hasSession() || !$request->hasPreviousSession()) {
return;
}
$this->sessionStrategy->onAuthentication($request, $token);
}
}
+4 -6
View File
@@ -11,13 +11,13 @@
namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Http\AccessMapInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
use Symfony\Component\Security\Http\AccessMapInterface;
/**
* AccessListener enforces access control rules.
@@ -42,8 +42,6 @@ class AccessListener implements ListenerInterface
/**
* Handles access authorization.
*
* @param GetResponseEvent $event A GetResponseEvent instance
*
* @throws AccessDeniedException
* @throws AuthenticationCredentialsNotFoundException
*/
@@ -11,12 +11,12 @@
namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
/**
* AnonymousAuthenticationListener automatically adds a Token if none is
@@ -41,8 +41,6 @@ class AnonymousAuthenticationListener implements ListenerInterface
/**
* Handles anonymous authentication.
*
* @param GetResponseEvent $event A GetResponseEvent instance
*/
public function handle(GetResponseEvent $event)
{
@@ -51,7 +49,7 @@ class AnonymousAuthenticationListener implements ListenerInterface
}
try {
$token = new AnonymousToken($this->secret, 'anon.', array());
$token = new AnonymousToken($this->secret, 'anon.', []);
if (null !== $this->authenticationManager) {
$token = $this->authenticationManager->authenticate($token);
}
@@ -63,7 +61,7 @@ class AnonymousAuthenticationListener implements ListenerInterface
}
} catch (AuthenticationException $failed) {
if (null !== $this->logger) {
$this->logger->info('Anonymous authentication failed.', array('exception' => $failed));
$this->logger->info('Anonymous authentication failed.', ['exception' => $failed]);
}
}
}
@@ -11,13 +11,16 @@
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
/**
* BasicAuthenticationListener implements Basic HTTP authentication.
@@ -32,6 +35,7 @@ class BasicAuthenticationListener implements ListenerInterface
private $authenticationEntryPoint;
private $logger;
private $ignoreFailure;
private $sessionStrategy;
public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, $providerKey, AuthenticationEntryPointInterface $authenticationEntryPoint, LoggerInterface $logger = null)
{
@@ -49,8 +53,6 @@ class BasicAuthenticationListener implements ListenerInterface
/**
* Handles basic authentication.
*
* @param GetResponseEvent $event A GetResponseEvent instance
*/
public function handle(GetResponseEvent $event)
{
@@ -67,11 +69,14 @@ class BasicAuthenticationListener implements ListenerInterface
}
if (null !== $this->logger) {
$this->logger->info('Basic authentication Authorization header found for user.', array('username' => $username));
$this->logger->info('Basic authentication Authorization header found for user.', ['username' => $username]);
}
try {
$token = $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $request->headers->get('PHP_AUTH_PW'), $this->providerKey));
$this->migrateSession($request, $token);
$this->tokenStorage->setToken($token);
} catch (AuthenticationException $e) {
$token = $this->tokenStorage->getToken();
@@ -80,7 +85,7 @@ class BasicAuthenticationListener implements ListenerInterface
}
if (null !== $this->logger) {
$this->logger->info('Basic authentication failed for user.', array('username' => $username, 'exception' => $e));
$this->logger->info('Basic authentication failed for user.', ['username' => $username, 'exception' => $e]);
}
if ($this->ignoreFailure) {
@@ -90,4 +95,23 @@ class BasicAuthenticationListener implements ListenerInterface
$event->setResponse($this->authenticationEntryPoint->start($request, $e));
}
}
/**
* Call this method if your authentication token is stored to a session.
*
* @final
*/
public function setSessionAuthenticationStrategy(SessionAuthenticationStrategyInterface $sessionStrategy)
{
$this->sessionStrategy = $sessionStrategy;
}
private function migrateSession(Request $request, TokenInterface $token)
{
if (!$this->sessionStrategy || !$request->hasSession() || !$request->hasPreviousSession()) {
return;
}
$this->sessionStrategy->onAuthentication($request, $token);
}
}
+2 -4
View File
@@ -11,10 +11,10 @@
namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\Security\Http\AccessMapInterface;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Http\AccessMapInterface;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
/**
* ChannelListener switches the HTTP protocol based on the access control
@@ -37,8 +37,6 @@ class ChannelListener implements ListenerInterface
/**
* Handles channel management.
*
* @param GetResponseEvent $event A GetResponseEvent instance
*/
public function handle(GetResponseEvent $event)
{
+132 -32
View File
@@ -12,8 +12,9 @@
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
@@ -21,11 +22,12 @@ use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
/**
* ContextListener manages the SecurityContext persistence through a session.
@@ -36,29 +38,27 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class ContextListener implements ListenerInterface
{
private $tokenStorage;
private $contextKey;
private $sessionKey;
private $logger;
private $userProviders;
private $dispatcher;
private $registered;
private $trustResolver;
private $logoutOnUserChange = false;
private $rememberMeServices;
public function __construct(TokenStorageInterface $tokenStorage, array $userProviders, $contextKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, AuthenticationTrustResolverInterface $trustResolver = null)
/**
* @param iterable|UserProviderInterface[] $userProviders
* @param string $contextKey
*/
public function __construct(TokenStorageInterface $tokenStorage, $userProviders, $contextKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, AuthenticationTrustResolverInterface $trustResolver = null)
{
if (empty($contextKey)) {
throw new \InvalidArgumentException('$contextKey must not be empty.');
}
foreach ($userProviders as $userProvider) {
if (!$userProvider instanceof UserProviderInterface) {
throw new \InvalidArgumentException(sprintf('User provider "%s" must implement "Symfony\Component\Security\Core\User\UserProviderInterface".', get_class($userProvider)));
}
}
$this->tokenStorage = $tokenStorage;
$this->userProviders = $userProviders;
$this->contextKey = $contextKey;
$this->sessionKey = '_security_'.$contextKey;
$this->logger = $logger;
$this->dispatcher = $dispatcher;
@@ -66,14 +66,22 @@ class ContextListener implements ListenerInterface
}
/**
* Reads the Security Token from the session.
* Enables deauthentication during refreshUser when the user has changed.
*
* @param GetResponseEvent $event A GetResponseEvent instance
* @param bool $logoutOnUserChange
*/
public function setLogoutOnUserChange($logoutOnUserChange)
{
$this->logoutOnUserChange = (bool) $logoutOnUserChange;
}
/**
* Reads the Security Token from the session.
*/
public function handle(GetResponseEvent $event)
{
if (!$this->registered && null !== $this->dispatcher && $event->isMasterRequest()) {
$this->dispatcher->addListener(KernelEvents::RESPONSE, array($this, 'onKernelResponse'));
$this->dispatcher->addListener(KernelEvents::RESPONSE, [$this, 'onKernelResponse']);
$this->registered = true;
}
@@ -86,17 +94,24 @@ class ContextListener implements ListenerInterface
return;
}
$token = unserialize($token);
$token = $this->safelyUnserialize($token);
if (null !== $this->logger) {
$this->logger->debug('Read existing security token from the session.', array('key' => $this->sessionKey));
$this->logger->debug('Read existing security token from the session.', [
'key' => $this->sessionKey,
'token_class' => \is_object($token) ? \get_class($token) : null,
]);
}
if ($token instanceof TokenInterface) {
$token = $this->refreshUser($token);
if (!$token && $this->logoutOnUserChange && $this->rememberMeServices) {
$this->rememberMeServices->loginFail($request);
}
} elseif (null !== $token) {
if (null !== $this->logger) {
$this->logger->warning('Expected a security token from the session, got something else.', array('key' => $this->sessionKey, 'received' => $token));
$this->logger->warning('Expected a security token from the session, got something else.', ['key' => $this->sessionKey, 'received' => $token]);
}
$token = null;
@@ -107,8 +122,6 @@ class ContextListener implements ListenerInterface
/**
* Writes the security token into the session.
*
* @param FilterResponseEvent $event A FilterResponseEvent instance
*/
public function onKernelResponse(FilterResponseEvent $event)
{
@@ -116,14 +129,14 @@ class ContextListener implements ListenerInterface
return;
}
if (!$event->getRequest()->hasSession()) {
$request = $event->getRequest();
if (!$request->hasSession()) {
return;
}
$this->dispatcher->removeListener(KernelEvents::RESPONSE, array($this, 'onKernelResponse'));
$this->dispatcher->removeListener(KernelEvents::RESPONSE, [$this, 'onKernelResponse']);
$this->registered = false;
$request = $event->getRequest();
$session = $request->getSession();
if ((null === $token = $this->tokenStorage->getToken()) || $this->trustResolver->isAnonymous($token)) {
@@ -134,7 +147,7 @@ class ContextListener implements ListenerInterface
$session->set($this->sessionKey, serialize($token));
if (null !== $this->logger) {
$this->logger->debug('Stored the security token in the session.', array('key' => $this->sessionKey));
$this->logger->debug('Stored the security token in the session.', ['key' => $this->sessionKey]);
}
}
}
@@ -142,8 +155,6 @@ class ContextListener implements ListenerInterface
/**
* Refreshes the user by reloading it from the user provider.
*
* @param TokenInterface $token
*
* @return TokenInterface|null
*
* @throws \RuntimeException
@@ -156,14 +167,51 @@ class ContextListener implements ListenerInterface
}
$userNotFoundByProvider = false;
$userDeauthenticated = false;
$userClass = \get_class($user);
foreach ($this->userProviders as $provider) {
if (!$provider instanceof UserProviderInterface) {
throw new \InvalidArgumentException(sprintf('User provider "%s" must implement "%s".', \get_class($provider), UserProviderInterface::class));
}
if (!$provider->supportsClass($userClass)) {
continue;
}
try {
$refreshedUser = $provider->refreshUser($user);
$newToken = clone $token;
$newToken->setUser($refreshedUser);
// tokens can be deauthenticated if the user has been changed.
if (!$newToken->isAuthenticated()) {
if ($this->logoutOnUserChange) {
$userDeauthenticated = true;
if (null !== $this->logger) {
$this->logger->debug('Cannot refresh token because user has changed.', ['username' => $refreshedUser->getUsername(), 'provider' => \get_class($provider)]);
}
continue;
}
@trigger_error('Refreshing a deauthenticated user is deprecated as of 3.4 and will trigger a logout in 4.0.', \E_USER_DEPRECATED);
}
$token->setUser($refreshedUser);
if (null !== $this->logger) {
$this->logger->debug('User was reloaded from a user provider.', array('username' => $refreshedUser->getUsername(), 'provider' => get_class($provider)));
$context = ['provider' => \get_class($provider), 'username' => $refreshedUser->getUsername()];
foreach ($token->getRoles() as $role) {
if ($role instanceof SwitchUserRole) {
$context['impersonator_username'] = $role->getSource()->getUsername();
break;
}
}
$this->logger->debug('User was reloaded from a user provider.', $context);
}
return $token;
@@ -171,17 +219,69 @@ class ContextListener implements ListenerInterface
// let's try the next user provider
} catch (UsernameNotFoundException $e) {
if (null !== $this->logger) {
$this->logger->warning('Username could not be found in the selected user provider.', array('username' => $e->getUsername(), 'provider' => get_class($provider)));
$this->logger->warning('Username could not be found in the selected user provider.', ['username' => $e->getUsername(), 'provider' => \get_class($provider)]);
}
$userNotFoundByProvider = true;
}
}
if ($userNotFoundByProvider) {
return;
if ($userDeauthenticated) {
if (null !== $this->logger) {
$this->logger->debug('Token was deauthenticated after trying to refresh it.');
}
return null;
}
throw new \RuntimeException(sprintf('There is no user provider for user "%s".', get_class($user)));
if ($userNotFoundByProvider) {
return null;
}
throw new \RuntimeException(sprintf('There is no user provider for user "%s". Shouldn\'t the "supportsClass()" method of your user provider return true for this classname?', $userClass));
}
private function safelyUnserialize($serializedToken)
{
$e = $token = null;
$prevUnserializeHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');
$prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) use (&$prevErrorHandler) {
if (__FILE__ === $file) {
throw new \UnexpectedValueException($msg, 0x37313bc);
}
return $prevErrorHandler ? $prevErrorHandler($type, $msg, $file, $line, $context) : false;
});
try {
$token = unserialize($serializedToken);
} catch (\Error $e) {
} catch (\Exception $e) {
}
restore_error_handler();
ini_set('unserialize_callback_func', $prevUnserializeHandler);
if ($e) {
if (!$e instanceof \UnexpectedValueException || 0x37313bc !== $e->getCode()) {
throw $e;
}
if ($this->logger) {
$this->logger->warning('Failed to unserialize the security token from the session.', ['key' => $this->sessionKey, 'received' => $serializedToken, 'exception' => $e]);
}
}
return $token;
}
/**
* @internal
*/
public static function handleUnserializeCallback($class)
{
throw new \UnexpectedValueException('Class not found: '.$class, 0x37313bc);
}
public function setRememberMeServices(RememberMeServicesInterface $rememberMeServices)
{
$this->rememberMeServices = $rememberMeServices;
}
}
@@ -11,23 +11,27 @@
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Exception\NonceExpiredException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\EntryPoint\DigestAuthenticationEntryPoint;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\NonceExpiredException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
/**
* DigestAuthenticationListener implements Digest HTTP authentication.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @deprecated since 3.4, to be removed in 4.0
*/
class DigestAuthenticationListener implements ListenerInterface
{
@@ -36,9 +40,12 @@ class DigestAuthenticationListener implements ListenerInterface
private $providerKey;
private $authenticationEntryPoint;
private $logger;
private $sessionStrategy;
public function __construct(TokenStorageInterface $tokenStorage, UserProviderInterface $provider, $providerKey, DigestAuthenticationEntryPoint $authenticationEntryPoint, LoggerInterface $logger = null)
{
@trigger_error(sprintf('The %s class and the whole HTTP digest authentication system is deprecated since Symfony 3.4 and will be removed in 4.0.', __CLASS__), \E_USER_DEPRECATED);
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
}
@@ -53,8 +60,6 @@ class DigestAuthenticationListener implements ListenerInterface
/**
* Handles digest authentication.
*
* @param GetResponseEvent $event A GetResponseEvent instance
*
* @throws AuthenticationServiceException
*/
public function handle(GetResponseEvent $event)
@@ -74,7 +79,7 @@ class DigestAuthenticationListener implements ListenerInterface
}
if (null !== $this->logger) {
$this->logger->debug('Digest Authorization header received from user agent.', array('header' => $header));
$this->logger->debug('Digest Authorization header received from user agent.', ['header' => $header]);
}
try {
@@ -89,7 +94,7 @@ class DigestAuthenticationListener implements ListenerInterface
$user = $this->provider->loadUserByUsername($digestAuth->getUsername());
if (null === $user) {
throw new AuthenticationServiceException('Digest User provider returned null, which is an interface contract violation');
throw new AuthenticationServiceException('Digest User provider returned null, which is an interface contract violation.');
}
$serverDigestMd5 = $digestAuth->calculateServerDigest($user->getPassword(), $request->getMethod());
@@ -101,7 +106,7 @@ class DigestAuthenticationListener implements ListenerInterface
if (!hash_equals($serverDigestMd5, $digestAuth->getResponse())) {
if (null !== $this->logger) {
$this->logger->debug('Unexpected response from the DigestAuth received; is the header returning a clear text passwords?', array('expected' => $serverDigestMd5, 'received' => $digestAuth->getResponse()));
$this->logger->debug('Unexpected response from the DigestAuth received; is the header returning a clear text passwords?', ['expected' => $serverDigestMd5, 'received' => $digestAuth->getResponse()]);
}
$this->fail($event, $request, new BadCredentialsException('Incorrect response'));
@@ -116,10 +121,23 @@ class DigestAuthenticationListener implements ListenerInterface
}
if (null !== $this->logger) {
$this->logger->info('Digest authentication successful.', array('username' => $digestAuth->getUsername(), 'received' => $digestAuth->getResponse()));
$this->logger->info('Digest authentication successful.', ['username' => $digestAuth->getUsername(), 'received' => $digestAuth->getResponse()]);
}
$this->tokenStorage->setToken(new UsernamePasswordToken($user, $user->getPassword(), $this->providerKey));
$token = new UsernamePasswordToken($user, $user->getPassword(), $this->providerKey);
$this->migrateSession($request, $token);
$this->tokenStorage->setToken($token);
}
/**
* Call this method if your authentication token is stored to a session.
*
* @final
*/
public function setSessionAuthenticationStrategy(SessionAuthenticationStrategyInterface $sessionStrategy)
{
$this->sessionStrategy = $sessionStrategy;
}
private function fail(GetResponseEvent $event, Request $request, AuthenticationException $authException)
@@ -130,23 +148,37 @@ class DigestAuthenticationListener implements ListenerInterface
}
if (null !== $this->logger) {
$this->logger->info('Digest authentication failed.', array('exception' => $authException));
$this->logger->info('Digest authentication failed.', ['exception' => $authException]);
}
$event->setResponse($this->authenticationEntryPoint->start($request, $authException));
}
private function migrateSession(Request $request, TokenInterface $token)
{
if (!$this->sessionStrategy || !$request->hasSession() || !$request->hasPreviousSession()) {
return;
}
$this->sessionStrategy->onAuthentication($request, $token);
}
}
/**
* @deprecated since 3.4, to be removed in 4.0.
*/
class DigestData
{
private $elements = array();
private $elements = [];
private $header;
private $nonceExpiryTime;
public function __construct($header)
{
@trigger_error(sprintf('The %s class and the whole HTTP digest authentication system is deprecated since Symfony 3.4 and will be removed in 4.0.', __CLASS__), \E_USER_DEPRECATED);
$this->header = $header;
preg_match_all('/(\w+)=("((?:[^"\\\\]|\\\\.)+)"|([^\s,$]+))/', $header, $matches, PREG_SET_ORDER);
preg_match_all('/(\w+)=("((?:[^"\\\\]|\\\\.)+)"|([^\s,$]+))/', $header, $matches, \PREG_SET_ORDER);
foreach ($matches as $match) {
if (isset($match[1]) && isset($match[3])) {
$this->elements[$match[1]] = isset($match[4]) ? $match[4] : $match[3];
@@ -161,17 +193,17 @@ class DigestData
public function getUsername()
{
return strtr($this->elements['username'], array('\\"' => '"', '\\\\' => '\\'));
return strtr($this->elements['username'], ['\\"' => '"', '\\\\' => '\\']);
}
public function validateAndDecode($entryPointKey, $expectedRealm)
{
if ($keys = array_diff(array('username', 'realm', 'nonce', 'uri', 'response'), array_keys($this->elements))) {
throw new BadCredentialsException(sprintf('Missing mandatory digest value; received header "%s" (%s)', $this->header, implode(', ', $keys)));
if ($keys = array_diff(['username', 'realm', 'nonce', 'uri', 'response'], array_keys($this->elements))) {
throw new BadCredentialsException(sprintf('Missing mandatory digest value; received header "%s" (%s).', $this->header, implode(', ', $keys)));
}
if ('auth' === $this->elements['qop'] && !isset($this->elements['nc'], $this->elements['cnonce'])) {
throw new BadCredentialsException(sprintf('Missing mandatory digest value; received header "%s"', $this->header));
throw new BadCredentialsException(sprintf('Missing mandatory digest value; received header "%s".', $this->header));
}
if ($expectedRealm !== $this->elements['realm']) {
@@ -184,7 +216,7 @@ class DigestData
$nonceTokens = explode(':', $nonceAsPlainText);
if (2 !== count($nonceTokens)) {
if (2 !== \count($nonceTokens)) {
throw new BadCredentialsException(sprintf('Nonce should have yielded two tokens but was "%s".', $nonceAsPlainText));
}
+49 -46
View File
@@ -11,26 +11,27 @@
namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Symfony\Component\Security\Core\Exception\AccountStatusException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Exception\InsufficientAuthenticationException;
use Symfony\Component\Security\Core\Exception\LogoutException;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\HttpFoundation\Request;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Exception\AccountStatusException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\InsufficientAuthenticationException;
use Symfony\Component\Security\Core\Exception\LogoutException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
/**
* ExceptionListener catches authentication exception and converts them to
@@ -67,39 +68,43 @@ class ExceptionListener
/**
* Registers a onKernelException listener to take care of security exceptions.
*
* @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
*/
public function register(EventDispatcherInterface $dispatcher)
{
$dispatcher->addListener(KernelEvents::EXCEPTION, array($this, 'onKernelException'));
$dispatcher->addListener(KernelEvents::EXCEPTION, [$this, 'onKernelException'], 1);
}
/**
* Unregisters the dispatcher.
*
* @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
*/
public function unregister(EventDispatcherInterface $dispatcher)
{
$dispatcher->removeListener(KernelEvents::EXCEPTION, array($this, 'onKernelException'));
$dispatcher->removeListener(KernelEvents::EXCEPTION, [$this, 'onKernelException']);
}
/**
* Handles security related exceptions.
*
* @param GetResponseForExceptionEvent $event An GetResponseForExceptionEvent instance
*/
public function onKernelException(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
do {
if ($exception instanceof AuthenticationException) {
return $this->handleAuthenticationException($event, $exception);
} elseif ($exception instanceof AccessDeniedException) {
return $this->handleAccessDeniedException($event, $exception);
} elseif ($exception instanceof LogoutException) {
return $this->handleLogoutException($exception);
$this->handleAuthenticationException($event, $exception);
return;
}
if ($exception instanceof AccessDeniedException) {
$this->handleAccessDeniedException($event, $exception);
return;
}
if ($exception instanceof LogoutException) {
$this->handleLogoutException($event, $exception);
return;
}
} while (null !== $exception = $exception->getPrevious());
}
@@ -107,11 +112,12 @@ class ExceptionListener
private function handleAuthenticationException(GetResponseForExceptionEvent $event, AuthenticationException $exception)
{
if (null !== $this->logger) {
$this->logger->info('An AuthenticationException was thrown; redirecting to authentication entry point.', array('exception' => $exception));
$this->logger->info('An AuthenticationException was thrown; redirecting to authentication entry point.', ['exception' => $exception]);
}
try {
$event->setResponse($this->startAuthentication($event->getRequest(), $exception));
$event->allowCustomResponseCode();
} catch (\Exception $e) {
$event->setException($e);
}
@@ -124,7 +130,7 @@ class ExceptionListener
$token = $this->tokenStorage->getToken();
if (!$this->authenticationTrustResolver->isFullFledged($token)) {
if (null !== $this->logger) {
$this->logger->debug('Access denied, the user is not fully authenticated; redirecting to authentication entry point.', array('exception' => $exception));
$this->logger->debug('Access denied, the user is not fully authenticated; redirecting to authentication entry point.', ['exception' => $exception]);
}
try {
@@ -140,7 +146,7 @@ class ExceptionListener
}
if (null !== $this->logger) {
$this->logger->debug('Access denied, the user is neither anonymous, nor remember-me.', array('exception' => $exception));
$this->logger->debug('Access denied, the user is neither anonymous, nor remember-me.', ['exception' => $exception]);
}
try {
@@ -155,27 +161,27 @@ class ExceptionListener
$subRequest->attributes->set(Security::ACCESS_DENIED_ERROR, $exception);
$event->setResponse($event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true));
$event->allowCustomResponseCode();
}
} catch (\Exception $e) {
if (null !== $this->logger) {
$this->logger->error('An exception was thrown when handling an AccessDeniedException.', array('exception' => $e));
$this->logger->error('An exception was thrown when handling an AccessDeniedException.', ['exception' => $e]);
}
$event->setException(new \RuntimeException('Exception thrown when handling an exception.', 0, $e));
}
}
private function handleLogoutException(LogoutException $exception)
private function handleLogoutException(GetResponseForExceptionEvent $event, LogoutException $exception)
{
$event->setException(new AccessDeniedHttpException($exception->getMessage(), $exception));
if (null !== $this->logger) {
$this->logger->info('A LogoutException was thrown.', array('exception' => $exception));
$this->logger->info('A LogoutException was thrown; wrapping with AccessDeniedHttpException', ['exception' => $exception]);
}
}
/**
* @param Request $request
* @param AuthenticationException $authException
*
* @return Response
*
* @throws AuthenticationException
@@ -183,7 +189,7 @@ class ExceptionListener
private function startAuthentication(Request $request, AuthenticationException $authException)
{
if (null === $this->authenticationEntryPoint) {
throw $authException;
throw new HttpException(Response::HTTP_UNAUTHORIZED, $authException->getMessage(), $authException, [], $authException->getCode());
}
if (null !== $this->logger) {
@@ -199,24 +205,21 @@ class ExceptionListener
$this->tokenStorage->setToken(null);
if (null !== $this->logger) {
$this->logger->info('The security token was removed due to an AccountStatusException.', array('exception' => $authException));
$this->logger->info('The security token was removed due to an AccountStatusException.', ['exception' => $authException]);
}
}
$response = $this->authenticationEntryPoint->start($request, $authException);
if (!$response instanceof Response) {
$given = is_object($response) ? get_class($response) : gettype($response);
$given = \is_object($response) ? \get_class($response) : \gettype($response);
throw new \LogicException(sprintf('The %s::start() method must return a Response object (%s returned)', get_class($this->authenticationEntryPoint), $given));
throw new \LogicException(sprintf('The "%s::start()" method must return a Response object ("%s" returned).', \get_class($this->authenticationEntryPoint), $given));
}
return $response;
}
/**
* @param Request $request
*/
protected function setTargetPath(Request $request)
{
// session isn't required when using HTTP basic authentication mechanism for example
@@ -20,10 +20,5 @@ use Symfony\Component\HttpKernel\Event\GetResponseEvent;
*/
interface ListenerInterface
{
/**
* This interface must be implemented by firewall listeners.
*
* @param GetResponseEvent $event
*/
public function handle(GetResponseEvent $event);
}
+4 -16
View File
@@ -38,33 +38,25 @@ class LogoutListener implements ListenerInterface
private $csrfTokenManager;
/**
* Constructor.
*
* @param TokenStorageInterface $tokenStorage
* @param HttpUtils $httpUtils An HttpUtils instance
* @param LogoutSuccessHandlerInterface $successHandler A LogoutSuccessHandlerInterface instance
* @param array $options An array of options to process a logout attempt
* @param CsrfTokenManagerInterface|null $csrfTokenManager A CsrfTokenManagerInterface instance
*/
public function __construct(TokenStorageInterface $tokenStorage, HttpUtils $httpUtils, LogoutSuccessHandlerInterface $successHandler, array $options = array(), CsrfTokenManagerInterface $csrfTokenManager = null)
public function __construct(TokenStorageInterface $tokenStorage, HttpUtils $httpUtils, LogoutSuccessHandlerInterface $successHandler, array $options = [], CsrfTokenManagerInterface $csrfTokenManager = null)
{
$this->tokenStorage = $tokenStorage;
$this->httpUtils = $httpUtils;
$this->options = array_merge(array(
$this->options = array_merge([
'csrf_parameter' => '_csrf_token',
'csrf_token_id' => 'logout',
'logout_path' => '/logout',
), $options);
], $options);
$this->successHandler = $successHandler;
$this->csrfTokenManager = $csrfTokenManager;
$this->handlers = array();
$this->handlers = [];
}
/**
* Adds a logout handler.
*
* @param LogoutHandlerInterface $handler
*/
public function addHandler(LogoutHandlerInterface $handler)
{
$this->handlers[] = $handler;
@@ -76,8 +68,6 @@ class LogoutListener implements ListenerInterface
* If a CsrfTokenManagerInterface instance is available, it will be used to
* validate the request.
*
* @param GetResponseEvent $event A GetResponseEvent instance
*
* @throws LogoutException if the CSRF token is invalid
* @throws \RuntimeException if the LogoutSuccessHandlerInterface instance does not return a response
*/
@@ -121,8 +111,6 @@ class LogoutListener implements ListenerInterface
* but a subclass could change this to logout requests where
* certain parameters is present.
*
* @param Request $request
*
* @return bool
*/
protected function requiresLogout(Request $request)
+25 -17
View File
@@ -12,16 +12,16 @@
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
/**
* RememberMeListener implements authentication capabilities via a cookie.
@@ -39,15 +39,7 @@ class RememberMeListener implements ListenerInterface
private $sessionStrategy;
/**
* Constructor.
*
* @param TokenStorageInterface $tokenStorage
* @param RememberMeServicesInterface $rememberMeServices
* @param AuthenticationManagerInterface $authenticationManager
* @param LoggerInterface|null $logger
* @param EventDispatcherInterface|null $dispatcher
* @param bool $catchExceptions
* @param SessionAuthenticationStrategyInterface|null $sessionStrategy
* @param bool $catchExceptions
*/
public function __construct(TokenStorageInterface $tokenStorage, RememberMeServicesInterface $rememberMeServices, AuthenticationManagerInterface $authenticationManager, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, $catchExceptions = true, SessionAuthenticationStrategyInterface $sessionStrategy = null)
{
@@ -62,8 +54,6 @@ class RememberMeListener implements ListenerInterface
/**
* Handles remember-me cookie based authentication.
*
* @param GetResponseEvent $event A GetResponseEvent instance
*/
public function handle(GetResponseEvent $event)
{
@@ -72,7 +62,25 @@ class RememberMeListener implements ListenerInterface
}
$request = $event->getRequest();
if (null === $token = $this->rememberMeServices->autoLogin($request)) {
try {
if (null === $token = $this->rememberMeServices->autoLogin($request)) {
return;
}
} catch (AuthenticationException $e) {
if (null !== $this->logger) {
$this->logger->warning(
'The token storage was not populated with remember-me token as the'
.' RememberMeServices was not able to create a token from the remember'
.' me information.', ['exception' => $e]
);
}
$this->rememberMeServices->loginFail($request);
if (!$this->catchExceptions) {
throw $e;
}
return;
}
@@ -96,11 +104,11 @@ class RememberMeListener implements ListenerInterface
$this->logger->warning(
'The token storage was not populated with remember-me token as the'
.' AuthenticationManager rejected the AuthenticationToken returned'
.' by the RememberMeServices.', array('exception' => $e)
.' by the RememberMeServices.', ['exception' => $e]
);
}
$this->rememberMeServices->loginFail($request);
$this->rememberMeServices->loginFail($request, $e);
if (!$this->catchExceptions) {
throw $e;
@@ -11,12 +11,12 @@
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* REMOTE_USER authentication listener.
@@ -41,9 +41,9 @@ class RemoteUserAuthenticationListener extends AbstractPreAuthenticatedListener
protected function getPreAuthenticatedData(Request $request)
{
if (!$request->server->has($this->userKey)) {
throw new BadCredentialsException(sprintf('User key was not found: %s', $this->userKey));
throw new BadCredentialsException(sprintf('User key was not found: "%s".', $this->userKey));
}
return array($request->server->get($this->userKey), null);
return [$request->server->get($this->userKey), null];
}
}
@@ -11,22 +11,23 @@
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Http\Authentication\SimpleFormAuthenticatorInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\ParameterBagUtils;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Psr\Log\LoggerInterface;
/**
* @author Jordi Boggiano <j.boggiano@seld.be>
@@ -37,40 +38,35 @@ class SimpleFormAuthenticationListener extends AbstractAuthenticationListener
private $csrfTokenManager;
/**
* Constructor.
*
* @param TokenStorageInterface $tokenStorage A TokenStorageInterface instance
* @param AuthenticationManagerInterface $authenticationManager An AuthenticationManagerInterface instance
* @param SessionAuthenticationStrategyInterface $sessionStrategy
* @param HttpUtils $httpUtils An HttpUtils instance
* @param string $providerKey
* @param AuthenticationSuccessHandlerInterface $successHandler
* @param AuthenticationFailureHandlerInterface $failureHandler
* @param array $options An array of options for the processing of a
* successful, or failed authentication attempt
* @param LoggerInterface|null $logger A LoggerInterface instance
* @param EventDispatcherInterface|null $dispatcher An EventDispatcherInterface instance
* @param CsrfTokenManagerInterface|null $csrfTokenManager A CsrfTokenManagerInterface instance
* @param SimpleFormAuthenticatorInterface|null $simpleAuthenticator A SimpleFormAuthenticatorInterface instance
* @param TokenStorageInterface $tokenStorage A TokenStorageInterface instance
* @param AuthenticationManagerInterface $authenticationManager An AuthenticationManagerInterface instance
* @param HttpUtils $httpUtils An HttpUtils instance
* @param string $providerKey
* @param array $options An array of options for the processing of a
* successful, or failed authentication attempt
* @param LoggerInterface|null $logger A LoggerInterface instance
* @param EventDispatcherInterface|null $dispatcher An EventDispatcherInterface instance
* @param CsrfTokenManagerInterface|null $csrfTokenManager A CsrfTokenManagerInterface instance
* @param SimpleFormAuthenticatorInterface|null $simpleAuthenticator A SimpleFormAuthenticatorInterface instance
*
* @throws \InvalidArgumentException In case no simple authenticator is provided
*/
public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, CsrfTokenManagerInterface $csrfTokenManager = null, SimpleFormAuthenticatorInterface $simpleAuthenticator = null)
public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = [], LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, CsrfTokenManagerInterface $csrfTokenManager = null, SimpleFormAuthenticatorInterface $simpleAuthenticator = null)
{
if (!$simpleAuthenticator) {
throw new \InvalidArgumentException('Missing simple authenticator');
throw new \InvalidArgumentException('Missing simple authenticator.');
}
$this->simpleAuthenticator = $simpleAuthenticator;
$this->csrfTokenManager = $csrfTokenManager;
$options = array_merge(array(
$options = array_merge([
'username_parameter' => '_username',
'password_parameter' => '_password',
'csrf_parameter' => '_csrf_token',
'csrf_token_id' => 'authenticate',
'post_only' => true,
), $options);
], $options);
parent::__construct($tokenStorage, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, $options, $logger, $dispatcher);
}
@@ -101,14 +97,20 @@ class SimpleFormAuthenticationListener extends AbstractAuthenticationListener
}
if ($this->options['post_only']) {
$username = trim(ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']));
$username = ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']);
$password = ParameterBagUtils::getParameterBagValue($request->request, $this->options['password_parameter']);
} else {
$username = trim(ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']));
$username = ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']);
$password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']);
}
if (strlen($username) > Security::MAX_USERNAME_LENGTH) {
if (!\is_string($username) && (!\is_object($username) || !method_exists($username, '__toString'))) {
throw new BadRequestHttpException(sprintf('The key "%s" must be a string, "%s" given.', $this->options['username_parameter'], \gettype($username)));
}
$username = trim($username);
if (\strlen($username) > Security::MAX_USERNAME_LENGTH) {
throw new BadCredentialsException('Invalid username.');
}
@@ -11,19 +11,22 @@
namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
/**
* SimplePreAuthenticationListener implements simple proxying to an authenticator.
@@ -38,10 +41,9 @@ class SimplePreAuthenticationListener implements ListenerInterface
private $simpleAuthenticator;
private $logger;
private $dispatcher;
private $sessionStrategy;
/**
* Constructor.
*
* @param TokenStorageInterface $tokenStorage A TokenStorageInterface instance
* @param AuthenticationManagerInterface $authenticationManager An AuthenticationManagerInterface instance
* @param string $providerKey
@@ -64,16 +66,24 @@ class SimplePreAuthenticationListener implements ListenerInterface
}
/**
* Handles basic authentication.
* Call this method if your authentication token is stored to a session.
*
* @param GetResponseEvent $event A GetResponseEvent instance
* @final
*/
public function setSessionAuthenticationStrategy(SessionAuthenticationStrategyInterface $sessionStrategy)
{
$this->sessionStrategy = $sessionStrategy;
}
/**
* Handles basic authentication.
*/
public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
if (null !== $this->logger) {
$this->logger->info('Attempting SimplePreAuthentication.', array('key' => $this->providerKey, 'authenticator' => get_class($this->simpleAuthenticator)));
$this->logger->info('Attempting SimplePreAuthentication.', ['key' => $this->providerKey, 'authenticator' => \get_class($this->simpleAuthenticator)]);
}
if (null !== $this->tokenStorage->getToken() && !$this->tokenStorage->getToken() instanceof AnonymousToken) {
@@ -89,6 +99,9 @@ class SimplePreAuthenticationListener implements ListenerInterface
}
$token = $this->authenticationManager->authenticate($token);
$this->migrateSession($request, $token);
$this->tokenStorage->setToken($token);
if (null !== $this->dispatcher) {
@@ -99,7 +112,7 @@ class SimplePreAuthenticationListener implements ListenerInterface
$this->tokenStorage->setToken(null);
if (null !== $this->logger) {
$this->logger->info('SimplePreAuthentication request failed.', array('exception' => $e, 'authenticator' => get_class($this->simpleAuthenticator)));
$this->logger->info('SimplePreAuthentication request failed.', ['exception' => $e, 'authenticator' => \get_class($this->simpleAuthenticator)]);
}
if ($this->simpleAuthenticator instanceof AuthenticationFailureHandlerInterface) {
@@ -107,7 +120,7 @@ class SimplePreAuthenticationListener implements ListenerInterface
if ($response instanceof Response) {
$event->setResponse($response);
} elseif (null !== $response) {
throw new \UnexpectedValueException(sprintf('The %s::onAuthenticationFailure method must return null or a Response object', get_class($this->simpleAuthenticator)));
throw new \UnexpectedValueException(sprintf('The "%s::onAuthenticationFailure()" method must return null or a Response object.', \get_class($this->simpleAuthenticator)));
}
}
@@ -119,8 +132,17 @@ class SimplePreAuthenticationListener implements ListenerInterface
if ($response instanceof Response) {
$event->setResponse($response);
} elseif (null !== $response) {
throw new \UnexpectedValueException(sprintf('The %s::onAuthenticationSuccess method must return null or a Response object', get_class($this->simpleAuthenticator)));
throw new \UnexpectedValueException(sprintf('The "%s::onAuthenticationSuccess()" method must return null or a Response object.', \get_class($this->simpleAuthenticator)));
}
}
}
private function migrateSession(Request $request, TokenInterface $token)
{
if (!$this->sessionStrategy || !$request->hasSession() || !$request->hasPreviousSession()) {
return;
}
$this->sessionStrategy->onAuthentication($request, $token);
}
}
+53 -39
View File
@@ -11,24 +11,24 @@
namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\Event\SwitchUserEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* SwitchUserListener allows a user to impersonate another one temporarily
@@ -38,6 +38,8 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
*/
class SwitchUserListener implements ListenerInterface
{
const EXIT_VALUE = '_exit';
private $tokenStorage;
private $provider;
private $userChecker;
@@ -47,8 +49,9 @@ class SwitchUserListener implements ListenerInterface
private $role;
private $logger;
private $dispatcher;
private $stateless;
public function __construct(TokenStorageInterface $tokenStorage, UserProviderInterface $provider, UserCheckerInterface $userChecker, $providerKey, AccessDecisionManagerInterface $accessDecisionManager, LoggerInterface $logger = null, $usernameParameter = '_switch_user', $role = 'ROLE_ALLOWED_TO_SWITCH', EventDispatcherInterface $dispatcher = null)
public function __construct(TokenStorageInterface $tokenStorage, UserProviderInterface $provider, UserCheckerInterface $userChecker, $providerKey, AccessDecisionManagerInterface $accessDecisionManager, LoggerInterface $logger = null, $usernameParameter = '_switch_user', $role = 'ROLE_ALLOWED_TO_SWITCH', EventDispatcherInterface $dispatcher = null, $stateless = false)
{
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
@@ -63,88 +66,102 @@ class SwitchUserListener implements ListenerInterface
$this->role = $role;
$this->logger = $logger;
$this->dispatcher = $dispatcher;
$this->stateless = $stateless;
}
/**
* Handles the switch to another user.
*
* @param GetResponseEvent $event A GetResponseEvent instance
*
* @throws \LogicException if switching to a user failed
*/
public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
if (!$request->get($this->usernameParameter)) {
// usernames can be falsy
$username = $request->get($this->usernameParameter);
if (null === $username || '' === $username) {
$username = $request->headers->get($this->usernameParameter);
}
// if it's still "empty", nothing to do.
if (null === $username || '' === $username) {
return;
}
if ('_exit' === $request->get($this->usernameParameter)) {
if (null === $this->tokenStorage->getToken()) {
throw new AuthenticationCredentialsNotFoundException('Could not find original Token object.');
}
if (self::EXIT_VALUE === $username) {
$this->tokenStorage->setToken($this->attemptExitUser($request));
} else {
try {
$this->tokenStorage->setToken($this->attemptSwitchUser($request));
$this->tokenStorage->setToken($this->attemptSwitchUser($request, $username));
} catch (AuthenticationException $e) {
throw new \LogicException(sprintf('Switch User failed: "%s"', $e->getMessage()));
throw new \LogicException('Switch User failed: '.$e->getMessage());
}
}
$request->query->remove($this->usernameParameter);
$request->server->set('QUERY_STRING', http_build_query($request->query->all()));
if (!$this->stateless) {
$request->query->remove($this->usernameParameter);
$request->server->set('QUERY_STRING', http_build_query($request->query->all(), '', '&'));
$response = new RedirectResponse($request->getUri(), 302);
$response = new RedirectResponse($request->getUri(), 302);
$event->setResponse($response);
$event->setResponse($response);
}
}
/**
* Attempts to switch to another user.
*
* @param Request $request A Request instance
* @param Request $request A Request instance
* @param string $username
*
* @return TokenInterface|null The new TokenInterface if successfully switched, null otherwise
*
* @throws \LogicException
* @throws AccessDeniedException
*/
private function attemptSwitchUser(Request $request)
private function attemptSwitchUser(Request $request, $username)
{
$token = $this->tokenStorage->getToken();
$originalToken = $this->getOriginalToken($token);
if (false !== $originalToken) {
if ($token->getUsername() === $request->get($this->usernameParameter)) {
if ($token->getUsername() === $username) {
return $token;
}
throw new \LogicException(sprintf('You are already switched to "%s" user.', $token->getUsername()));
// User already switched, exit before seamlessly switching to another user
$token = $this->attemptExitUser($request);
}
if (false === $this->accessDecisionManager->decide($token, array($this->role))) {
if (false === $this->accessDecisionManager->decide($token, [$this->role])) {
$exception = new AccessDeniedException();
$exception->setAttributes($this->role);
throw $exception;
}
$username = $request->get($this->usernameParameter);
if (null !== $this->logger) {
$this->logger->info('Attempting to switch to user.', array('username' => $username));
$this->logger->info('Attempting to switch to user.', ['username' => $username]);
}
$user = $this->provider->loadUserByUsername($username);
$this->userChecker->checkPostAuth($user);
$roles = $user->getRoles();
$roles[] = new SwitchUserRole('ROLE_PREVIOUS_ADMIN', $this->tokenStorage->getToken());
$roles[] = new SwitchUserRole('ROLE_PREVIOUS_ADMIN', $token);
$token = new UsernamePasswordToken($user, $user->getPassword(), $this->providerKey, $roles);
if (null !== $this->dispatcher) {
$switchEvent = new SwitchUserEvent($request, $token->getUser());
$switchEvent = new SwitchUserEvent($request, $token->getUser(), $token);
$this->dispatcher->dispatch(SecurityEvents::SWITCH_USER, $switchEvent);
// use the token from the event in case any listeners have replaced it.
$token = $switchEvent->getToken();
}
return $token;
@@ -153,22 +170,21 @@ class SwitchUserListener implements ListenerInterface
/**
* Attempts to exit from an already switched user.
*
* @param Request $request A Request instance
*
* @return TokenInterface The original TokenInterface instance
*
* @throws AuthenticationCredentialsNotFoundException
*/
private function attemptExitUser(Request $request)
{
if (null === ($currentToken = $this->tokenStorage->getToken()) || false === $original = $this->getOriginalToken($currentToken)) {
if (false === $original = $this->getOriginalToken($this->tokenStorage->getToken())) {
throw new AuthenticationCredentialsNotFoundException('Could not find original Token object.');
}
if (null !== $this->dispatcher && $original->getUser() instanceof UserInterface) {
$user = $this->provider->refreshUser($original->getUser());
$switchEvent = new SwitchUserEvent($request, $user);
$switchEvent = new SwitchUserEvent($request, $user, $original);
$this->dispatcher->dispatch(SecurityEvents::SWITCH_USER, $switchEvent);
$original = $switchEvent->getToken();
}
return $original;
@@ -177,8 +193,6 @@ class SwitchUserListener implements ListenerInterface
/**
* Gets the original Token from a switched one.
*
* @param TokenInterface $token A switched TokenInterface instance
*
* @return TokenInterface|false The original TokenInterface instance, false if the current TokenInterface is not switched
*/
private function getOriginalToken(TokenInterface $token)
@@ -11,22 +11,23 @@
namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\HttpFoundation\Request;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\ParameterBagUtils;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\ParameterBagUtils;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
/**
* UsernamePasswordFormAuthenticationListener is the default implementation of
@@ -38,15 +39,15 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
{
private $csrfTokenManager;
public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, CsrfTokenManagerInterface $csrfTokenManager = null)
public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = [], LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, CsrfTokenManagerInterface $csrfTokenManager = null)
{
parent::__construct($tokenStorage, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, array_merge(array(
parent::__construct($tokenStorage, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, array_merge([
'username_parameter' => '_username',
'password_parameter' => '_password',
'csrf_parameter' => '_csrf_token',
'csrf_token_id' => 'authenticate',
'post_only' => true,
), $options), $logger, $dispatcher);
], $options), $logger, $dispatcher);
$this->csrfTokenManager = $csrfTokenManager;
}
@@ -77,14 +78,20 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
}
if ($this->options['post_only']) {
$username = trim(ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']));
$username = ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']);
$password = ParameterBagUtils::getParameterBagValue($request->request, $this->options['password_parameter']);
} else {
$username = trim(ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']));
$username = ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']);
$password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']);
}
if (strlen($username) > Security::MAX_USERNAME_LENGTH) {
if (!\is_string($username) && (!\is_object($username) || !method_exists($username, '__toString'))) {
throw new BadRequestHttpException(sprintf('The key "%s" must be a string, "%s" given.', $this->options['username_parameter'], \gettype($username)));
}
$username = trim($username);
if (\strlen($username) > Security::MAX_USERNAME_LENGTH) {
throw new BadCredentialsException('Invalid username.');
}
@@ -11,12 +11,12 @@
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* X509 authentication listener.
@@ -44,14 +44,17 @@ class X509AuthenticationListener extends AbstractPreAuthenticatedListener
$user = null;
if ($request->server->has($this->userKey)) {
$user = $request->server->get($this->userKey);
} elseif ($request->server->has($this->credentialKey) && preg_match('#/emailAddress=(.+\@.+\..+)(/|$)#', $request->server->get($this->credentialKey), $matches)) {
} elseif (
$request->server->has($this->credentialKey)
&& preg_match('#emailAddress=([^,/@]++@[^,/]++)#', $request->server->get($this->credentialKey), $matches)
) {
$user = $matches[1];
}
if (null === $user) {
throw new BadCredentialsException(sprintf('SSL credentials not found: %s, %s', $this->userKey, $this->credentialKey));
throw new BadCredentialsException(sprintf('SSL credentials not found: "%s", "%s".', $this->userKey, $this->credentialKey));
}
return array($user, $request->server->get($this->credentialKey, ''));
return [$user, $request->server->get($this->credentialKey, '')];
}
}
+7 -11
View File
@@ -11,9 +11,10 @@
namespace Symfony\Component\Security\Http;
use Symfony\Component\HttpFoundation\RequestMatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestMatcherInterface;
use Symfony\Component\Security\Http\Firewall\ExceptionListener;
use Symfony\Component\Security\Http\Firewall\LogoutListener;
/**
* FirewallMap allows configuration of different firewalls for specific parts
@@ -23,16 +24,11 @@ use Symfony\Component\Security\Http\Firewall\ExceptionListener;
*/
class FirewallMap implements FirewallMapInterface
{
private $map = array();
private $map = [];
/**
* @param RequestMatcherInterface $requestMatcher
* @param array $listeners
* @param ExceptionListener $exceptionListener
*/
public function add(RequestMatcherInterface $requestMatcher = null, array $listeners = array(), ExceptionListener $exceptionListener = null)
public function add(RequestMatcherInterface $requestMatcher = null, array $listeners = [], ExceptionListener $exceptionListener = null, LogoutListener $logoutListener = null)
{
$this->map[] = array($requestMatcher, $listeners, $exceptionListener);
$this->map[] = [$requestMatcher, $listeners, $exceptionListener, $logoutListener];
}
/**
@@ -42,10 +38,10 @@ class FirewallMap implements FirewallMapInterface
{
foreach ($this->map as $elements) {
if (null === $elements[0] || $elements[0]->matches($request)) {
return array($elements[1], $elements[2]);
return [$elements[1], $elements[2], $elements[3]];
}
}
return array(array(), null);
return [[], null, null];
}
}
+1 -3
View File
@@ -30,9 +30,7 @@ interface FirewallMapInterface
* If there is no exception listener, the second element of the outer array
* must be null.
*
* @param Request $request
*
* @return array of the format array(array(AuthenticationListener), ExceptionListener)
* @return array of the format [[AuthenticationListener], ExceptionListener]
*/
public function getListeners(Request $request);
}
+19 -9
View File
@@ -11,13 +11,13 @@
namespace Symfony\Component\Security\Http;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
use Symfony\Component\Security\Core\Security;
/**
@@ -32,8 +32,6 @@ class HttpUtils
private $domainRegexp;
/**
* Constructor.
*
* @param UrlGeneratorInterface $urlGenerator A UrlGeneratorInterface instance
* @param UrlMatcherInterface|RequestMatcherInterface $urlMatcher The URL or Request matcher
* @param string|null $domainRegexp A regexp that the target of HTTP redirections must match, scheme included
@@ -43,7 +41,7 @@ class HttpUtils
public function __construct(UrlGeneratorInterface $urlGenerator = null, $urlMatcher = null, $domainRegexp = null)
{
$this->urlGenerator = $urlGenerator;
if ($urlMatcher !== null && !$urlMatcher instanceof UrlMatcherInterface && !$urlMatcher instanceof RequestMatcherInterface) {
if (null !== $urlMatcher && !$urlMatcher instanceof UrlMatcherInterface && !$urlMatcher instanceof RequestMatcherInterface) {
throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.');
}
$this->urlMatcher = $urlMatcher;
@@ -61,7 +59,7 @@ class HttpUtils
*/
public function createRedirectResponse(Request $request, $path, $status = 302)
{
if (null !== $this->domainRegexp && preg_match('#^https?://[^/]++#i', $path, $host) && !preg_match(sprintf($this->domainRegexp, preg_quote($request->getHttpHost())), $host[0])) {
if (null !== $this->domainRegexp && preg_match('#^https?:[/\\\\]{2,}+[^/]++#i', $path, $host) && !preg_match(sprintf($this->domainRegexp, preg_quote($request->getHttpHost())), $host[0])) {
$path = '/';
}
@@ -78,7 +76,7 @@ class HttpUtils
*/
public function createRequest(Request $request, $path)
{
$newRequest = Request::create($this->generateUri($request, $path), 'get', array(), $request->cookies->all(), array(), $request->server->all());
$newRequest = Request::create($this->generateUri($request, $path), 'get', [], $request->cookies->all(), [], $request->server->all());
if ($request->hasSession()) {
$newRequest->setSession($request->getSession());
}
@@ -93,6 +91,13 @@ class HttpUtils
$newRequest->attributes->set(Security::LAST_USERNAME, $request->attributes->get(Security::LAST_USERNAME));
}
if ($request->get('_format')) {
$newRequest->attributes->set('_format', $request->get('_format'));
}
if ($request->getDefaultLocale() !== $request->getLocale()) {
$newRequest->setLocale($request->getLocale());
}
return $newRequest;
}
@@ -157,7 +162,12 @@ class HttpUtils
// fortunately, they all are, so we have to remove entire query string
$position = strpos($url, '?');
if (false !== $position) {
$fragment = parse_url($url, \PHP_URL_FRAGMENT);
$url = substr($url, 0, $position);
// fragment must be preserved
if ($fragment) {
$url .= "#$fragment";
}
}
return $url;
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2004-2017 Fabien Potencier
Copyright (c) 2004-2020 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -11,9 +11,9 @@
namespace Symfony\Component\Security\Http\Logout;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
/**
* This handler clears the passed cookies when a user logs out.
@@ -25,8 +25,6 @@ class CookieClearingLogoutHandler implements LogoutHandlerInterface
private $cookies;
/**
* Constructor.
*
* @param array $cookies An array of cookie names to unset
*/
public function __construct(array $cookies)
@@ -36,15 +34,11 @@ class CookieClearingLogoutHandler implements LogoutHandlerInterface
/**
* Implementation for the LogoutHandlerInterface. Deletes all requested cookies.
*
* @param Request $request
* @param Response $response
* @param TokenInterface $token
*/
public function logout(Request $request, Response $response, TokenInterface $token)
{
foreach ($this->cookies as $cookieName => $cookieData) {
$response->headers->clearCookie($cookieName, $cookieData['path'], $cookieData['domain']);
$response->headers->clearCookie($cookieName, $cookieData['path'], $cookieData['domain'], isset($cookieData['secure']) ? $cookieData['secure'] : false, true, isset($cookieData['samesite']) ? $cookieData['samesite'] : null);
}
}
}
@@ -26,8 +26,7 @@ class DefaultLogoutSuccessHandler implements LogoutSuccessHandlerInterface
protected $targetUrl;
/**
* @param HttpUtils $httpUtils
* @param string $targetUrl
* @param string $targetUrl
*/
public function __construct(HttpUtils $httpUtils, $targetUrl = '/')
{
@@ -11,9 +11,9 @@
namespace Symfony\Component\Security\Http\Logout;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
/**
* Interface that needs to be implemented by LogoutHandlers.
@@ -26,10 +26,6 @@ interface LogoutHandlerInterface
* This method is called by the LogoutListener when a user has requested
* to be logged out. Usually, you would unset session variables, or remove
* cookies, etc.
*
* @param Request $request
* @param Response $response
* @param TokenInterface $token
*/
public function logout(Request $request, Response $response, TokenInterface $token);
}
@@ -30,8 +30,6 @@ interface LogoutSuccessHandlerInterface
/**
* Creates a Response object to send upon a successful logout.
*
* @param Request $request
*
* @return Response never null
*/
public function onLogoutSuccess(Request $request);
+85 -29
View File
@@ -13,6 +13,7 @@ namespace Symfony\Component\Security\Http\Logout;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
@@ -27,7 +28,8 @@ class LogoutUrlGenerator
private $requestStack;
private $router;
private $tokenStorage;
private $listeners = array();
private $listeners = [];
private $currentFirewall;
public function __construct(RequestStack $requestStack = null, UrlGeneratorInterface $router = null, TokenStorageInterface $tokenStorage = null)
{
@@ -39,15 +41,28 @@ class LogoutUrlGenerator
/**
* Registers a firewall's LogoutListener, allowing its URL to be generated.
*
* @param string $key The firewall key
* @param string $logoutPath The path that starts the logout process
* @param string $csrfTokenId The ID of the CSRF token
* @param string $csrfParameter The CSRF token parameter name
* @param CsrfTokenManagerInterface $csrfTokenManager A CsrfTokenManagerInterface instance
* @param string $key The firewall key
* @param string $logoutPath The path that starts the logout process
* @param string|null $csrfTokenId The ID of the CSRF token
* @param string|null $csrfParameter The CSRF token parameter name
* @param string|null $context The listener context
*/
public function registerListener($key, $logoutPath, $csrfTokenId, $csrfParameter, CsrfTokenManagerInterface $csrfTokenManager = null)
public function registerListener($key, $logoutPath, $csrfTokenId, $csrfParameter, CsrfTokenManagerInterface $csrfTokenManager = null/*, string $context = null*/)
{
$this->listeners[$key] = array($logoutPath, $csrfTokenId, $csrfParameter, $csrfTokenManager);
if (\func_num_args() >= 6) {
$context = func_get_arg(5);
} else {
if (__CLASS__ !== static::class) {
$r = new \ReflectionMethod($this, __FUNCTION__);
if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
@trigger_error(sprintf('The "%s()" method will have a 6th `string $context = null` argument in version 4.0. Not defining it is deprecated since Symfony 3.3.', __METHOD__), \E_USER_DEPRECATED);
}
}
$context = null;
}
$this->listeners[$key] = [$logoutPath, $csrfTokenId, $csrfParameter, $csrfTokenManager, $context];
}
/**
@@ -74,6 +89,15 @@ class LogoutUrlGenerator
return $this->generateLogoutUrl($key, UrlGeneratorInterface::ABSOLUTE_URL);
}
/**
* @param string|null $key The current firewall key
* @param string|null $context The current firewall context
*/
public function setCurrentFirewall($key, $context = null)
{
$this->currentFirewall = [$key, $context];
}
/**
* Generates the logout URL for the firewall.
*
@@ -81,34 +105,16 @@ class LogoutUrlGenerator
* @param int $referenceType The type of reference (one of the constants in UrlGeneratorInterface)
*
* @return string The logout URL
*
* @throws \InvalidArgumentException if no LogoutListener is registered for the key or the key could not be found automatically.
*/
private function generateLogoutUrl($key, $referenceType)
{
// Fetch the current provider key from token, if possible
if (null === $key && null !== $this->tokenStorage) {
$token = $this->tokenStorage->getToken();
if (null !== $token && method_exists($token, 'getProviderKey')) {
$key = $token->getProviderKey();
}
}
if (null === $key) {
throw new \InvalidArgumentException('Unable to find the current firewall LogoutListener, please provide the provider key manually.');
}
if (!array_key_exists($key, $this->listeners)) {
throw new \InvalidArgumentException(sprintf('No LogoutListener found for firewall key "%s".', $key));
}
list($logoutPath, $csrfTokenId, $csrfParameter, $csrfTokenManager) = $this->listeners[$key];
list($logoutPath, $csrfTokenId, $csrfParameter, $csrfTokenManager) = $this->getListener($key);
if (null === $logoutPath) {
throw new \LogicException('Unable to generate the logout URL without a path.');
}
$parameters = null !== $csrfTokenManager ? array($csrfParameter => (string) $csrfTokenManager->getToken($csrfTokenId)) : array();
$parameters = null !== $csrfTokenManager ? [$csrfParameter => (string) $csrfTokenManager->getToken($csrfTokenId)] : [];
if ('/' === $logoutPath[0]) {
if (!$this->requestStack) {
@@ -120,7 +126,7 @@ class LogoutUrlGenerator
$url = UrlGeneratorInterface::ABSOLUTE_URL === $referenceType ? $request->getUriForPath($logoutPath) : $request->getBaseUrl().$logoutPath;
if (!empty($parameters)) {
$url .= '?'.http_build_query($parameters);
$url .= '?'.http_build_query($parameters, '', '&');
}
} else {
if (!$this->router) {
@@ -132,4 +138,54 @@ class LogoutUrlGenerator
return $url;
}
/**
* @param string|null $key The firewall key or null use the current firewall key
*
* @return array The logout listener found
*
* @throws \InvalidArgumentException if no LogoutListener is registered for the key or could not be found automatically
*/
private function getListener($key)
{
if (null !== $key) {
if (isset($this->listeners[$key])) {
return $this->listeners[$key];
}
throw new \InvalidArgumentException(sprintf('No LogoutListener found for firewall key "%s".', $key));
}
// Fetch the current provider key from token, if possible
if (null !== $this->tokenStorage) {
$token = $this->tokenStorage->getToken();
if ($token instanceof AnonymousToken) {
throw new \InvalidArgumentException('Unable to generate a logout url for an anonymous token.');
}
if (null !== $token && method_exists($token, 'getProviderKey')) {
$key = $token->getProviderKey();
if (isset($this->listeners[$key])) {
return $this->listeners[$key];
}
}
}
// Fetch from injected current firewall information, if possible
list($key, $context) = $this->currentFirewall;
if (isset($this->listeners[$key])) {
return $this->listeners[$key];
}
foreach ($this->listeners as $listener) {
if (isset($listener[4]) && $context === $listener[4]) {
return $listener;
}
}
throw new \InvalidArgumentException('Unable to find the current firewall LogoutListener, please provide the provider key manually.');
}
}
@@ -11,9 +11,9 @@
namespace Symfony\Component\Security\Http\Logout;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
/**
* Handler for clearing invalidating the current session.
@@ -24,10 +24,6 @@ class SessionLogoutHandler implements LogoutHandlerInterface
{
/**
* Invalidate the current session.
*
* @param Request $request
* @param Response $response
* @param TokenInterface $token
*/
public function logout(Request $request, Response $response, TokenInterface $token)
{
+4 -4
View File
@@ -45,7 +45,7 @@ final class ParameterBagUtils
$root = substr($path, 0, $pos);
if (null === $value = $parameters->get($root)) {
return;
return null;
}
if (null === self::$propertyAccessor) {
@@ -55,7 +55,7 @@ final class ParameterBagUtils
try {
return self::$propertyAccessor->getValue($value, substr($path, $pos));
} catch (AccessException $e) {
return;
return null;
}
}
@@ -80,7 +80,7 @@ final class ParameterBagUtils
$root = substr($path, 0, $pos);
if (null === $value = $request->get($root)) {
return;
return null;
}
if (null === self::$propertyAccessor) {
@@ -90,7 +90,7 @@ final class ParameterBagUtils
try {
return self::$propertyAccessor->getValue($value, substr($path, $pos));
} catch (AccessException $e) {
return;
return null;
}
}
}
+1 -1
View File
@@ -9,7 +9,7 @@ the Java Spring framework.
Resources
---------
* [Documentation](https://symfony.com/doc/current/components/security/index.html)
* [Documentation](https://symfony.com/doc/current/components/security.html)
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
* [Report issues](https://github.com/symfony/symfony/issues) and
[send Pull Requests](https://github.com/symfony/symfony/pulls)
@@ -11,18 +11,18 @@
namespace Symfony\Component\Security\Http\RememberMe;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CookieTheftException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\CookieTheftException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Cookie;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface;
use Symfony\Component\Security\Http\ParameterBagUtils;
/**
@@ -35,26 +35,23 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
const COOKIE_DELIMITER = ':';
protected $logger;
protected $options = array(
protected $options = [
'secure' => false,
'httponly' => true,
);
'samesite' => null,
];
private $providerKey;
private $secret;
private $userProviders;
/**
* Constructor.
*
* @param array $userProviders
* @param string $secret
* @param string $providerKey
* @param array $options
* @param LoggerInterface $logger
*
* @throws \InvalidArgumentException
*/
public function __construct(array $userProviders, $secret, $providerKey, array $options = array(), LoggerInterface $logger = null)
public function __construct(array $userProviders, $secret, $providerKey, array $options = [], LoggerInterface $logger = null)
{
if (empty($secret)) {
throw new \InvalidArgumentException('$secret must not be empty.');
@@ -62,7 +59,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
}
if (0 === count($userProviders)) {
if (0 === \count($userProviders)) {
throw new \InvalidArgumentException('You must provide at least one user provider.');
}
@@ -96,8 +93,6 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
* Implementation of RememberMeServicesInterface. Detects whether a remember-me
* cookie was set, decodes it, and hands it to subclasses for further processing.
*
* @param Request $request
*
* @return TokenInterface|null
*
* @throws CookieTheftException
@@ -105,8 +100,12 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
*/
final public function autoLogin(Request $request)
{
if (($cookie = $request->attributes->get(self::COOKIE_ATTR_NAME)) && null === $cookie->getValue()) {
return null;
}
if (null === $cookie = $request->cookies->get($this->options['name'])) {
return;
return null;
}
if (null !== $this->logger) {
@@ -128,32 +127,38 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
return new RememberMeToken($user, $this->providerKey, $this->secret);
} catch (CookieTheftException $e) {
$this->cancelCookie($request);
$this->loginFail($request, $e);
throw $e;
} catch (UsernameNotFoundException $e) {
if (null !== $this->logger) {
$this->logger->info('User for remember-me cookie not found.');
$this->logger->info('User for remember-me cookie not found.', ['exception' => $e]);
}
$this->loginFail($request, $e);
} catch (UnsupportedUserException $e) {
if (null !== $this->logger) {
$this->logger->warning('User class for remember-me cookie not supported.');
$this->logger->warning('User class for remember-me cookie not supported.', ['exception' => $e]);
}
$this->loginFail($request, $e);
} catch (AuthenticationException $e) {
if (null !== $this->logger) {
$this->logger->debug('Remember-Me authentication failed.', array('exception' => $e));
$this->logger->debug('Remember-Me authentication failed.', ['exception' => $e]);
}
$this->loginFail($request, $e);
} catch (\Exception $e) {
$this->loginFail($request, $e);
throw $e;
}
$this->cancelCookie($request);
return null;
}
/**
* Implementation for LogoutHandlerInterface. Deletes the cookie.
*
* @param Request $request
* @param Response $response
* @param TokenInterface $token
*/
public function logout(Request $request, Response $response, TokenInterface $token)
{
@@ -163,22 +168,16 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
/**
* Implementation for RememberMeServicesInterface. Deletes the cookie when
* an attempted authentication fails.
*
* @param Request $request
*/
final public function loginFail(Request $request)
final public function loginFail(Request $request, \Exception $exception = null)
{
$this->cancelCookie($request);
$this->onLoginFail($request);
$this->onLoginFail($request, $exception);
}
/**
* Implementation for RememberMeServicesInterface. This is called when an
* authentication is successful.
*
* @param Request $request
* @param Response $response
* @param TokenInterface $token The token that resulted in a successful authentication
*/
final public function loginSuccess(Request $request, Response $response, TokenInterface $token)
{
@@ -218,17 +217,11 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
* Subclasses should validate the cookie and do any additional processing
* that is required. This is called from autoLogin().
*
* @param array $cookieParts
* @param Request $request
*
* @return UserInterface
*/
abstract protected function processAutoLoginCookie(array $cookieParts, Request $request);
/**
* @param Request $request
*/
protected function onLoginFail(Request $request)
protected function onLoginFail(Request $request, \Exception $exception = null)
{
}
@@ -236,10 +229,6 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
* This is called after a user has been logged in successfully, and has
* requested remember-me capabilities. The implementation usually sets a
* cookie and possibly stores a persistent record of it.
*
* @param Request $request
* @param Response $response
* @param TokenInterface $token
*/
abstract protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token);
@@ -251,7 +240,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
}
}
throw new UnsupportedUserException(sprintf('There is no user provider that supports class "%s".', $class));
throw new UnsupportedUserException(sprintf('There is no user provider for user "%s". Shouldn\'t the "supportsClass()" method of your user provider return true for this classname?', $class));
}
/**
@@ -269,8 +258,6 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
/**
* Encodes the cookie parts.
*
* @param array $cookieParts
*
* @return string
*
* @throws \InvalidArgumentException When $cookieParts contain the cookie delimiter. Extending class should either remove or escape it.
@@ -279,7 +266,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
{
foreach ($cookieParts as $cookiePart) {
if (false !== strpos($cookiePart, self::COOKIE_DELIMITER)) {
throw new \InvalidArgumentException(sprintf('$cookieParts should not contain the cookie delimiter "%s"', self::COOKIE_DELIMITER));
throw new \InvalidArgumentException(sprintf('$cookieParts should not contain the cookie delimiter "%s".', self::COOKIE_DELIMITER));
}
}
@@ -288,23 +275,19 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
/**
* Deletes the remember-me cookie.
*
* @param Request $request
*/
protected function cancelCookie(Request $request)
{
if (null !== $this->logger) {
$this->logger->debug('Clearing remember-me cookie.', array('name' => $this->options['name']));
$this->logger->debug('Clearing remember-me cookie.', ['name' => $this->options['name']]);
}
$request->attributes->set(self::COOKIE_ATTR_NAME, new Cookie($this->options['name'], null, 1, $this->options['path'], $this->options['domain'], $this->options['secure'], $this->options['httponly']));
$request->attributes->set(self::COOKIE_ATTR_NAME, new Cookie($this->options['name'], null, 1, $this->options['path'], $this->options['domain'], $this->options['secure'], $this->options['httponly'], false, $this->options['samesite']));
}
/**
* Checks whether remember-me capabilities were requested.
*
* @param Request $request
*
* @return bool
*/
protected function isRememberMeRequested(Request $request)
@@ -316,9 +299,9 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
$parameter = ParameterBagUtils::getRequestParameterValue($request, $this->options['remember_me_parameter']);
if (null === $parameter && null !== $this->logger) {
$this->logger->debug('Did not send remember-me cookie.', array('parameter' => $this->options['remember_me_parameter']));
$this->logger->debug('Did not send remember-me cookie.', ['parameter' => $this->options['remember_me_parameter']]);
}
return $parameter === 'true' || $parameter === 'on' || $parameter === '1' || $parameter === 'yes' || $parameter === true;
return 'true' === $parameter || 'on' === $parameter || '1' === $parameter || 'yes' === $parameter || true === $parameter;
}
}
@@ -11,14 +11,14 @@
namespace Symfony\Component\Security\Http\RememberMe;
use Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken;
use Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CookieTheftException;
use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
/**
* Concrete implementation of the RememberMeServicesInterface which needs
@@ -29,13 +29,9 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
*/
class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
{
/** @var TokenProviderInterface */
private $tokenProvider;
/**
* Sets the token provider.
*
* @param TokenProviderInterface $tokenProvider
*/
public function setTokenProvider(TokenProviderInterface $tokenProvider)
{
$this->tokenProvider = $tokenProvider;
@@ -51,7 +47,7 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
// Delete cookie from the tokenProvider
if (null !== ($cookie = $request->cookies->get($this->options['name']))
&& count($parts = $this->decodeCookie($cookie)) === 2
&& 2 === \count($parts = $this->decodeCookie($cookie))
) {
list($series) = $parts;
$this->tokenProvider->deleteTokenBySeries($series);
@@ -63,7 +59,7 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
*/
protected function processAutoLoginCookie(array $cookieParts, Request $request)
{
if (count($cookieParts) !== 2) {
if (2 !== \count($cookieParts)) {
throw new AuthenticationException('The cookie is invalid.');
}
@@ -83,12 +79,14 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
$request->attributes->set(self::COOKIE_ATTR_NAME,
new Cookie(
$this->options['name'],
$this->encodeCookie(array($series, $tokenValue)),
$this->encodeCookie([$series, $tokenValue]),
time() + $this->options['lifetime'],
$this->options['path'],
$this->options['domain'],
$this->options['secure'],
$this->options['httponly']
$this->options['httponly'],
false,
$this->options['samesite']
)
);
@@ -105,7 +103,7 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
$this->tokenProvider->createNewToken(
new PersistentToken(
get_class($user = $token->getUser()),
\get_class($user = $token->getUser()),
$user->getUsername(),
$series,
$tokenValue,
@@ -116,12 +114,14 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
$response->headers->setCookie(
new Cookie(
$this->options['name'],
$this->encodeCookie(array($series, $tokenValue)),
$this->encodeCookie([$series, $tokenValue]),
time() + $this->options['lifetime'],
$this->options['path'],
$this->options['domain'],
$this->options['secure'],
$this->options['httponly']
$this->options['httponly'],
false,
$this->options['samesite']
)
);
}
@@ -11,9 +11,9 @@
namespace Symfony\Component\Security\Http\RememberMe;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
/**
* Interface that needs to be implemented by classes which provide remember-me
@@ -30,8 +30,6 @@ interface RememberMeServicesInterface
/**
* This attribute name can be used by the implementation if it needs to set
* a cookie on the Request when there is no actual Response, yet.
*
* @var string
*/
const COOKIE_ATTR_NAME = '_security_remember_me_cookie';
@@ -48,9 +46,7 @@ interface RememberMeServicesInterface
* make sure to throw an AuthenticationException as this will consequentially
* result in a call to loginFail() and therefore an invalidation of the cookie.
*
* @param Request $request
*
* @return TokenInterface
* @return TokenInterface|null
*/
public function autoLogin(Request $request);
@@ -59,10 +55,8 @@ interface RememberMeServicesInterface
* credentials supplied by the user were missing or otherwise invalid.
*
* This method needs to take care of invalidating the cookie.
*
* @param Request $request
*/
public function loginFail(Request $request);
public function loginFail(Request $request, \Exception $exception = null);
/**
* Called whenever an interactive authentication attempt is successful
@@ -74,10 +68,6 @@ interface RememberMeServicesInterface
* Instead, implementations should typically look for a request parameter
* (such as a HTTP POST parameter) that indicates the browser has explicitly
* requested for the authentication to be remembered.
*
* @param Request $request
* @param Response $response
* @param TokenInterface $token
*/
public function loginSuccess(Request $request, Response $response, TokenInterface $token);
}
@@ -11,9 +11,9 @@
namespace Symfony\Component\Security\Http\RememberMe;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Adds remember-me cookies to the Response.
@@ -22,9 +22,6 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
*/
class ResponseListener implements EventSubscriberInterface
{
/**
* @param FilterResponseEvent $event
*/
public function onKernelResponse(FilterResponseEvent $event)
{
if (!$event->isMasterRequest()) {
@@ -44,6 +41,6 @@ class ResponseListener implements EventSubscriberInterface
*/
public static function getSubscribedEvents()
{
return array(KernelEvents::RESPONSE => 'onKernelResponse');
return [KernelEvents::RESPONSE => 'onKernelResponse'];
}
}
@@ -31,7 +31,7 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
*/
protected function processAutoLoginCookie(array $cookieParts, Request $request)
{
if (count($cookieParts) !== 4) {
if (4 !== \count($cookieParts)) {
throw new AuthenticationException('The cookie is invalid.');
}
@@ -50,7 +50,7 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
}
if (!$user instanceof UserInterface) {
throw new \RuntimeException(sprintf('The UserProviderInterface implementation must return an instance of UserInterface, but returned "%s".', get_class($user)));
throw new \RuntimeException(sprintf('The UserProviderInterface implementation must return an instance of UserInterface, but returned "%s".', \get_class($user)));
}
if (true !== hash_equals($this->generateCookieHash($class, $username, $expires, $user->getPassword()), $hash)) {
@@ -71,7 +71,7 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
{
$user = $token->getUser();
$expires = time() + $this->options['lifetime'];
$value = $this->generateCookieValue(get_class($user), $user->getUsername(), $expires, $user->getPassword());
$value = $this->generateCookieValue(\get_class($user), $user->getUsername(), $expires, $user->getPassword());
$response->headers->setCookie(
new Cookie(
@@ -81,7 +81,9 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
$this->options['path'],
$this->options['domain'],
$this->options['secure'],
$this->options['httponly']
$this->options['httponly'],
false,
$this->options['samesite']
)
);
}
@@ -89,10 +91,10 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
/**
* Generates the cookie value.
*
* @param string $class
* @param string $username The username
* @param int $expires The Unix timestamp when the cookie expires
* @param string $password The encoded password
* @param string $class
* @param string $username The username
* @param int $expires The Unix timestamp when the cookie expires
* @param string|null $password The encoded password
*
* @return string
*/
@@ -100,26 +102,26 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
{
// $username is encoded because it might contain COOKIE_DELIMITER,
// we assume other values don't
return $this->encodeCookie(array(
return $this->encodeCookie([
$class,
base64_encode($username),
$expires,
$this->generateCookieHash($class, $username, $expires, $password),
));
]);
}
/**
* Generates a hash for the cookie to ensure it is not being tempered with.
* Generates a hash for the cookie to ensure it is not being tampered with.
*
* @param string $class
* @param string $username The username
* @param int $expires The Unix timestamp when the cookie expires
* @param string $password The encoded password
* @param string $class
* @param string $username The username
* @param int $expires The Unix timestamp when the cookie expires
* @param string|null $password The encoded password
*
* @return string
*/
protected function generateCookieHash($class, $username, $expires, $password)
{
return hash_hmac('sha256', $class.$username.$expires.$password, $this->getSecret());
return hash_hmac('sha256', $class.self::COOKIE_DELIMITER.$username.self::COOKIE_DELIMITER.$expires.self::COOKIE_DELIMITER.$password, $this->getSecret());
}
}
+5 -6
View File
@@ -14,12 +14,13 @@ namespace Symfony\Component\Security\Http;
final class SecurityEvents
{
/**
* The INTERACTIVE_LOGIN event occurs after a user is logged in
* interactively for authentication based on http, cookies or X509.
* The INTERACTIVE_LOGIN event occurs after a user has actively logged
* into your website. It is important to distinguish this action from
* non-interactive authentication methods, such as:
* - authentication based on your session.
* - authentication using a HTTP basic or HTTP digest header.
*
* @Event("Symfony\Component\Security\Http\Event\InteractiveLoginEvent")
*
* @var string
*/
const INTERACTIVE_LOGIN = 'security.interactive_login';
@@ -28,8 +29,6 @@ final class SecurityEvents
* before exit from an already switched user.
*
* @Event("Symfony\Component\Security\Http\Event\SwitchUserEvent")
*
* @var string
*/
const SWITCH_USER = 'security.switch_user';
}
@@ -11,8 +11,8 @@
namespace Symfony\Component\Security\Http\Session;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
/**
* The default session strategy implementation.
@@ -47,6 +47,8 @@ class SessionAuthenticationStrategy implements SessionAuthenticationStrategyInte
return;
case self::MIGRATE:
// Note: this logic is duplicated in several authentication listeners
// until Symfony 5.0 due to a security fix with BC compat
$request->getSession()->migrate(true);
return;
@@ -57,7 +59,7 @@ class SessionAuthenticationStrategy implements SessionAuthenticationStrategyInte
return;
default:
throw new \RuntimeException(sprintf('Invalid session authentication strategy "%s"', $this->strategy));
throw new \RuntimeException(sprintf('Invalid session authentication strategy "%s".', $this->strategy));
}
}
}
@@ -11,8 +11,8 @@
namespace Symfony\Component\Security\Http\Session;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
/**
* SessionAuthenticationStrategyInterface.
@@ -27,11 +27,8 @@ interface SessionAuthenticationStrategyInterface
/**
* This performs any necessary changes to the session.
*
* This method is called before the TokenStorage is populated with a
* Token, and only by classes inheriting from AbstractAuthenticationListener.
*
* @param Request $request
* @param TokenInterface $token
* This method should be called before the TokenStorage is populated with a
* Token. It should be used by authentication listeners when a session is used.
*/
public function onAuthentication(Request $request, TokenInterface $token);
}
+6 -6
View File
@@ -23,10 +23,10 @@ class AccessMapTest extends TestCase
$requestMatcher2 = $this->getRequestMatcher($request, true);
$map = new AccessMap();
$map->add($requestMatcher1, array('ROLE_ADMIN'), 'http');
$map->add($requestMatcher2, array('ROLE_USER'), 'https');
$map->add($requestMatcher1, ['ROLE_ADMIN'], 'http');
$map->add($requestMatcher2, ['ROLE_USER'], 'https');
$this->assertSame(array(array('ROLE_USER'), 'https'), $map->getPatterns($request));
$this->assertSame([['ROLE_USER'], 'https'], $map->getPatterns($request));
}
public function testReturnsEmptyPatternIfNoneMatched()
@@ -35,9 +35,9 @@ class AccessMapTest extends TestCase
$requestMatcher = $this->getRequestMatcher($request, false);
$map = new AccessMap();
$map->add($requestMatcher, array('ROLE_USER'), 'https');
$map->add($requestMatcher, ['ROLE_USER'], 'https');
$this->assertSame(array(null, null), $map->getPatterns($request));
$this->assertSame([null, null], $map->getPatterns($request));
}
private function getRequestMatcher($request, $matches)
@@ -45,7 +45,7 @@ class AccessMapTest extends TestCase
$requestMatcher = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestMatcherInterface')->getMock();
$requestMatcher->expects($this->once())
->method('matches')->with($request)
->will($this->returnValue($matches));
->willReturn($matches);
return $requestMatcher;
}
@@ -12,10 +12,11 @@
namespace Symfony\Component\Security\Http\Tests\Authentication;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler;
class DefaultAuthenticationFailureHandlerTest extends TestCase
{
@@ -34,25 +35,25 @@ class DefaultAuthenticationFailureHandlerTest extends TestCase
$this->session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock();
$this->request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$this->request->expects($this->any())->method('getSession')->will($this->returnValue($this->session));
$this->exception = $this->getMockBuilder('Symfony\Component\Security\Core\Exception\AuthenticationException')->setMethods(array('getMessage'))->getMock();
$this->request->expects($this->any())->method('getSession')->willReturn($this->session);
$this->exception = $this->getMockBuilder('Symfony\Component\Security\Core\Exception\AuthenticationException')->setMethods(['getMessage'])->getMock();
}
public function testForward()
{
$options = array('failure_forward' => true);
$options = ['failure_forward' => true];
$subRequest = $this->getRequest();
$subRequest->attributes->expects($this->once())
->method('set')->with(Security::AUTHENTICATION_ERROR, $this->exception);
$this->httpUtils->expects($this->once())
->method('createRequest')->with($this->request, '/login')
->will($this->returnValue($subRequest));
->willReturn($subRequest);
$response = new Response();
$this->httpKernel->expects($this->once())
->method('handle')->with($subRequest, HttpKernelInterface::SUB_REQUEST)
->will($this->returnValue($response));
->willReturn($response);
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, $options, $this->logger);
$result = $handler->onAuthenticationFailure($this->request, $this->exception);
@@ -62,12 +63,12 @@ class DefaultAuthenticationFailureHandlerTest extends TestCase
public function testRedirect()
{
$response = new Response();
$response = new RedirectResponse('/login');
$this->httpUtils->expects($this->once())
->method('createRedirectResponse')->with($this->request, '/login')
->will($this->returnValue($response));
->willReturn($response);
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, array(), $this->logger);
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, [], $this->logger);
$result = $handler->onAuthenticationFailure($this->request, $this->exception);
$this->assertSame($response, $result);
@@ -78,13 +79,13 @@ class DefaultAuthenticationFailureHandlerTest extends TestCase
$this->session->expects($this->once())
->method('set')->with(Security::AUTHENTICATION_ERROR, $this->exception);
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, array(), $this->logger);
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, [], $this->logger);
$handler->onAuthenticationFailure($this->request, $this->exception);
}
public function testExceptionIsPassedInRequestOnForward()
{
$options = array('failure_forward' => true);
$options = ['failure_forward' => true];
$subRequest = $this->getRequest();
$subRequest->attributes->expects($this->once())
@@ -92,7 +93,7 @@ class DefaultAuthenticationFailureHandlerTest extends TestCase
$this->httpUtils->expects($this->once())
->method('createRequest')->with($this->request, '/login')
->will($this->returnValue($subRequest));
->willReturn($subRequest);
$this->session->expects($this->never())->method('set');
@@ -105,24 +106,24 @@ class DefaultAuthenticationFailureHandlerTest extends TestCase
$this->logger
->expects($this->once())
->method('debug')
->with('Authentication failure, redirect triggered.', array('failure_path' => '/login'));
->with('Authentication failure, redirect triggered.', ['failure_path' => '/login']);
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, array(), $this->logger);
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, [], $this->logger);
$handler->onAuthenticationFailure($this->request, $this->exception);
}
public function testForwardIsLogged()
{
$options = array('failure_forward' => true);
$options = ['failure_forward' => true];
$this->httpUtils->expects($this->once())
->method('createRequest')->with($this->request, '/login')
->will($this->returnValue($this->getRequest()));
->willReturn($this->getRequest());
$this->logger
->expects($this->once())
->method('debug')
->with('Authentication failure, forward triggered.', array('failure_path' => '/login'));
->with('Authentication failure, forward triggered.', ['failure_path' => '/login']);
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, $options, $this->logger);
$handler->onAuthenticationFailure($this->request, $this->exception);
@@ -130,7 +131,7 @@ class DefaultAuthenticationFailureHandlerTest extends TestCase
public function testFailurePathCanBeOverwritten()
{
$options = array('failure_path' => '/auth/login');
$options = ['failure_path' => '/auth/login'];
$this->httpUtils->expects($this->once())
->method('createRedirectResponse')->with($this->request, '/auth/login');
@@ -143,12 +144,12 @@ class DefaultAuthenticationFailureHandlerTest extends TestCase
{
$this->request->expects($this->once())
->method('get')->with('_failure_path')
->will($this->returnValue('/auth/login'));
->willReturn('/auth/login');
$this->httpUtils->expects($this->once())
->method('createRedirectResponse')->with($this->request, '/auth/login');
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, array(), $this->logger);
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, [], $this->logger);
$handler->onAuthenticationFailure($this->request, $this->exception);
}
@@ -156,22 +157,22 @@ class DefaultAuthenticationFailureHandlerTest extends TestCase
{
$this->request->expects($this->once())
->method('get')->with('_failure_path')
->will($this->returnValue(array('value' => '/auth/login')));
->willReturn(['value' => '/auth/login']);
$this->httpUtils->expects($this->once())
->method('createRedirectResponse')->with($this->request, '/auth/login');
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, array('failure_path_parameter' => '_failure_path[value]'), $this->logger);
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, ['failure_path_parameter' => '_failure_path[value]'], $this->logger);
$handler->onAuthenticationFailure($this->request, $this->exception);
}
public function testFailurePathParameterCanBeOverwritten()
{
$options = array('failure_path_parameter' => '_my_failure_path');
$options = ['failure_path_parameter' => '_my_failure_path'];
$this->request->expects($this->once())
->method('get')->with('_my_failure_path')
->will($this->returnValue('/auth/login'));
->willReturn('/auth/login');
$this->httpUtils->expects($this->once())
->method('createRedirectResponse')->with($this->request, '/auth/login');
@@ -24,7 +24,7 @@ class DefaultAuthenticationSuccessHandlerTest extends TestCase
public function testRequestRedirections(Request $request, $options, $redirectedUrl)
{
$urlGenerator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->getMock();
$urlGenerator->expects($this->any())->method('generate')->will($this->returnValue('http://localhost/login'));
$urlGenerator->expects($this->any())->method('generate')->willReturn('http://localhost/login');
$httpUtils = new HttpUtils($urlGenerator);
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$handler = new DefaultAuthenticationSuccessHandler($httpUtils, $options);
@@ -37,67 +37,77 @@ class DefaultAuthenticationSuccessHandlerTest extends TestCase
public function getRequestRedirections()
{
$session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock();
$session->expects($this->once())->method('get')->with('_security.admin.target_path')->will($this->returnValue('/admin/dashboard'));
$session->expects($this->once())->method('get')->with('_security.admin.target_path')->willReturn('/admin/dashboard');
$session->expects($this->once())->method('remove')->with('_security.admin.target_path');
$requestWithSession = Request::create('/');
$requestWithSession->setSession($session);
return array(
'default' => array(
return [
'default' => [
Request::create('/'),
array(),
[],
'/',
),
'forced target path' => array(
],
'forced target path' => [
Request::create('/'),
array('always_use_default_target_path' => true, 'default_target_path' => '/dashboard'),
['always_use_default_target_path' => true, 'default_target_path' => '/dashboard'],
'/dashboard',
),
'target path as query string' => array(
],
'target path as query string' => [
Request::create('/?_target_path=/dashboard'),
array(),
[],
'/dashboard',
),
'target path name as query string is customized' => array(
],
'target path name as query string is customized' => [
Request::create('/?_my_target_path=/dashboard'),
array('target_path_parameter' => '_my_target_path'),
['target_path_parameter' => '_my_target_path'],
'/dashboard',
),
'target path name as query string is customized and nested' => array(
],
'target path name as query string is customized and nested' => [
Request::create('/?_target_path[value]=/dashboard'),
array('target_path_parameter' => '_target_path[value]'),
['target_path_parameter' => '_target_path[value]'],
'/dashboard',
),
'target path in session' => array(
],
'target path in session' => [
$requestWithSession,
array(),
[],
'/admin/dashboard',
),
'target path as referer' => array(
Request::create('/', 'GET', array(), array(), array(), array('HTTP_REFERER' => 'http://localhost/dashboard')),
array('use_referer' => true),
],
'target path as referer' => [
Request::create('/', 'GET', [], [], [], ['HTTP_REFERER' => 'http://localhost/dashboard']),
['use_referer' => true],
'/dashboard',
),
'target path as referer is ignored if not configured' => array(
Request::create('/', 'GET', array(), array(), array(), array('HTTP_REFERER' => 'http://localhost/dashboard')),
array(),
],
'target path as referer is ignored if not configured' => [
Request::create('/', 'GET', [], [], [], ['HTTP_REFERER' => 'http://localhost/dashboard']),
[],
'/',
),
'target path should be different than login URL' => array(
Request::create('/', 'GET', array(), array(), array(), array('HTTP_REFERER' => 'http://localhost/login')),
array('use_referer' => true, 'login_path' => '/login'),
],
'target path as referer when referer not set' => [
Request::create('/'),
['use_referer' => true],
'/',
),
'target path should be different than login URL (query string does not matter)' => array(
Request::create('/', 'GET', array(), array(), array(), array('HTTP_REFERER' => 'http://localhost/login?t=1&p=2')),
array('use_referer' => true, 'login_path' => '/login'),
],
'target path as referer when referer is ?' => [
Request::create('/', 'GET', [], [], [], ['HTTP_REFERER' => '?']),
['use_referer' => true],
'/',
),
'target path should be different than login URL (login_path as a route)' => array(
Request::create('/', 'GET', array(), array(), array(), array('HTTP_REFERER' => 'http://localhost/login?t=1&p=2')),
array('use_referer' => true, 'login_path' => 'login_route'),
],
'target path should be different than login URL' => [
Request::create('/', 'GET', [], [], [], ['HTTP_REFERER' => 'http://localhost/login']),
['use_referer' => true, 'login_path' => '/login'],
'/',
),
);
],
'target path should be different than login URL (query string does not matter)' => [
Request::create('/', 'GET', [], [], [], ['HTTP_REFERER' => 'http://localhost/login?t=1&p=2']),
['use_referer' => true, 'login_path' => '/login'],
'/',
],
'target path should be different than login URL (login_path as a route)' => [
Request::create('/', 'GET', [], [], [], ['HTTP_REFERER' => 'http://localhost/login?t=1&p=2']),
['use_referer' => true, 'login_path' => 'login_route'],
'/',
],
];
}
}
@@ -53,7 +53,7 @@ class SimpleAuthenticationHandlerTest extends TestCase
$this->successHandler->expects($this->once())
->method('onAuthenticationSuccess')
->with($this->request, $this->token)
->will($this->returnValue($this->response));
->willReturn($this->response);
$handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
$result = $handler->onAuthenticationSuccess($this->request, $this->token);
@@ -70,7 +70,7 @@ class SimpleAuthenticationHandlerTest extends TestCase
$authenticator->expects($this->once())
->method('onAuthenticationSuccess')
->with($this->request, $this->token)
->will($this->returnValue($this->response));
->willReturn($this->response);
$handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
$result = $handler->onAuthenticationSuccess($this->request, $this->token);
@@ -78,12 +78,10 @@ class SimpleAuthenticationHandlerTest extends TestCase
$this->assertSame($this->response, $result);
}
/**
* @expectedException \UnexpectedValueException
* @expectedExceptionMessage onAuthenticationSuccess method must return null to use the default success handler, or a Response object
*/
public function testOnAuthenticationSuccessThrowsAnExceptionIfNonResponseIsReturned()
{
$this->expectException('UnexpectedValueException');
$this->expectExceptionMessage('onAuthenticationSuccess()" method must return null to use the default success handler, or a Response object');
$this->successHandler->expects($this->never())
->method('onAuthenticationSuccess');
@@ -91,7 +89,7 @@ class SimpleAuthenticationHandlerTest extends TestCase
$authenticator->expects($this->once())
->method('onAuthenticationSuccess')
->with($this->request, $this->token)
->will($this->returnValue(new \stdClass()));
->willReturn(new \stdClass());
$handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
$handler->onAuthenticationSuccess($this->request, $this->token);
@@ -102,13 +100,13 @@ class SimpleAuthenticationHandlerTest extends TestCase
$this->successHandler->expects($this->once())
->method('onAuthenticationSuccess')
->with($this->request, $this->token)
->will($this->returnValue($this->response));
->willReturn($this->response);
$authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestSuccessHandlerInterface');
$authenticator->expects($this->once())
->method('onAuthenticationSuccess')
->with($this->request, $this->token)
->will($this->returnValue(null));
->willReturn(null);
$handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
$result = $handler->onAuthenticationSuccess($this->request, $this->token);
@@ -123,7 +121,7 @@ class SimpleAuthenticationHandlerTest extends TestCase
$this->failureHandler->expects($this->once())
->method('onAuthenticationFailure')
->with($this->request, $this->authenticationException)
->will($this->returnValue($this->response));
->willReturn($this->response);
$handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
$result = $handler->onAuthenticationFailure($this->request, $this->authenticationException);
@@ -140,7 +138,7 @@ class SimpleAuthenticationHandlerTest extends TestCase
$authenticator->expects($this->once())
->method('onAuthenticationFailure')
->with($this->request, $this->authenticationException)
->will($this->returnValue($this->response));
->willReturn($this->response);
$handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
$result = $handler->onAuthenticationFailure($this->request, $this->authenticationException);
@@ -148,12 +146,10 @@ class SimpleAuthenticationHandlerTest extends TestCase
$this->assertSame($this->response, $result);
}
/**
* @expectedException \UnexpectedValueException
* @expectedExceptionMessage onAuthenticationFailure method must return null to use the default failure handler, or a Response object
*/
public function testOnAuthenticationFailureThrowsAnExceptionIfNonResponseIsReturned()
{
$this->expectException('UnexpectedValueException');
$this->expectExceptionMessage('onAuthenticationFailure()" method must return null to use the default failure handler, or a Response object');
$this->failureHandler->expects($this->never())
->method('onAuthenticationFailure');
@@ -161,7 +157,7 @@ class SimpleAuthenticationHandlerTest extends TestCase
$authenticator->expects($this->once())
->method('onAuthenticationFailure')
->with($this->request, $this->authenticationException)
->will($this->returnValue(new \stdClass()));
->willReturn(new \stdClass());
$handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
$handler->onAuthenticationFailure($this->request, $this->authenticationException);
@@ -172,13 +168,13 @@ class SimpleAuthenticationHandlerTest extends TestCase
$this->failureHandler->expects($this->once())
->method('onAuthenticationFailure')
->with($this->request, $this->authenticationException)
->will($this->returnValue($this->response));
->willReturn($this->response);
$authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestFailureHandlerInterface');
$authenticator->expects($this->once())
->method('onAuthenticationFailure')
->with($this->request, $this->authenticationException)
->will($this->returnValue(null));
->willReturn(null);
$handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
$result = $handler->onAuthenticationFailure($this->request, $this->authenticationException);
@@ -12,8 +12,8 @@
namespace Symfony\Component\Security\Http\Tests\EntryPoint;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\EntryPoint\BasicAuthenticationEntryPoint;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\EntryPoint\BasicAuthenticationEntryPoint;
class BasicAuthenticationEntryPointTest extends TestCase
{
@@ -12,10 +12,13 @@
namespace Symfony\Component\Security\Http\Tests\EntryPoint;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\EntryPoint\DigestAuthenticationEntryPoint;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\NonceExpiredException;
use Symfony\Component\Security\Http\EntryPoint\DigestAuthenticationEntryPoint;
/**
* @group legacy
*/
class DigestAuthenticationEntryPointTest extends TestCase
{
public function testStart()
@@ -28,7 +31,7 @@ class DigestAuthenticationEntryPointTest extends TestCase
$response = $entryPoint->start($request, $authenticationException);
$this->assertEquals(401, $response->getStatusCode());
$this->assertRegExp('/^Digest realm="TheRealmName", qop="auth", nonce="[a-zA-Z0-9\/+]+={0,2}"$/', $response->headers->get('WWW-Authenticate'));
$this->assertMatchesRegularExpression('/^Digest realm="TheRealmName", qop="auth", nonce="[a-zA-Z0-9\/+]+={0,2}"$/', $response->headers->get('WWW-Authenticate'));
}
public function testStartWithNoException()
@@ -39,7 +42,7 @@ class DigestAuthenticationEntryPointTest extends TestCase
$response = $entryPoint->start($request);
$this->assertEquals(401, $response->getStatusCode());
$this->assertRegExp('/^Digest realm="TheRealmName", qop="auth", nonce="[a-zA-Z0-9\/+]+={0,2}"$/', $response->headers->get('WWW-Authenticate'));
$this->assertMatchesRegularExpression('/^Digest realm="TheRealmName", qop="auth", nonce="[a-zA-Z0-9\/+]+={0,2}"$/', $response->headers->get('WWW-Authenticate'));
}
public function testStartWithNonceExpiredException()
@@ -52,6 +55,6 @@ class DigestAuthenticationEntryPointTest extends TestCase
$response = $entryPoint->start($request, $nonceExpiredException);
$this->assertEquals(401, $response->getStatusCode());
$this->assertRegExp('/^Digest realm="TheRealmName", qop="auth", nonce="[a-zA-Z0-9\/+]+={0,2}", stale="true"$/', $response->headers->get('WWW-Authenticate'));
$this->assertMatchesRegularExpression('/^Digest realm="TheRealmName", qop="auth", nonce="[a-zA-Z0-9\/+]+={0,2}", stale="true"$/', $response->headers->get('WWW-Authenticate'));
}
}
@@ -12,16 +12,17 @@
namespace Symfony\Component\Security\Http\Tests\EntryPoint;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\EntryPoint\FormAuthenticationEntryPoint;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Http\EntryPoint\FormAuthenticationEntryPoint;
class FormAuthenticationEntryPointTest extends TestCase
{
public function testStart()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->disableOriginalClone()->getMock();
$response = new Response();
$response = new RedirectResponse('/the/login/path');
$httpKernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$httpUtils = $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')->getMock();
@@ -29,7 +30,7 @@ class FormAuthenticationEntryPointTest extends TestCase
->expects($this->once())
->method('createRedirectResponse')
->with($this->equalTo($request), $this->equalTo('/the/login/path'))
->will($this->returnValue($response))
->willReturn($response)
;
$entryPoint = new FormAuthenticationEntryPoint($httpKernel, $httpUtils, '/the/login/path', false);
@@ -48,7 +49,7 @@ class FormAuthenticationEntryPointTest extends TestCase
->expects($this->once())
->method('createRequest')
->with($this->equalTo($request), $this->equalTo('/the/login/path'))
->will($this->returnValue($subRequest))
->willReturn($subRequest)
;
$httpKernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
@@ -56,7 +57,7 @@ class FormAuthenticationEntryPointTest extends TestCase
->expects($this->once())
->method('handle')
->with($this->equalTo($subRequest), $this->equalTo(HttpKernelInterface::SUB_REQUEST))
->will($this->returnValue($response))
->willReturn($response)
;
$entryPoint = new FormAuthenticationEntryPoint($httpKernel, $httpUtils, '/the/login/path', true);
@@ -64,6 +65,6 @@ class FormAuthenticationEntryPointTest extends TestCase
$entryPointResponse = $entryPoint->start($request);
$this->assertEquals($response, $entryPointResponse);
$this->assertEquals(401, $entryPointResponse->headers->get('X-Status-Code'));
$this->assertEquals(401, $entryPointResponse->getStatusCode());
}
}
@@ -12,8 +12,8 @@
namespace Symfony\Component\Security\Http\Tests\EntryPoint;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\EntryPoint\RetryAuthenticationEntryPoint;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\EntryPoint\RetryAuthenticationEntryPoint;
class RetryAuthenticationEntryPointTest extends TestCase
{
@@ -32,34 +32,34 @@ class RetryAuthenticationEntryPointTest extends TestCase
public function dataForStart()
{
if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
return array(array());
return [[]];
}
return array(
array(
return [
[
80,
443,
Request::create('http://localhost/foo/bar?baz=bat'),
'https://localhost/foo/bar?baz=bat',
),
array(
],
[
80,
443,
Request::create('https://localhost/foo/bar?baz=bat'),
'http://localhost/foo/bar?baz=bat',
),
array(
],
[
80,
123,
Request::create('http://localhost/foo/bar?baz=bat'),
'https://localhost:123/foo/bar?baz=bat',
),
array(
],
[
8080,
443,
Request::create('https://localhost/foo/bar?baz=bat'),
'http://localhost:8080/foo/bar?baz=bat',
),
);
],
];
}
}
@@ -21,9 +21,9 @@ class AbstractPreAuthenticatedListenerTest extends TestCase
{
public function testHandleWithValidValues()
{
$userCredentials = array('TheUser', 'TheCredentials');
$userCredentials = ['TheUser', 'TheCredentials'];
$request = new Request(array(), array(), array(), array(), array(), array());
$request = new Request([], [], [], [], [], []);
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
@@ -31,7 +31,7 @@ class AbstractPreAuthenticatedListenerTest extends TestCase
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
->willReturn(null)
;
$tokenStorage
->expects($this->once())
@@ -44,24 +44,24 @@ class AbstractPreAuthenticatedListenerTest extends TestCase
->expects($this->once())
->method('authenticate')
->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken'))
->will($this->returnValue($token))
->willReturn($token)
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', [
$tokenStorage,
$authenticationManager,
'TheProviderKey',
));
]);
$listener
->expects($this->once())
->method('getPreAuthenticatedData')
->will($this->returnValue($userCredentials));
->willReturn($userCredentials);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$listener->handle($event);
@@ -69,15 +69,15 @@ class AbstractPreAuthenticatedListenerTest extends TestCase
public function testHandleWhenAuthenticationFails()
{
$userCredentials = array('TheUser', 'TheCredentials');
$userCredentials = ['TheUser', 'TheCredentials'];
$request = new Request(array(), array(), array(), array(), array(), array());
$request = new Request([], [], [], [], [], []);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
->willReturn(null)
;
$tokenStorage
->expects($this->never())
@@ -90,24 +90,24 @@ class AbstractPreAuthenticatedListenerTest extends TestCase
->expects($this->once())
->method('authenticate')
->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken'))
->will($this->throwException($exception))
->willThrowException($exception)
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', [
$tokenStorage,
$authenticationManager,
'TheProviderKey',
));
]);
$listener
->expects($this->once())
->method('getPreAuthenticatedData')
->will($this->returnValue($userCredentials));
->willReturn($userCredentials);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$listener->handle($event);
@@ -115,17 +115,17 @@ class AbstractPreAuthenticatedListenerTest extends TestCase
public function testHandleWhenAuthenticationFailsWithDifferentToken()
{
$userCredentials = array('TheUser', 'TheCredentials');
$userCredentials = ['TheUser', 'TheCredentials'];
$token = new UsernamePasswordToken('TheUsername', 'ThePassword', 'TheProviderKey', array('ROLE_FOO'));
$token = new UsernamePasswordToken('TheUsername', 'ThePassword', 'TheProviderKey', ['ROLE_FOO']);
$request = new Request(array(), array(), array(), array(), array(), array());
$request = new Request([], [], [], [], [], []);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
->willReturn($token)
;
$tokenStorage
->expects($this->never())
@@ -138,24 +138,24 @@ class AbstractPreAuthenticatedListenerTest extends TestCase
->expects($this->once())
->method('authenticate')
->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken'))
->will($this->throwException($exception))
->willThrowException($exception)
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', [
$tokenStorage,
$authenticationManager,
'TheProviderKey',
));
]);
$listener
->expects($this->once())
->method('getPreAuthenticatedData')
->will($this->returnValue($userCredentials));
->willReturn($userCredentials);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$listener->handle($event);
@@ -163,17 +163,17 @@ class AbstractPreAuthenticatedListenerTest extends TestCase
public function testHandleWithASimilarAuthenticatedToken()
{
$userCredentials = array('TheUser', 'TheCredentials');
$userCredentials = ['TheUser', 'TheCredentials'];
$request = new Request(array(), array(), array(), array(), array(), array());
$request = new Request([], [], [], [], [], []);
$token = new PreAuthenticatedToken('TheUser', 'TheCredentials', 'TheProviderKey', array('ROLE_FOO'));
$token = new PreAuthenticatedToken('TheUser', 'TheCredentials', 'TheProviderKey', ['ROLE_FOO']);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
->willReturn($token)
;
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
@@ -182,21 +182,21 @@ class AbstractPreAuthenticatedListenerTest extends TestCase
->method('authenticate')
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', [
$tokenStorage,
$authenticationManager,
'TheProviderKey',
));
]);
$listener
->expects($this->once())
->method('getPreAuthenticatedData')
->will($this->returnValue($userCredentials));
->willReturn($userCredentials);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$listener->handle($event);
@@ -204,17 +204,17 @@ class AbstractPreAuthenticatedListenerTest extends TestCase
public function testHandleWithAnInvalidSimilarToken()
{
$userCredentials = array('TheUser', 'TheCredentials');
$userCredentials = ['TheUser', 'TheCredentials'];
$request = new Request(array(), array(), array(), array(), array(), array());
$request = new Request([], [], [], [], [], []);
$token = new PreAuthenticatedToken('AnotherUser', 'TheCredentials', 'TheProviderKey', array('ROLE_FOO'));
$token = new PreAuthenticatedToken('AnotherUser', 'TheCredentials', 'TheProviderKey', ['ROLE_FOO']);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
->willReturn($token)
;
$tokenStorage
->expects($this->once())
@@ -228,24 +228,24 @@ class AbstractPreAuthenticatedListenerTest extends TestCase
->expects($this->once())
->method('authenticate')
->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken'))
->will($this->throwException($exception))
->willThrowException($exception)
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', [
$tokenStorage,
$authenticationManager,
'TheProviderKey',
));
]);
$listener
->expects($this->once())
->method('getPreAuthenticatedData')
->will($this->returnValue($userCredentials));
->willReturn($userCredentials);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$listener->handle($event);
@@ -16,11 +16,9 @@ use Symfony\Component\Security\Http\Firewall\AccessListener;
class AccessListenerTest extends TestCase
{
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AccessDeniedException
*/
public function testHandleWhenTheAccessDecisionManagerDecidesToRefuseAccess()
{
$this->expectException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->disableOriginalClone()->getMock();
$accessMap = $this->getMockBuilder('Symfony\Component\Security\Http\AccessMapInterface')->getMock();
@@ -28,29 +26,29 @@ class AccessListenerTest extends TestCase
->expects($this->any())
->method('getPatterns')
->with($this->equalTo($request))
->will($this->returnValue(array(array('foo' => 'bar'), null)))
->willReturn([['foo' => 'bar'], null])
;
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token
->expects($this->any())
->method('isAuthenticated')
->will($this->returnValue(true))
->willReturn(true)
;
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
->willReturn($token)
;
$accessDecisionManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface')->getMock();
$accessDecisionManager
->expects($this->once())
->method('decide')
->with($this->equalTo($token), $this->equalTo(array('foo' => 'bar')), $this->equalTo($request))
->will($this->returnValue(false))
->with($this->equalTo($token), $this->equalTo(['foo' => 'bar']), $this->equalTo($request))
->willReturn(false)
;
$listener = new AccessListener(
@@ -64,7 +62,7 @@ class AccessListenerTest extends TestCase
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$listener->handle($event);
@@ -79,21 +77,21 @@ class AccessListenerTest extends TestCase
->expects($this->any())
->method('getPatterns')
->with($this->equalTo($request))
->will($this->returnValue(array(array('foo' => 'bar'), null)))
->willReturn([['foo' => 'bar'], null])
;
$notAuthenticatedToken = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$notAuthenticatedToken
->expects($this->any())
->method('isAuthenticated')
->will($this->returnValue(false))
->willReturn(false)
;
$authenticatedToken = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$authenticatedToken
->expects($this->any())
->method('isAuthenticated')
->will($this->returnValue(true))
->willReturn(true)
;
$authManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
@@ -101,14 +99,14 @@ class AccessListenerTest extends TestCase
->expects($this->once())
->method('authenticate')
->with($this->equalTo($notAuthenticatedToken))
->will($this->returnValue($authenticatedToken))
->willReturn($authenticatedToken)
;
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($notAuthenticatedToken))
->willReturn($notAuthenticatedToken)
;
$tokenStorage
->expects($this->once())
@@ -120,8 +118,8 @@ class AccessListenerTest extends TestCase
$accessDecisionManager
->expects($this->once())
->method('decide')
->with($this->equalTo($authenticatedToken), $this->equalTo(array('foo' => 'bar')), $this->equalTo($request))
->will($this->returnValue(true))
->with($this->equalTo($authenticatedToken), $this->equalTo(['foo' => 'bar']), $this->equalTo($request))
->willReturn(true)
;
$listener = new AccessListener(
@@ -135,7 +133,7 @@ class AccessListenerTest extends TestCase
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$listener->handle($event);
@@ -150,7 +148,7 @@ class AccessListenerTest extends TestCase
->expects($this->any())
->method('getPatterns')
->with($this->equalTo($request))
->will($this->returnValue(array(null, null)))
->willReturn([null, null])
;
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
@@ -163,7 +161,7 @@ class AccessListenerTest extends TestCase
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
->willReturn($token)
;
$listener = new AccessListener(
@@ -177,22 +175,20 @@ class AccessListenerTest extends TestCase
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$listener->handle($event);
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
*/
public function testHandleWhenTheSecurityTokenStorageHasNoToken()
{
$this->expectException('Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException');
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
->willReturn(null)
;
$listener = new AccessListener(
@@ -23,7 +23,7 @@ class AnonymousAuthenticationListenerTest extends TestCase
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock()))
->willReturn($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock())
;
$tokenStorage
->expects($this->never())
@@ -46,10 +46,10 @@ class AnonymousAuthenticationListenerTest extends TestCase
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
->willReturn(null)
;
$anonymousToken = new AnonymousToken('TheSecret', 'anon.', array());
$anonymousToken = new AnonymousToken('TheSecret', 'anon.', []);
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$authenticationManager
@@ -58,7 +58,7 @@ class AnonymousAuthenticationListenerTest extends TestCase
->with($this->callback(function ($token) {
return 'TheSecret' === $token->getSecret();
}))
->will($this->returnValue($anonymousToken))
->willReturn($anonymousToken)
;
$tokenStorage
@@ -13,20 +13,20 @@ namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Firewall\BasicAuthenticationListener;
use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager;
class BasicAuthenticationListenerTest extends TestCase
{
public function testHandleWithValidUsernameAndPasswordServerParameters()
{
$request = new Request(array(), array(), array(), array(), array(), array(
$request = new Request([], [], [], [], [], [
'PHP_AUTH_USER' => 'TheUsername',
'PHP_AUTH_PW' => 'ThePassword',
));
]);
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
@@ -34,7 +34,7 @@ class BasicAuthenticationListenerTest extends TestCase
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
->willReturn(null)
;
$tokenStorage
->expects($this->once())
@@ -47,7 +47,7 @@ class BasicAuthenticationListenerTest extends TestCase
->expects($this->once())
->method('authenticate')
->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken'))
->will($this->returnValue($token))
->willReturn($token)
;
$listener = new BasicAuthenticationListener(
@@ -61,7 +61,7 @@ class BasicAuthenticationListenerTest extends TestCase
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$listener->handle($event);
@@ -69,18 +69,16 @@ class BasicAuthenticationListenerTest extends TestCase
public function testHandleWhenAuthenticationFails()
{
$request = new Request(array(), array(), array(), array(), array(), array(
$request = new Request([], [], [], [], [], [
'PHP_AUTH_USER' => 'TheUsername',
'PHP_AUTH_PW' => 'ThePassword',
));
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
]);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
->willReturn(null)
;
$tokenStorage
->expects($this->never())
@@ -94,12 +92,12 @@ class BasicAuthenticationListenerTest extends TestCase
->expects($this->any())
->method('start')
->with($this->equalTo($request), $this->isInstanceOf('Symfony\Component\Security\Core\Exception\AuthenticationException'))
->will($this->returnValue($response))
->willReturn($response)
;
$listener = new BasicAuthenticationListener(
$tokenStorage,
new AuthenticationProviderManager(array($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface')->getMock())),
new AuthenticationProviderManager([$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface')->getMock()]),
'TheProviderKey',
$authenticationEntryPoint
);
@@ -108,7 +106,7 @@ class BasicAuthenticationListenerTest extends TestCase
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$event
->expects($this->once())
@@ -140,7 +138,7 @@ class BasicAuthenticationListenerTest extends TestCase
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$listener->handle($event);
@@ -148,15 +146,15 @@ class BasicAuthenticationListenerTest extends TestCase
public function testHandleWithASimilarAuthenticatedToken()
{
$request = new Request(array(), array(), array(), array(), array(), array('PHP_AUTH_USER' => 'TheUsername'));
$request = new Request([], [], [], [], [], ['PHP_AUTH_USER' => 'TheUsername']);
$token = new UsernamePasswordToken('TheUsername', 'ThePassword', 'TheProviderKey', array('ROLE_FOO'));
$token = new UsernamePasswordToken('TheUsername', 'ThePassword', 'TheProviderKey', ['ROLE_FOO']);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
->willReturn($token)
;
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
@@ -176,18 +174,16 @@ class BasicAuthenticationListenerTest extends TestCase
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$listener->handle($event);
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage $providerKey must not be empty
*/
public function testItRequiresProviderKey()
{
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage('$providerKey must not be empty');
new BasicAuthenticationListener(
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(),
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock(),
@@ -198,18 +194,18 @@ class BasicAuthenticationListenerTest extends TestCase
public function testHandleWithADifferentAuthenticatedToken()
{
$request = new Request(array(), array(), array(), array(), array(), array(
$request = new Request([], [], [], [], [], [
'PHP_AUTH_USER' => 'TheUsername',
'PHP_AUTH_PW' => 'ThePassword',
));
]);
$token = new PreAuthenticatedToken('TheUser', 'TheCredentials', 'TheProviderKey', array('ROLE_FOO'));
$token = new PreAuthenticatedToken('TheUser', 'TheCredentials', 'TheProviderKey', ['ROLE_FOO']);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
->willReturn($token)
;
$tokenStorage
->expects($this->never())
@@ -223,12 +219,12 @@ class BasicAuthenticationListenerTest extends TestCase
->expects($this->any())
->method('start')
->with($this->equalTo($request), $this->isInstanceOf('Symfony\Component\Security\Core\Exception\AuthenticationException'))
->will($this->returnValue($response))
->willReturn($response)
;
$listener = new BasicAuthenticationListener(
$tokenStorage,
new AuthenticationProviderManager(array($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface')->getMock())),
new AuthenticationProviderManager([$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface')->getMock()]),
'TheProviderKey',
$authenticationEntryPoint
);
@@ -237,7 +233,7 @@ class BasicAuthenticationListenerTest extends TestCase
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$event
->expects($this->once())
@@ -12,8 +12,8 @@
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\Firewall\ChannelListener;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Firewall\ChannelListener;
class ChannelListenerTest extends TestCase
{
@@ -23,7 +23,7 @@ class ChannelListenerTest extends TestCase
$request
->expects($this->any())
->method('isSecure')
->will($this->returnValue(false))
->willReturn(false)
;
$accessMap = $this->getMockBuilder('Symfony\Component\Security\Http\AccessMapInterface')->getMock();
@@ -31,7 +31,7 @@ class ChannelListenerTest extends TestCase
->expects($this->any())
->method('getPatterns')
->with($this->equalTo($request))
->will($this->returnValue(array(array(), 'http')))
->willReturn([[], 'http'])
;
$entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
@@ -44,7 +44,7 @@ class ChannelListenerTest extends TestCase
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$event
->expects($this->never())
@@ -61,7 +61,7 @@ class ChannelListenerTest extends TestCase
$request
->expects($this->any())
->method('isSecure')
->will($this->returnValue(true))
->willReturn(true)
;
$accessMap = $this->getMockBuilder('Symfony\Component\Security\Http\AccessMapInterface')->getMock();
@@ -69,7 +69,7 @@ class ChannelListenerTest extends TestCase
->expects($this->any())
->method('getPatterns')
->with($this->equalTo($request))
->will($this->returnValue(array(array(), 'https')))
->willReturn([[], 'https'])
;
$entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
@@ -82,7 +82,7 @@ class ChannelListenerTest extends TestCase
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$event
->expects($this->never())
@@ -99,7 +99,7 @@ class ChannelListenerTest extends TestCase
$request
->expects($this->any())
->method('isSecure')
->will($this->returnValue(false))
->willReturn(false)
;
$response = new Response();
@@ -109,7 +109,7 @@ class ChannelListenerTest extends TestCase
->expects($this->any())
->method('getPatterns')
->with($this->equalTo($request))
->will($this->returnValue(array(array(), 'https')))
->willReturn([[], 'https'])
;
$entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
@@ -117,14 +117,14 @@ class ChannelListenerTest extends TestCase
->expects($this->once())
->method('start')
->with($this->equalTo($request))
->will($this->returnValue($response))
->willReturn($response)
;
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$event
->expects($this->once())
@@ -142,7 +142,7 @@ class ChannelListenerTest extends TestCase
$request
->expects($this->any())
->method('isSecure')
->will($this->returnValue(true))
->willReturn(true)
;
$response = new Response();
@@ -152,7 +152,7 @@ class ChannelListenerTest extends TestCase
->expects($this->any())
->method('getPatterns')
->with($this->equalTo($request))
->will($this->returnValue(array(array(), 'http')))
->willReturn([[], 'http'])
;
$entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
@@ -160,14 +160,14 @@ class ChannelListenerTest extends TestCase
->expects($this->once())
->method('start')
->with($this->equalTo($request))
->will($this->returnValue($response))
->willReturn($response)
;
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$event
->expects($this->once())
@@ -12,6 +12,7 @@
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
@@ -30,34 +31,26 @@ use Symfony\Component\Security\Core\User\User;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\Firewall\ContextListener;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
class ContextListenerTest extends TestCase
{
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage $contextKey must not be empty
*/
public function testItRequiresContextKey()
{
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage('$contextKey must not be empty');
new ContextListener(
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(),
array(),
[],
''
);
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage User provider "stdClass" must implement "Symfony\Component\Security\Core\User\UserProviderInterface
*/
public function testUserProvidersNeedToImplementAnInterface()
{
new ContextListener(
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(),
array(new \stdClass()),
'key123'
);
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage('User provider "stdClass" must implement "Symfony\Component\Security\Core\User\UserProviderInterface');
$this->handleEventWithPreviousSession(new TokenStorage(), [new \stdClass()]);
}
public function testOnKernelResponseWillAddSession()
@@ -116,7 +109,7 @@ class ContextListenerTest extends TestCase
new Response()
);
$listener = new ContextListener($tokenStorage, array(), 'session', null, new EventDispatcher());
$listener = new ContextListener($tokenStorage, [], 'session', null, new EventDispatcher());
$listener->onKernelResponse($event);
$this->assertTrue($session->isStarted());
@@ -135,7 +128,7 @@ class ContextListenerTest extends TestCase
new Response()
);
$listener = new ContextListener(new TokenStorage(), array(), 'session', null, new EventDispatcher());
$listener = new ContextListener(new TokenStorage(), [], 'session', null, new EventDispatcher());
$listener->onKernelResponse($event);
$this->assertFalse($session->isStarted());
@@ -155,32 +148,34 @@ class ContextListenerTest extends TestCase
$event->expects($this->any())
->method('getRequest')
->will($this->returnValue($request));
->willReturn($request);
$request->expects($this->any())
->method('hasPreviousSession')
->will($this->returnValue(true));
->willReturn(true);
$request->expects($this->any())
->method('getSession')
->will($this->returnValue($session));
->willReturn($session);
$session->expects($this->any())
->method('get')
->with('_security_key123')
->will($this->returnValue($token));
->willReturn($token);
$tokenStorage->expects($this->once())
->method('setToken')
->with(null);
$listener = new ContextListener($tokenStorage, array(), 'key123');
$listener = new ContextListener($tokenStorage, [], 'key123');
$listener->handle($event);
}
public function provideInvalidToken()
{
return array(
array(serialize(new \__PHP_Incomplete_Class())),
array(serialize(null)),
array(null),
);
return [
['foo'],
['O:8:"NotFound":0:{}'],
[serialize(new \__PHP_Incomplete_Class())],
[serialize(null)],
[null],
];
}
public function testHandleAddsKernelResponseListener()
@@ -191,18 +186,18 @@ class ContextListenerTest extends TestCase
->disableOriginalConstructor()
->getMock();
$listener = new ContextListener($tokenStorage, array(), 'key123', null, $dispatcher);
$listener = new ContextListener($tokenStorage, [], 'key123', null, $dispatcher);
$event->expects($this->any())
->method('isMasterRequest')
->will($this->returnValue(true));
->willReturn(true);
$event->expects($this->any())
->method('getRequest')
->will($this->returnValue($this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock()));
->willReturn($this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock());
$dispatcher->expects($this->once())
->method('addListener')
->with(KernelEvents::RESPONSE, array($listener, 'onKernelResponse'));
->with(KernelEvents::RESPONSE, [$listener, 'onKernelResponse']);
$listener->handle($event);
}
@@ -215,23 +210,23 @@ class ContextListenerTest extends TestCase
->disableOriginalConstructor()
->getMock();
$listener = new ContextListener($tokenStorage, array(), 'key123', null, $dispatcher);
$listener = new ContextListener($tokenStorage, [], 'key123', null, $dispatcher);
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$request->expects($this->any())
->method('hasSession')
->will($this->returnValue(true));
->willReturn(true);
$event->expects($this->any())
->method('isMasterRequest')
->will($this->returnValue(true));
->willReturn(true);
$event->expects($this->any())
->method('getRequest')
->will($this->returnValue($request));
->willReturn($request);
$dispatcher->expects($this->once())
->method('removeListener')
->with(KernelEvents::RESPONSE, array($listener, 'onKernelResponse'));
->with(KernelEvents::RESPONSE, [$listener, 'onKernelResponse']);
$listener->onKernelResponse($event);
}
@@ -239,25 +234,69 @@ class ContextListenerTest extends TestCase
public function testHandleRemovesTokenIfNoPreviousSessionWasFound()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$request->expects($this->any())->method('hasPreviousSession')->will($this->returnValue(false));
$request->expects($this->any())->method('hasPreviousSession')->willReturn(false);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
->disableOriginalConstructor()
->getMock();
$event->expects($this->any())->method('getRequest')->will($this->returnValue($request));
$event->expects($this->any())->method('getRequest')->willReturn($request);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage->expects($this->once())->method('setToken')->with(null);
$listener = new ContextListener($tokenStorage, array(), 'key123');
$listener = new ContextListener($tokenStorage, [], 'key123');
$listener->handle($event);
}
/**
* @group legacy
* @expectedDeprecation Refreshing a deauthenticated user is deprecated as of 3.4 and will trigger a logout in 4.0.
*/
public function testIfTokenIsDeauthenticatedTriggersDeprecations()
{
$tokenStorage = new TokenStorage();
$refreshedUser = new User('foobar', 'baz');
$this->handleEventWithPreviousSession($tokenStorage, [new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)]);
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
}
public function testIfTokenIsDeauthenticated()
{
$tokenStorage = new TokenStorage();
$refreshedUser = new User('foobar', 'baz');
$this->handleEventWithPreviousSession($tokenStorage, [new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)], null, true);
$this->assertNull($tokenStorage->getToken());
}
public function testIfTokenIsNotDeauthenticated()
{
$tokenStorage = new TokenStorage();
$badRefreshedUser = new User('foobar', 'baz');
$goodRefreshedUser = new User('foobar', 'bar');
$this->handleEventWithPreviousSession($tokenStorage, [new SupportingUserProvider($badRefreshedUser), new SupportingUserProvider($goodRefreshedUser)], $goodRefreshedUser, true);
$this->assertSame($goodRefreshedUser, $tokenStorage->getToken()->getUser());
}
public function testRememberMeGetsCanceledIfTokenIsDeauthenticated()
{
$tokenStorage = new TokenStorage();
$refreshedUser = new User('foobar', 'baz');
$rememberMeServices = $this->createMock(RememberMeServicesInterface::class);
$rememberMeServices->expects($this->once())->method('loginFail');
$this->handleEventWithPreviousSession($tokenStorage, [new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)], null, true, $rememberMeServices);
$this->assertNull($tokenStorage->getToken());
}
public function testTryAllUserProvidersUntilASupportingUserProviderIsFound()
{
$tokenStorage = new TokenStorage();
$refreshedUser = new User('foobar', 'baz');
$this->handleEventWithPreviousSession($tokenStorage, array(new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)));
$this->handleEventWithPreviousSession($tokenStorage, [new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)], $refreshedUser);
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
}
@@ -266,7 +305,7 @@ class ContextListenerTest extends TestCase
{
$tokenStorage = new TokenStorage();
$refreshedUser = new User('foobar', 'baz');
$this->handleEventWithPreviousSession($tokenStorage, array(new SupportingUserProvider(), new SupportingUserProvider($refreshedUser)));
$this->handleEventWithPreviousSession($tokenStorage, [new SupportingUserProvider(), new SupportingUserProvider($refreshedUser)], $refreshedUser);
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
}
@@ -274,24 +313,31 @@ class ContextListenerTest extends TestCase
public function testTokenIsSetToNullIfNoUserWasLoadedByTheRegisteredUserProviders()
{
$tokenStorage = new TokenStorage();
$this->handleEventWithPreviousSession($tokenStorage, array(new NotSupportingUserProvider(), new SupportingUserProvider()));
$this->handleEventWithPreviousSession($tokenStorage, [new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider()]);
$this->assertNull($tokenStorage->getToken());
}
/**
* @expectedException \RuntimeException
*/
public function testRuntimeExceptionIsThrownIfNoSupportingUserProviderWasRegistered()
{
$this->handleEventWithPreviousSession(new TokenStorage(), array(new NotSupportingUserProvider(), new NotSupportingUserProvider()));
$this->expectException('RuntimeException');
$this->handleEventWithPreviousSession(new TokenStorage(), [new NotSupportingUserProvider(false), new NotSupportingUserProvider(true)]);
}
public function testAcceptsProvidersAsTraversable()
{
$tokenStorage = new TokenStorage();
$refreshedUser = new User('foobar', 'baz');
$this->handleEventWithPreviousSession($tokenStorage, new \ArrayObject([new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)]), $refreshedUser);
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
}
protected function runSessionOnKernelResponse($newToken, $original = null)
{
$session = new Session(new MockArraySessionStorage());
if ($original !== null) {
if (null !== $original) {
$session->set('_security_session', $original);
}
@@ -309,28 +355,42 @@ class ContextListenerTest extends TestCase
new Response()
);
$listener = new ContextListener($tokenStorage, array(), 'session', null, new EventDispatcher());
$listener = new ContextListener($tokenStorage, [], 'session', null, new EventDispatcher());
$listener->onKernelResponse($event);
return $session;
}
private function handleEventWithPreviousSession(TokenStorageInterface $tokenStorage, array $userProviders)
private function handleEventWithPreviousSession(TokenStorageInterface $tokenStorage, $userProviders, UserInterface $user = null, $logoutOnUserChange = false, RememberMeServicesInterface $rememberMeServices = null)
{
$user = $user ?: new User('foo', 'bar');
$session = new Session(new MockArraySessionStorage());
$session->set('_security_context_key', serialize(new UsernamePasswordToken(new User('foo', 'bar'), '', 'context_key')));
$session->set('_security_context_key', serialize(new UsernamePasswordToken($user, '', 'context_key', ['ROLE_USER'])));
$request = new Request();
$request->setSession($session);
$request->cookies->set('MOCKSESSID', true);
$listener = new ContextListener($tokenStorage, $userProviders, 'context_key');
$listener->setLogoutOnUserChange($logoutOnUserChange);
if ($rememberMeServices) {
$listener->setRememberMeServices($rememberMeServices);
}
$listener->handle(new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST));
}
}
class NotSupportingUserProvider implements UserProviderInterface
{
/** @var bool */
private $throwsUnsupportedException;
public function __construct($throwsUnsupportedException)
{
$this->throwsUnsupportedException = $throwsUnsupportedException;
}
public function loadUserByUsername($username)
{
throw new UsernameNotFoundException();
@@ -338,7 +398,11 @@ class NotSupportingUserProvider implements UserProviderInterface
public function refreshUser(UserInterface $user)
{
throw new UnsupportedUserException();
if ($this->throwsUnsupportedException) {
throw new UnsupportedUserException();
}
return $user;
}
public function supportsClass($class)
@@ -8,6 +8,9 @@ use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\EntryPoint\DigestAuthenticationEntryPoint;
use Symfony\Component\Security\Http\Firewall\DigestAuthenticationListener;
/**
* @group legacy
*/
class DigestAuthenticationListenerTest extends TestCase
{
public function testHandleWithValidDigest()
@@ -31,7 +34,7 @@ class DigestAuthenticationListenerTest extends TestCase
'response="'.$serverDigest.'"'
;
$request = new Request(array(), array(), array(), array(), array(), array('PHP_AUTH_DIGEST' => $digestData));
$request = new Request([], [], [], [], [], ['PHP_AUTH_DIGEST' => $digestData]);
$entryPoint = new DigestAuthenticationEntryPoint($realm, $secret);
@@ -44,7 +47,7 @@ class DigestAuthenticationListenerTest extends TestCase
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
->willReturn(null)
;
$tokenStorage
->expects($this->once())
@@ -61,7 +64,7 @@ class DigestAuthenticationListenerTest extends TestCase
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$listener->handle($event);
@@ -14,6 +14,9 @@ namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\Firewall\DigestData;
/**
* @group legacy
*/
class DigestDataTest extends TestCase
{
public function testGetResponse()
@@ -15,11 +15,13 @@ use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\LogoutException;
use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Symfony\Component\Security\Http\Firewall\ExceptionListener;
@@ -30,7 +32,7 @@ class ExceptionListenerTest extends TestCase
/**
* @dataProvider getAuthenticationExceptionProvider
*/
public function testAuthenticationExceptionWithoutEntryPoint(\Exception $exception, \Exception $eventException = null)
public function testAuthenticationExceptionWithoutEntryPoint(\Exception $exception, \Exception $eventException)
{
$event = $this->createEvent($exception);
@@ -38,46 +40,54 @@ class ExceptionListenerTest extends TestCase
$listener->onKernelException($event);
$this->assertNull($event->getResponse());
$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException());
$this->assertEquals($eventException, $event->getException());
}
/**
* @dataProvider getAuthenticationExceptionProvider
*/
public function testAuthenticationExceptionWithEntryPoint(\Exception $exception, \Exception $eventException = null)
public function testAuthenticationExceptionWithEntryPoint(\Exception $exception)
{
$event = $this->createEvent($exception = new AuthenticationException());
$event = $this->createEvent($exception);
$listener = $this->createExceptionListener(null, null, null, $this->createEntryPoint());
$response = new Response('Forbidden', 403);
$listener = $this->createExceptionListener(null, null, null, $this->createEntryPoint($response));
$listener->onKernelException($event);
$this->assertEquals('OK', $event->getResponse()->getContent());
$this->assertTrue($event->isAllowingCustomResponseCode());
$this->assertEquals('Forbidden', $event->getResponse()->getContent());
$this->assertEquals(403, $event->getResponse()->getStatusCode());
$this->assertSame($exception, $event->getException());
}
public function getAuthenticationExceptionProvider()
{
return array(
array(new AuthenticationException()),
array(new \LogicException('random', 0, $e = new AuthenticationException()), $e),
array(new \LogicException('random', 0, $e = new AuthenticationException('embed', 0, new AuthenticationException())), $e),
array(new \LogicException('random', 0, $e = new AuthenticationException('embed', 0, new AccessDeniedException())), $e),
array(new AuthenticationException('random', 0, new \LogicException())),
);
return [
[$e = new AuthenticationException(), new HttpException(Response::HTTP_UNAUTHORIZED, '', $e, [], 0)],
[new \LogicException('random', 0, $e = new AuthenticationException()), new HttpException(Response::HTTP_UNAUTHORIZED, '', $e, [], 0)],
[new \LogicException('random', 0, $e = new AuthenticationException('embed', 0, new AuthenticationException())), new HttpException(Response::HTTP_UNAUTHORIZED, 'embed', $e, [], 0)],
[new \LogicException('random', 0, $e = new AuthenticationException('embed', 0, new AccessDeniedException())), new HttpException(Response::HTTP_UNAUTHORIZED, 'embed', $e, [], 0)],
[$e = new AuthenticationException('random', 0, new \LogicException()), new HttpException(Response::HTTP_UNAUTHORIZED, 'random', $e, [], 0)],
];
}
/**
* @group legacy
*/
public function testExceptionWhenEntryPointReturnsBadValue()
{
$event = $this->createEvent(new AuthenticationException());
$entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
$entryPoint->expects($this->once())->method('start')->will($this->returnValue('NOT A RESPONSE'));
$entryPoint->expects($this->once())->method('start')->willReturn('NOT A RESPONSE');
$listener = $this->createExceptionListener(null, null, null, $entryPoint);
$listener->onKernelException($event);
// the exception has been replaced by our LogicException
$this->assertInstanceOf('LogicException', $event->getException());
$this->assertStringEndsWith('start() method must return a Response object (string returned)', $event->getException()->getMessage());
$this->assertStringEndsWith('start()" method must return a Response object ("string" returned).', $event->getException()->getMessage());
}
/**
@@ -100,17 +110,20 @@ class ExceptionListenerTest extends TestCase
public function testAccessDeniedExceptionFullFledgedAndWithoutAccessDeniedHandlerAndWithErrorPage(\Exception $exception, \Exception $eventException = null)
{
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$kernel->expects($this->once())->method('handle')->will($this->returnValue(new Response('error')));
$kernel->expects($this->once())->method('handle')->willReturn(new Response('Unauthorized', 401));
$event = $this->createEvent($exception, $kernel);
$httpUtils = $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')->getMock();
$httpUtils->expects($this->once())->method('createRequest')->will($this->returnValue(Request::create('/error')));
$httpUtils->expects($this->once())->method('createRequest')->willReturn(Request::create('/error'));
$listener = $this->createExceptionListener(null, $this->createTrustResolver(true), $httpUtils, null, '/error');
$listener->onKernelException($event);
$this->assertEquals('error', $event->getResponse()->getContent());
$this->assertTrue($event->isAllowingCustomResponseCode());
$this->assertEquals('Unauthorized', $event->getResponse()->getContent());
$this->assertEquals(401, $event->getResponse()->getStatusCode());
$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
}
@@ -122,7 +135,7 @@ class ExceptionListenerTest extends TestCase
$event = $this->createEvent($exception);
$accessDeniedHandler = $this->getMockBuilder('Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface')->getMock();
$accessDeniedHandler->expects($this->once())->method('handle')->will($this->returnValue(new Response('error')));
$accessDeniedHandler->expects($this->once())->method('handle')->willReturn(new Response('error'));
$listener = $this->createExceptionListener(null, $this->createTrustResolver(true), null, null, null, $accessDeniedHandler);
$listener->onKernelException($event);
@@ -139,7 +152,7 @@ class ExceptionListenerTest extends TestCase
$event = $this->createEvent($exception);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage->expects($this->once())->method('getToken')->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock()));
$tokenStorage->expects($this->once())->method('getToken')->willReturn($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock());
$listener = $this->createExceptionListener($tokenStorage, $this->createTrustResolver(false), null, $this->createEntryPoint());
$listener->onKernelException($event);
@@ -148,21 +161,32 @@ class ExceptionListenerTest extends TestCase
$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
}
public function getAccessDeniedExceptionProvider()
public function testLogoutException()
{
return array(
array(new AccessDeniedException()),
array(new \LogicException('random', 0, $e = new AccessDeniedException()), $e),
array(new \LogicException('random', 0, $e = new AccessDeniedException('embed', new AccessDeniedException())), $e),
array(new \LogicException('random', 0, $e = new AccessDeniedException('embed', new AuthenticationException())), $e),
array(new AccessDeniedException('random', new \LogicException())),
);
$event = $this->createEvent(new LogoutException('Invalid CSRF.'));
$listener = $this->createExceptionListener();
$listener->onKernelException($event);
$this->assertEquals('Invalid CSRF.', $event->getException()->getMessage());
$this->assertEquals(403, $event->getException()->getStatusCode());
}
private function createEntryPoint()
public function getAccessDeniedExceptionProvider()
{
return [
[new AccessDeniedException()],
[new \LogicException('random', 0, $e = new AccessDeniedException()), $e],
[new \LogicException('random', 0, $e = new AccessDeniedException('embed', new AccessDeniedException())), $e],
[new \LogicException('random', 0, $e = new AccessDeniedException('embed', new AuthenticationException())), $e],
[new AccessDeniedException('random', new \LogicException())],
];
}
private function createEntryPoint(Response $response = null)
{
$entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
$entryPoint->expects($this->once())->method('start')->will($this->returnValue(new Response('OK')));
$entryPoint->expects($this->once())->method('start')->willReturn($response ?: new Response('OK'));
return $entryPoint;
}
@@ -170,7 +194,7 @@ class ExceptionListenerTest extends TestCase
private function createTrustResolver($fullFledged)
{
$trustResolver = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface')->getMock();
$trustResolver->expects($this->once())->method('isFullFledged')->will($this->returnValue($fullFledged));
$trustResolver->expects($this->once())->method('isFullFledged')->willReturn($fullFledged);
return $trustResolver;
}
@@ -20,7 +20,7 @@ class LogoutListenerTest extends TestCase
{
public function testHandleUnmatchedPath()
{
list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener();
list($listener, , $httpUtils, $options) = $this->getListener();
list($event, $request) = $this->getGetResponseEvent();
@@ -30,7 +30,7 @@ class LogoutListenerTest extends TestCase
$httpUtils->expects($this->once())
->method('checkRequestPath')
->with($request, $options['logout_path'])
->will($this->returnValue(false));
->willReturn(false);
$listener->handle($event);
}
@@ -49,20 +49,20 @@ class LogoutListenerTest extends TestCase
$httpUtils->expects($this->once())
->method('checkRequestPath')
->with($request, $options['logout_path'])
->will($this->returnValue(true));
->willReturn(true);
$tokenManager->expects($this->once())
->method('isTokenValid')
->will($this->returnValue(true));
->willReturn(true);
$successHandler->expects($this->once())
->method('onLogoutSuccess')
->with($request)
->will($this->returnValue($response = new Response()));
->willReturn($response = new Response());
$tokenStorage->expects($this->once())
->method('getToken')
->will($this->returnValue($token = $this->getToken()));
->willReturn($token = $this->getToken());
$handler = $this->getHandler();
$handler->expects($this->once())
@@ -93,16 +93,16 @@ class LogoutListenerTest extends TestCase
$httpUtils->expects($this->once())
->method('checkRequestPath')
->with($request, $options['logout_path'])
->will($this->returnValue(true));
->willReturn(true);
$successHandler->expects($this->once())
->method('onLogoutSuccess')
->with($request)
->will($this->returnValue($response = new Response()));
->willReturn($response = new Response());
$tokenStorage->expects($this->once())
->method('getToken')
->will($this->returnValue($token = $this->getToken()));
->willReturn($token = $this->getToken());
$handler = $this->getHandler();
$handler->expects($this->once())
@@ -123,37 +123,36 @@ class LogoutListenerTest extends TestCase
}
/**
* @expectedException \RuntimeException
* @group legacy
*/
public function testSuccessHandlerReturnsNonResponse()
{
$this->expectException('RuntimeException');
$successHandler = $this->getSuccessHandler();
list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener($successHandler);
list($listener, , $httpUtils, $options) = $this->getListener($successHandler);
list($event, $request) = $this->getGetResponseEvent();
$httpUtils->expects($this->once())
->method('checkRequestPath')
->with($request, $options['logout_path'])
->will($this->returnValue(true));
->willReturn(true);
$successHandler->expects($this->once())
->method('onLogoutSuccess')
->with($request)
->will($this->returnValue(null));
->willReturn(null);
$listener->handle($event);
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\LogoutException
*/
public function testCsrfValidationFails()
{
$this->expectException('Symfony\Component\Security\Core\Exception\LogoutException');
$tokenManager = $this->getTokenManager();
list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener(null, $tokenManager);
list($listener, , $httpUtils, $options) = $this->getListener(null, $tokenManager);
list($event, $request) = $this->getGetResponseEvent();
@@ -162,11 +161,11 @@ class LogoutListenerTest extends TestCase
$httpUtils->expects($this->once())
->method('checkRequestPath')
->with($request, $options['logout_path'])
->will($this->returnValue(true));
->willReturn(true);
$tokenManager->expects($this->once())
->method('isTokenValid')
->will($this->returnValue(false));
->willReturn(false);
$listener->handle($event);
}
@@ -189,9 +188,9 @@ class LogoutListenerTest extends TestCase
$event->expects($this->any())
->method('getRequest')
->will($this->returnValue($request = new Request()));
->willReturn($request = new Request());
return array($event, $request);
return [$event, $request];
}
private function getHandler()
@@ -212,16 +211,16 @@ class LogoutListenerTest extends TestCase
$tokenStorage = $this->getTokenStorage(),
$httpUtils = $this->getHttpUtils(),
$successHandler ?: $this->getSuccessHandler(),
$options = array(
$options = [
'csrf_parameter' => '_csrf_token',
'csrf_token_id' => 'logout',
'logout_path' => '/logout',
'target_url' => '/',
),
],
$tokenManager
);
return array($listener, $tokenStorage, $httpUtils, $options);
return [$listener, $tokenStorage, $httpUtils, $options];
}
private function getSuccessHandler()
@@ -12,9 +12,9 @@
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Firewall\RememberMeListener;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\SecurityEvents;
class RememberMeListenerTest extends TestCase
@@ -26,7 +26,7 @@ class RememberMeListenerTest extends TestCase
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock()))
->willReturn($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock())
;
$tokenStorage
@@ -44,20 +44,20 @@ class RememberMeListenerTest extends TestCase
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
->willReturn(null)
;
$service
->expects($this->once())
->method('autoLogin')
->will($this->returnValue(null))
->willReturn(null)
;
$event = $this->getGetResponseEvent();
$event
->expects($this->once())
->method('getRequest')
->will($this->returnValue(new Request()))
->willReturn(new Request())
;
$this->assertNull($listener->handle($event));
@@ -66,59 +66,59 @@ class RememberMeListenerTest extends TestCase
public function testOnCoreSecurityIgnoresAuthenticationExceptionThrownByAuthenticationManagerImplementation()
{
list($listener, $tokenStorage, $service, $manager) = $this->getListener();
$request = new Request();
$exception = new AuthenticationException('Authentication failed.');
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
->willReturn(null)
;
$service
->expects($this->once())
->method('autoLogin')
->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock()))
->willReturn($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock())
;
$service
->expects($this->once())
->method('loginFail')
->with($request, $exception)
;
$exception = new AuthenticationException('Authentication failed.');
$manager
->expects($this->once())
->method('authenticate')
->will($this->throwException($exception))
->willThrowException($exception)
;
$event = $this->getGetResponseEvent();
$event
->expects($this->once())
->method('getRequest')
->will($this->returnValue(new Request()))
->willReturn($request)
;
$listener->handle($event);
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationException
* @expectedExceptionMessage Authentication failed.
*/
public function testOnCoreSecurityIgnoresAuthenticationOptionallyRethrowsExceptionThrownAuthenticationManagerImplementation()
{
$this->expectException('Symfony\Component\Security\Core\Exception\AuthenticationException');
$this->expectExceptionMessage('Authentication failed.');
list($listener, $tokenStorage, $service, $manager) = $this->getListener(false, false);
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
->willReturn(null)
;
$service
->expects($this->once())
->method('autoLogin')
->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock()))
->willReturn($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock())
;
$service
@@ -130,14 +130,51 @@ class RememberMeListenerTest extends TestCase
$manager
->expects($this->once())
->method('authenticate')
->will($this->throwException($exception))
->willThrowException($exception)
;
$event = $this->getGetResponseEvent();
$event
->expects($this->once())
->method('getRequest')
->will($this->returnValue(new Request()))
->willReturn(new Request())
;
$listener->handle($event);
}
public function testOnCoreSecurityAuthenticationExceptionDuringAutoLoginTriggersLoginFail()
{
list($listener, $tokenStorage, $service, $manager) = $this->getListener();
$tokenStorage
->expects($this->once())
->method('getToken')
->willReturn(null)
;
$exception = new AuthenticationException('Authentication failed.');
$service
->expects($this->once())
->method('autoLogin')
->willThrowException($exception)
;
$service
->expects($this->once())
->method('loginFail')
;
$manager
->expects($this->never())
->method('authenticate')
;
$event = $this->getGetResponseEvent();
$event
->expects($this->once())
->method('getRequest')
->willReturn(new Request())
;
$listener->handle($event);
@@ -150,14 +187,14 @@ class RememberMeListenerTest extends TestCase
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
->willReturn(null)
;
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$service
->expects($this->once())
->method('autoLogin')
->will($this->returnValue($token))
->willReturn($token)
;
$tokenStorage
@@ -169,14 +206,14 @@ class RememberMeListenerTest extends TestCase
$manager
->expects($this->once())
->method('authenticate')
->will($this->returnValue($token))
->willReturn($token)
;
$event = $this->getGetResponseEvent();
$event
->expects($this->once())
->method('getRequest')
->will($this->returnValue(new Request()))
->willReturn(new Request())
;
$listener->handle($event);
@@ -184,19 +221,19 @@ class RememberMeListenerTest extends TestCase
public function testSessionStrategy()
{
list($listener, $tokenStorage, $service, $manager, , $dispatcher, $sessionStrategy) = $this->getListener(false, true, true);
list($listener, $tokenStorage, $service, $manager, , , $sessionStrategy) = $this->getListener(false, true, true);
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
->willReturn(null)
;
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$service
->expects($this->once())
->method('autoLogin')
->will($this->returnValue($token))
->willReturn($token)
;
$tokenStorage
@@ -208,40 +245,40 @@ class RememberMeListenerTest extends TestCase
$manager
->expects($this->once())
->method('authenticate')
->will($this->returnValue($token))
->willReturn($token)
;
$session = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock();
$session
->expects($this->once())
->method('isStarted')
->will($this->returnValue(true))
->willReturn(true)
;
$request = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Request')->getMock();
$request
->expects($this->once())
->method('hasSession')
->will($this->returnValue(true))
->willReturn(true)
;
$request
->expects($this->once())
->method('getSession')
->will($this->returnValue($session))
->willReturn($session)
;
$event = $this->getGetResponseEvent();
$event
->expects($this->once())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$sessionStrategy
->expects($this->once())
->method('onAuthentication')
->will($this->returnValue(null))
->willReturn(null)
;
$listener->handle($event);
@@ -249,19 +286,19 @@ class RememberMeListenerTest extends TestCase
public function testSessionIsMigratedByDefault()
{
list($listener, $tokenStorage, $service, $manager, , $dispatcher, $sessionStrategy) = $this->getListener(false, true, false);
list($listener, $tokenStorage, $service, $manager) = $this->getListener(false, true, false);
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
->willReturn(null)
;
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$service
->expects($this->once())
->method('autoLogin')
->will($this->returnValue($token))
->willReturn($token)
;
$tokenStorage
@@ -273,14 +310,14 @@ class RememberMeListenerTest extends TestCase
$manager
->expects($this->once())
->method('authenticate')
->will($this->returnValue($token))
->willReturn($token)
;
$session = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock();
$session
->expects($this->once())
->method('isStarted')
->will($this->returnValue(true))
->willReturn(true)
;
$session
->expects($this->once())
@@ -291,20 +328,20 @@ class RememberMeListenerTest extends TestCase
$request
->expects($this->any())
->method('hasSession')
->will($this->returnValue(true))
->willReturn(true)
;
$request
->expects($this->any())
->method('getSession')
->will($this->returnValue($session))
->willReturn($session)
;
$event = $this->getGetResponseEvent();
$event
->expects($this->once())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$listener->handle($event);
@@ -317,14 +354,14 @@ class RememberMeListenerTest extends TestCase
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
->willReturn(null)
;
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$service
->expects($this->once())
->method('autoLogin')
->will($this->returnValue($token))
->willReturn($token)
;
$tokenStorage
@@ -336,7 +373,7 @@ class RememberMeListenerTest extends TestCase
$manager
->expects($this->once())
->method('authenticate')
->will($this->returnValue($token))
->willReturn($token)
;
$event = $this->getGetResponseEvent();
@@ -344,7 +381,7 @@ class RememberMeListenerTest extends TestCase
$event
->expects($this->once())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$dispatcher
@@ -381,7 +418,7 @@ class RememberMeListenerTest extends TestCase
$sessionStrategy = ($withSessionStrategy ? $this->getSessionStrategy() : null)
);
return array($listener, $tokenStorage, $service, $manager, $logger, $dispatcher, $sessionStrategy);
return [$listener, $tokenStorage, $service, $manager, $logger, $dispatcher, $sessionStrategy];
}
protected function getLogger()
@@ -19,11 +19,11 @@ class RemoteUserAuthenticationListenerTest extends TestCase
{
public function testGetPreAuthenticatedData()
{
$serverVars = array(
$serverVars = [
'REMOTE_USER' => 'TheUser',
);
];
$request = new Request(array(), array(), array(), array(), array(), $serverVars);
$request = new Request([], [], [], [], [], $serverVars);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
@@ -38,16 +38,14 @@ class RemoteUserAuthenticationListenerTest extends TestCase
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
$result = $method->invokeArgs($listener, array($request));
$this->assertSame($result, array('TheUser', null));
$result = $method->invokeArgs($listener, [$request]);
$this->assertSame($result, ['TheUser', null]);
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
*/
public function testGetPreAuthenticatedDataNoUser()
{
$request = new Request(array(), array(), array(), array(), array(), array());
$this->expectException('Symfony\Component\Security\Core\Exception\BadCredentialsException');
$request = new Request([], [], [], [], [], []);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
@@ -62,16 +60,16 @@ class RemoteUserAuthenticationListenerTest extends TestCase
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
$result = $method->invokeArgs($listener, array($request));
$method->invokeArgs($listener, [$request]);
}
public function testGetPreAuthenticatedDataWithDifferentKeys()
{
$userCredentials = array('TheUser', null);
$userCredentials = ['TheUser', null];
$request = new Request(array(), array(), array(), array(), array(), array(
$request = new Request([], [], [], [], [], [
'TheUserKey' => 'TheUser',
));
]);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
@@ -86,7 +84,7 @@ class RemoteUserAuthenticationListenerTest extends TestCase
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
$result = $method->invokeArgs($listener, array($request));
$result = $method->invokeArgs($listener, [$request]);
$this->assertSame($result, $userCredentials);
}
}
@@ -40,7 +40,7 @@ class SimplePreAuthenticationListenerTest extends TestCase
->expects($this->once())
->method('authenticate')
->with($this->equalTo($this->token))
->will($this->returnValue($this->token))
->willReturn($this->token)
;
$simpleAuthenticator = $this->getMockBuilder('Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface')->getMock();
@@ -48,7 +48,7 @@ class SimplePreAuthenticationListenerTest extends TestCase
->expects($this->once())
->method('createToken')
->with($this->equalTo($this->request), $this->equalTo('secured_area'))
->will($this->returnValue($this->token))
->willReturn($this->token)
;
$loginEvent = new InteractiveLoginEvent($this->request, $this->token);
@@ -72,7 +72,7 @@ class SimplePreAuthenticationListenerTest extends TestCase
->expects($this->once())
->method('authenticate')
->with($this->equalTo($this->token))
->will($this->throwException($exception))
->willThrowException($exception)
;
$this->tokenStorage->expects($this->once())
@@ -85,7 +85,7 @@ class SimplePreAuthenticationListenerTest extends TestCase
->expects($this->once())
->method('createToken')
->with($this->equalTo($this->request), $this->equalTo('secured_area'))
->will($this->returnValue($this->token))
->willReturn($this->token)
;
$listener = new SimplePreAuthenticationListener($this->tokenStorage, $this->authenticationManager, 'secured_area', $simpleAuthenticator, $this->logger, $this->dispatcher);
@@ -102,13 +102,13 @@ class SimplePreAuthenticationListenerTest extends TestCase
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$this->request = new Request(array(), array(), array(), array(), array(), array());
$this->request = new Request([], [], [], [], [], []);
$this->event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$this->event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($this->request))
->willReturn($this->request)
;
$this->logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
@@ -47,12 +47,10 @@ class SwitchUserListenerTest extends TestCase
$this->event = new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $this->request, HttpKernelInterface::MASTER_REQUEST);
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage $providerKey must not be empty
*/
public function testProviderKeyIsRequired()
{
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage('$providerKey must not be empty');
new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, '', $this->accessDecisionManager);
}
@@ -65,26 +63,22 @@ class SwitchUserListenerTest extends TestCase
$this->assertNull($this->tokenStorage->getToken());
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
*/
public function testExitUserThrowsAuthenticationExceptionIfNoCurrentToken()
{
$this->expectException('Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException');
$this->tokenStorage->setToken(null);
$this->request->query->set('_switch_user', '_exit');
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
*/
public function testExitUserThrowsAuthenticationExceptionIfOriginalTokenCannotBeFound()
{
$token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO'));
$this->expectException('Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException');
$token = new UsernamePasswordToken('username', '', 'key', ['ROLE_FOO']);
$this->tokenStorage->setToken($token);
$this->request->query->set('_switch_user', '_exit');
$this->request->query->set('_switch_user', SwitchUserListener::EXIT_VALUE);
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
@@ -92,15 +86,15 @@ class SwitchUserListenerTest extends TestCase
public function testExitUserUpdatesToken()
{
$originalToken = new UsernamePasswordToken('username', '', 'key', array());
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', array(new SwitchUserRole('ROLE_PREVIOUS', $originalToken))));
$originalToken = new UsernamePasswordToken('username', '', 'key', []);
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', [new SwitchUserRole('ROLE_PREVIOUS', $originalToken)]));
$this->request->query->set('_switch_user', '_exit');
$this->request->query->set('_switch_user', SwitchUserListener::EXIT_VALUE);
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
$this->assertSame(array(), $this->request->query->all());
$this->assertSame([], $this->request->query->all());
$this->assertSame('', $this->request->server->get('QUERY_STRING'));
$this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $this->event->getResponse());
$this->assertSame($this->request->getUri(), $this->event->getResponse()->getTargetUrl());
@@ -118,8 +112,8 @@ class SwitchUserListenerTest extends TestCase
->with($originalUser)
->willReturn($refreshedUser);
$originalToken = new UsernamePasswordToken($originalUser, '', 'key');
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', array(new SwitchUserRole('ROLE_PREVIOUS', $originalToken))));
$this->request->query->set('_switch_user', '_exit');
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', [new SwitchUserRole('ROLE_PREVIOUS', $originalToken)]));
$this->request->query->set('_switch_user', SwitchUserListener::EXIT_VALUE);
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher
@@ -142,8 +136,8 @@ class SwitchUserListenerTest extends TestCase
->expects($this->never())
->method('refreshUser');
$originalToken = new UsernamePasswordToken($originalUser, '', 'key');
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', array(new SwitchUserRole('ROLE_PREVIOUS', $originalToken))));
$this->request->query->set('_switch_user', '_exit');
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', [new SwitchUserRole('ROLE_PREVIOUS', $originalToken)]));
$this->request->query->set('_switch_user', SwitchUserListener::EXIT_VALUE);
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher
@@ -155,19 +149,17 @@ class SwitchUserListenerTest extends TestCase
$listener->handle($this->event);
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AccessDeniedException
*/
public function testSwitchUserIsDisallowed()
{
$token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO'));
$this->expectException('Symfony\Component\Security\Core\Exception\AccessDeniedException');
$token = new UsernamePasswordToken('username', '', 'key', ['ROLE_FOO']);
$this->tokenStorage->setToken($token);
$this->request->query->set('_switch_user', 'kuba');
$this->accessDecisionManager->expects($this->once())
->method('decide')->with($token, array('ROLE_ALLOWED_TO_SWITCH'))
->will($this->returnValue(false));
->method('decide')->with($token, ['ROLE_ALLOWED_TO_SWITCH'])
->willReturn(false);
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
@@ -175,49 +167,105 @@ class SwitchUserListenerTest extends TestCase
public function testSwitchUser()
{
$token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO'));
$user = new User('username', 'password', array());
$token = new UsernamePasswordToken('username', '', 'key', ['ROLE_FOO']);
$user = new User('username', 'password', []);
$this->tokenStorage->setToken($token);
$this->request->query->set('_switch_user', 'kuba');
$this->accessDecisionManager->expects($this->once())
->method('decide')->with($token, array('ROLE_ALLOWED_TO_SWITCH'))
->will($this->returnValue(true));
->method('decide')->with($token, ['ROLE_ALLOWED_TO_SWITCH'])
->willReturn(true);
$this->userProvider->expects($this->once())
->method('loadUserByUsername')->with('kuba')
->will($this->returnValue($user));
->willReturn($user);
$this->userChecker->expects($this->once())
->method('checkPostAuth')->with($user);
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
$this->assertSame(array(), $this->request->query->all());
$this->assertSame([], $this->request->query->all());
$this->assertSame('', $this->request->server->get('QUERY_STRING'));
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $this->tokenStorage->getToken());
}
public function testSwitchUserAlreadySwitched()
{
$originalToken = new UsernamePasswordToken('original', null, 'key', ['ROLE_FOO']);
$alreadySwitchedToken = new UsernamePasswordToken('switched_1', null, 'key', [new SwitchUserRole('ROLE_PREVIOUS_ADMIN', $originalToken)]);
$tokenStorage = new TokenStorage();
$tokenStorage->setToken($alreadySwitchedToken);
$targetUser = new User('kuba', 'password', ['ROLE_FOO', 'ROLE_BAR']);
$this->request->query->set('_switch_user', 'kuba');
$this->accessDecisionManager->expects($this->once())
->method('decide')->with($originalToken, ['ROLE_ALLOWED_TO_SWITCH'])
->willReturn(true);
$this->userProvider->expects($this->once())
->method('loadUserByUsername')
->with('kuba')
->willReturn($targetUser);
$this->userChecker->expects($this->once())
->method('checkPostAuth')->with($targetUser);
$listener = new SwitchUserListener($tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', null, false);
$listener->handle($this->event);
$this->assertSame([], $this->request->query->all());
$this->assertSame('', $this->request->server->get('QUERY_STRING'));
$this->assertSame('kuba', $tokenStorage->getToken()->getUsername());
$this->assertSame($originalToken, $tokenStorage->getToken()->getRoles()[2]->getSource());
}
public function testSwitchUserWorksWithFalsyUsernames()
{
$token = new UsernamePasswordToken('username', '', 'key', ['ROLE_FOO']);
$user = new User('username', 'password', []);
$this->tokenStorage->setToken($token);
$this->request->query->set('_switch_user', '0');
$this->accessDecisionManager->expects($this->once())
->method('decide')->with($token, ['ROLE_ALLOWED_TO_SWITCH'])
->willReturn(true);
$this->userProvider->expects($this->once())
->method('loadUserByUsername')->with('0')
->willReturn($user);
$this->userChecker->expects($this->once())
->method('checkPostAuth')->with($user);
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
$this->assertSame([], $this->request->query->all());
$this->assertSame('', $this->request->server->get('QUERY_STRING'));
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $this->tokenStorage->getToken());
}
public function testSwitchUserKeepsOtherQueryStringParameters()
{
$token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO'));
$user = new User('username', 'password', array());
$token = new UsernamePasswordToken('username', '', 'key', ['ROLE_FOO']);
$user = new User('username', 'password', []);
$this->tokenStorage->setToken($token);
$this->request->query->replace(array(
$this->request->query->replace([
'_switch_user' => 'kuba',
'page' => 3,
'section' => 2,
));
]);
$this->accessDecisionManager->expects($this->once())
->method('decide')->with($token, array('ROLE_ALLOWED_TO_SWITCH'))
->will($this->returnValue(true));
->method('decide')->with($token, ['ROLE_ALLOWED_TO_SWITCH'])
->willReturn(true);
$this->userProvider->expects($this->once())
->method('loadUserByUsername')->with('kuba')
->will($this->returnValue($user));
->willReturn($user);
$this->userChecker->expects($this->once())
->method('checkPostAuth')->with($user);
@@ -227,4 +275,77 @@ class SwitchUserListenerTest extends TestCase
$this->assertSame('page=3&section=2', $this->request->server->get('QUERY_STRING'));
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $this->tokenStorage->getToken());
}
public function testSwitchUserWithReplacedToken()
{
$user = new User('username', 'password', []);
$token = new UsernamePasswordToken($user, '', 'provider123', ['ROLE_FOO']);
$user = new User('replaced', 'password', []);
$replacedToken = new UsernamePasswordToken($user, '', 'provider123', ['ROLE_BAR']);
$this->tokenStorage->setToken($token);
$this->request->query->set('_switch_user', 'kuba');
$this->accessDecisionManager->expects($this->any())
->method('decide')->with($token, ['ROLE_ALLOWED_TO_SWITCH'])
->willReturn(true);
$this->userProvider->expects($this->any())
->method('loadUserByUsername')->with('kuba')
->willReturn($user);
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher
->expects($this->once())
->method('dispatch')
->with(SecurityEvents::SWITCH_USER,
$this->callback(function (SwitchUserEvent $event) use ($replacedToken, $user) {
if ($user !== $event->getTargetUser()) {
return false;
}
$event->setToken($replacedToken);
return true;
}));
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', $dispatcher);
$listener->handle($this->event);
$this->assertSame($replacedToken, $this->tokenStorage->getToken());
}
public function testSwitchUserThrowsAuthenticationExceptionIfNoCurrentToken()
{
$this->expectException('Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException');
$this->tokenStorage->setToken(null);
$this->request->query->set('_switch_user', 'username');
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
}
public function testSwitchUserStateless()
{
$token = new UsernamePasswordToken('username', '', 'key', ['ROLE_FOO']);
$user = new User('username', 'password', []);
$this->tokenStorage->setToken($token);
$this->request->query->set('_switch_user', 'kuba');
$this->accessDecisionManager->expects($this->once())
->method('decide')->with($token, ['ROLE_ALLOWED_TO_SWITCH'])
->willReturn(true);
$this->userProvider->expects($this->once())
->method('loadUserByUsername')->with('kuba')
->willReturn($user);
$this->userChecker->expects($this->once())
->method('checkPostAuth')->with($user);
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', null, true);
$listener->handle($this->event);
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $this->tokenStorage->getToken());
$this->assertFalse($this->event->hasResponse());
}
}
@@ -9,13 +9,21 @@
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Tests\Http\Firewall;
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler;
use Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy;
class UsernamePasswordFormAuthenticationListenerTest extends TestCase
{
@@ -24,28 +32,32 @@ class UsernamePasswordFormAuthenticationListenerTest extends TestCase
*/
public function testHandleWhenUsernameLength($username, $ok)
{
$request = Request::create('/login_check', 'POST', array('_username' => $username));
$request = Request::create('/login_check', 'POST', ['_username' => $username]);
$request->setSession($this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock());
$httpUtils = $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')->getMock();
$httpUtils
->expects($this->any())
->method('checkRequestPath')
->will($this->returnValue(true))
->willReturn(true)
;
$httpUtils
->method('createRedirectResponse')
->willReturn(new RedirectResponse('/hello'))
;
$failureHandler = $this->getMockBuilder('Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface')->getMock();
$failureHandler
->expects($ok ? $this->never() : $this->once())
->method('onAuthenticationFailure')
->will($this->returnValue(new Response()))
->willReturn(new Response())
;
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager')->disableOriginalConstructor()->getMock();
$authenticationManager
->expects($ok ? $this->once() : $this->never())
->method('authenticate')
->will($this->returnValue(new Response()))
->willReturnArgument(0)
;
$listener = new UsernamePasswordFormAuthenticationListener(
@@ -54,26 +66,138 @@ class UsernamePasswordFormAuthenticationListenerTest extends TestCase
$this->getMockBuilder('Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface')->getMock(),
$httpUtils,
'TheProviderKey',
$this->getMockBuilder('Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface')->getMock(),
new DefaultAuthenticationSuccessHandler($httpUtils),
$failureHandler,
array('require_previous_session' => false)
['require_previous_session' => false]
);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
->willReturn($request)
;
$listener->handle($event);
}
/**
* @dataProvider postOnlyDataProvider
*/
public function testHandleNonStringUsernameWithArray($postOnly)
{
$this->expectException('Symfony\Component\HttpKernel\Exception\BadRequestHttpException');
$this->expectExceptionMessage('The key "_username" must be a string, "array" given.');
$request = Request::create('/login_check', 'POST', ['_username' => []]);
$request->setSession($this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock());
$listener = new UsernamePasswordFormAuthenticationListener(
new TokenStorage(),
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock(),
new SessionAuthenticationStrategy(SessionAuthenticationStrategy::NONE),
$httpUtils = new HttpUtils(),
'foo',
new DefaultAuthenticationSuccessHandler($httpUtils),
new DefaultAuthenticationFailureHandler($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $httpUtils),
['require_previous_session' => false, 'post_only' => $postOnly]
);
$event = new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST);
$listener->handle($event);
}
/**
* @dataProvider postOnlyDataProvider
*/
public function testHandleNonStringUsernameWithInt($postOnly)
{
$this->expectException('Symfony\Component\HttpKernel\Exception\BadRequestHttpException');
$this->expectExceptionMessage('The key "_username" must be a string, "integer" given.');
$request = Request::create('/login_check', 'POST', ['_username' => 42]);
$request->setSession($this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock());
$listener = new UsernamePasswordFormAuthenticationListener(
new TokenStorage(),
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock(),
new SessionAuthenticationStrategy(SessionAuthenticationStrategy::NONE),
$httpUtils = new HttpUtils(),
'foo',
new DefaultAuthenticationSuccessHandler($httpUtils),
new DefaultAuthenticationFailureHandler($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $httpUtils),
['require_previous_session' => false, 'post_only' => $postOnly]
);
$event = new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST);
$listener->handle($event);
}
/**
* @dataProvider postOnlyDataProvider
*/
public function testHandleNonStringUsernameWithObject($postOnly)
{
$this->expectException('Symfony\Component\HttpKernel\Exception\BadRequestHttpException');
$this->expectExceptionMessage('The key "_username" must be a string, "object" given.');
$request = Request::create('/login_check', 'POST', ['_username' => new \stdClass()]);
$request->setSession($this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock());
$listener = new UsernamePasswordFormAuthenticationListener(
new TokenStorage(),
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock(),
new SessionAuthenticationStrategy(SessionAuthenticationStrategy::NONE),
$httpUtils = new HttpUtils(),
'foo',
new DefaultAuthenticationSuccessHandler($httpUtils),
new DefaultAuthenticationFailureHandler($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $httpUtils),
['require_previous_session' => false, 'post_only' => $postOnly]
);
$event = new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST);
$listener->handle($event);
}
/**
* @dataProvider postOnlyDataProvider
*/
public function testHandleNonStringUsernameWith__toString($postOnly)
{
$usernameClass = $this->getMockBuilder(DummyUserClass::class)->getMock();
$usernameClass
->expects($this->atLeastOnce())
->method('__toString')
->willReturn('someUsername');
$request = Request::create('/login_check', 'POST', ['_username' => $usernameClass]);
$request->setSession($this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock());
$listener = new UsernamePasswordFormAuthenticationListener(
new TokenStorage(),
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock(),
new SessionAuthenticationStrategy(SessionAuthenticationStrategy::NONE),
$httpUtils = new HttpUtils(),
'foo',
new DefaultAuthenticationSuccessHandler($httpUtils),
new DefaultAuthenticationFailureHandler($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $httpUtils),
['require_previous_session' => false, 'post_only' => $postOnly]
);
$event = new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST);
$listener->handle($event);
}
public function postOnlyDataProvider()
{
return [
[true],
[false],
];
}
public function getUsernameForLength()
{
return array(
array(str_repeat('x', Security::MAX_USERNAME_LENGTH + 1), false),
array(str_repeat('x', Security::MAX_USERNAME_LENGTH - 1), true),
);
return [
[str_repeat('x', Security::MAX_USERNAME_LENGTH + 1), false],
[str_repeat('x', Security::MAX_USERNAME_LENGTH - 1), true],
];
}
}
class DummyUserClass
{
public function __toString()
{
return '';
}
}
@@ -22,7 +22,7 @@ class X509AuthenticationListenerTest extends TestCase
*/
public function testGetPreAuthenticatedData($user, $credentials)
{
$serverVars = array();
$serverVars = [];
if ('' !== $user) {
$serverVars['SSL_CLIENT_S_DN_Email'] = $user;
}
@@ -30,7 +30,7 @@ class X509AuthenticationListenerTest extends TestCase
$serverVars['SSL_CLIENT_S_DN'] = $credentials;
}
$request = new Request(array(), array(), array(), array(), array(), $serverVars);
$request = new Request([], [], [], [], [], $serverVars);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
@@ -41,25 +41,24 @@ class X509AuthenticationListenerTest extends TestCase
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
$result = $method->invokeArgs($listener, array($request));
$this->assertSame($result, array($user, $credentials));
$result = $method->invokeArgs($listener, [$request]);
$this->assertSame($result, [$user, $credentials]);
}
public static function dataProviderGetPreAuthenticatedData()
{
return array(
'validValues' => array('TheUser', 'TheCredentials'),
'noCredentials' => array('TheUser', ''),
);
return [
'validValues' => ['TheUser', 'TheCredentials'],
'noCredentials' => ['TheUser', ''],
];
}
/**
* @dataProvider dataProviderGetPreAuthenticatedDataNoUser
*/
public function testGetPreAuthenticatedDataNoUser($emailAddress)
public function testGetPreAuthenticatedDataNoUser($emailAddress, $credentials)
{
$credentials = 'CN=Sample certificate DN/emailAddress='.$emailAddress;
$request = new Request(array(), array(), array(), array(), array(), array('SSL_CLIENT_S_DN' => $credentials));
$request = new Request([], [], [], [], [], ['SSL_CLIENT_S_DN' => $credentials]);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
@@ -70,24 +69,25 @@ class X509AuthenticationListenerTest extends TestCase
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
$result = $method->invokeArgs($listener, array($request));
$this->assertSame($result, array($emailAddress, $credentials));
$result = $method->invokeArgs($listener, [$request]);
$this->assertSame($result, [$emailAddress, $credentials]);
}
public static function dataProviderGetPreAuthenticatedDataNoUser()
{
return array(
'basicEmailAddress' => array('cert@example.com'),
'emailAddressWithPlusSign' => array('cert+something@example.com'),
);
yield ['cert@example.com', 'CN=Sample certificate DN/emailAddress=cert@example.com'];
yield ['cert+something@example.com', 'CN=Sample certificate DN/emailAddress=cert+something@example.com'];
yield ['cert@example.com', 'CN=Sample certificate DN,emailAddress=cert@example.com'];
yield ['cert+something@example.com', 'CN=Sample certificate DN,emailAddress=cert+something@example.com'];
yield ['cert+something@example.com', 'emailAddress=cert+something@example.com,CN=Sample certificate DN'];
yield ['cert+something@example.com', 'emailAddress=cert+something@example.com'];
yield ['firstname.lastname@mycompany.co.uk', 'emailAddress=firstname.lastname@mycompany.co.uk,CN=Firstname.Lastname,OU=london,OU=company design and engineering,OU=Issuer London,OU=Roaming,OU=Interactive,OU=Users,OU=Standard,OU=Business,DC=england,DC=core,DC=company,DC=co,DC=uk'];
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
*/
public function testGetPreAuthenticatedDataNoData()
{
$request = new Request(array(), array(), array(), array(), array(), array());
$this->expectException('Symfony\Component\Security\Core\Exception\BadCredentialsException');
$request = new Request([], [], [], [], [], []);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
@@ -98,17 +98,17 @@ class X509AuthenticationListenerTest extends TestCase
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
$result = $method->invokeArgs($listener, array($request));
$method->invokeArgs($listener, [$request]);
}
public function testGetPreAuthenticatedDataWithDifferentKeys()
{
$userCredentials = array('TheUser', 'TheCredentials');
$userCredentials = ['TheUser', 'TheCredentials'];
$request = new Request(array(), array(), array(), array(), array(), array(
$request = new Request([], [], [], [], [], [
'TheUserKey' => 'TheUser',
'TheCredentialsKey' => 'TheCredentials',
));
]);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
@@ -118,7 +118,7 @@ class X509AuthenticationListenerTest extends TestCase
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
$result = $method->invokeArgs($listener, array($request));
$result = $method->invokeArgs($listener, [$request]);
$this->assertSame($result, $userCredentials);
}
}
+15 -15
View File
@@ -12,8 +12,8 @@
namespace Symfony\Component\Security\Http\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\FirewallMap;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\FirewallMap;
class FirewallMapTest extends TestCase
{
@@ -28,22 +28,22 @@ class FirewallMapTest extends TestCase
->expects($this->once())
->method('matches')
->with($this->equalTo($request))
->will($this->returnValue(false))
->willReturn(false)
;
$map->add($notMatchingMatcher, array($this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock()));
$map->add($notMatchingMatcher, [$this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock()]);
$matchingMatcher = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestMatcher')->getMock();
$matchingMatcher
->expects($this->once())
->method('matches')
->with($this->equalTo($request))
->will($this->returnValue(true))
->willReturn(true)
;
$theListener = $this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock();
$theException = $this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ExceptionListener')->disableOriginalConstructor()->getMock();
$map->add($matchingMatcher, array($theListener), $theException);
$map->add($matchingMatcher, [$theListener], $theException);
$tooLateMatcher = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestMatcher')->getMock();
$tooLateMatcher
@@ -51,11 +51,11 @@ class FirewallMapTest extends TestCase
->method('matches')
;
$map->add($tooLateMatcher, array($this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock()));
$map->add($tooLateMatcher, [$this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock()]);
list($listeners, $exception) = $map->getListeners($request);
$this->assertEquals(array($theListener), $listeners);
$this->assertEquals([$theListener], $listeners);
$this->assertEquals($theException, $exception);
}
@@ -70,15 +70,15 @@ class FirewallMapTest extends TestCase
->expects($this->once())
->method('matches')
->with($this->equalTo($request))
->will($this->returnValue(false))
->willReturn(false)
;
$map->add($notMatchingMatcher, array($this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock()));
$map->add($notMatchingMatcher, [$this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock()]);
$theListener = $this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock();
$theException = $this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ExceptionListener')->disableOriginalConstructor()->getMock();
$map->add(null, array($theListener), $theException);
$map->add(null, [$theListener], $theException);
$tooLateMatcher = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestMatcher')->getMock();
$tooLateMatcher
@@ -86,11 +86,11 @@ class FirewallMapTest extends TestCase
->method('matches')
;
$map->add($tooLateMatcher, array($this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock()));
$map->add($tooLateMatcher, [$this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock()]);
list($listeners, $exception) = $map->getListeners($request);
$this->assertEquals(array($theListener), $listeners);
$this->assertEquals([$theListener], $listeners);
$this->assertEquals($theException, $exception);
}
@@ -105,14 +105,14 @@ class FirewallMapTest extends TestCase
->expects($this->once())
->method('matches')
->with($this->equalTo($request))
->will($this->returnValue(false))
->willReturn(false)
;
$map->add($notMatchingMatcher, array($this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock()));
$map->add($notMatchingMatcher, [$this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock()]);
list($listeners, $exception) = $map->getListeners($request);
$this->assertEquals(array(), $listeners);
$this->assertEquals([], $listeners);
$this->assertNull($exception);
}
}
+6 -9
View File
@@ -12,7 +12,6 @@
namespace Symfony\Component\Security\Http\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Http\Firewall;
@@ -37,7 +36,7 @@ class FirewallTest extends TestCase
->expects($this->once())
->method('getListeners')
->with($this->equalTo($request))
->will($this->returnValue(array(array(), $listener)))
->willReturn([[], $listener])
;
$event = new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST);
@@ -48,8 +47,6 @@ class FirewallTest extends TestCase
public function testOnKernelRequestStopsWhenThereIsAResponse()
{
$response = new Response();
$first = $this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock();
$first
->expects($this->once())
@@ -66,22 +63,22 @@ class FirewallTest extends TestCase
$map
->expects($this->once())
->method('getListeners')
->will($this->returnValue(array(array($first, $second), null)))
->willReturn([[$first, $second], null])
;
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
->setMethods(array('hasResponse'))
->setConstructorArgs(array(
->setMethods(['hasResponse'])
->setConstructorArgs([
$this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(),
$this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->disableOriginalClone()->getMock(),
HttpKernelInterface::MASTER_REQUEST,
))
])
->getMock()
;
$event
->expects($this->once())
->method('hasResponse')
->will($this->returnValue(true))
->willReturn(true)
;
$firewall = new Firewall($map, $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock());
+48 -31
View File
@@ -15,8 +15,8 @@ use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\HttpUtils;
class HttpUtilsTest extends TestCase
@@ -54,14 +54,28 @@ class HttpUtilsTest extends TestCase
$this->assertTrue($response->isRedirect('http://localhost/blog'));
}
public function testCreateRedirectResponseWithBadRequestsDomain()
/**
* @dataProvider badRequestDomainUrls
*/
public function testCreateRedirectResponseWithBadRequestsDomain($url)
{
$utils = new HttpUtils($this->getUrlGenerator(), null, '#^https?://%s$#i');
$response = $utils->createRedirectResponse($this->getRequest(), 'http://pirate.net/foo');
$response = $utils->createRedirectResponse($this->getRequest(), $url);
$this->assertTrue($response->isRedirect('http://localhost/'));
}
public function badRequestDomainUrls()
{
return [
['http://pirate.net/foo'],
['http:\\\\pirate.net/foo'],
['http:/\\pirate.net/foo'],
['http:\\/pirate.net/foo'],
['http://////pirate.net/foo'],
];
}
public function testCreateRedirectResponseWithProtocolRelativeTarget()
{
$utils = new HttpUtils($this->getUrlGenerator(), null, '#^https?://%s$#i');
@@ -77,13 +91,13 @@ class HttpUtilsTest extends TestCase
$urlGenerator
->expects($this->any())
->method('generate')
->with('foobar', array(), UrlGeneratorInterface::ABSOLUTE_URL)
->will($this->returnValue('http://localhost/foo/bar'))
->with('foobar', [], UrlGeneratorInterface::ABSOLUTE_URL)
->willReturn('http://localhost/foo/bar')
;
$urlGenerator
->expects($this->any())
->method('getContext')
->will($this->returnValue($this->getMockBuilder('Symfony\Component\Routing\RequestContext')->getMock()))
->willReturn($this->getMockBuilder('Symfony\Component\Routing\RequestContext')->getMock())
;
$response = $utils->createRedirectResponse($this->getRequest(), 'foobar');
@@ -111,12 +125,12 @@ class HttpUtilsTest extends TestCase
$urlGenerator
->expects($this->once())
->method('generate')
->will($this->returnValue('/foo/bar'))
->willReturn('/foo/bar')
;
$urlGenerator
->expects($this->any())
->method('getContext')
->will($this->returnValue($this->getMockBuilder('Symfony\Component\Routing\RequestContext')->getMock()))
->willReturn($this->getMockBuilder('Symfony\Component\Routing\RequestContext')->getMock())
;
$subRequest = $utils->createRequest($this->getRequest(), 'foobar');
@@ -159,11 +173,11 @@ class HttpUtilsTest extends TestCase
public function provideSecurityContextAttributes()
{
return array(
array(Security::AUTHENTICATION_ERROR),
array(Security::ACCESS_DENIED_ERROR),
array(Security::LAST_USERNAME),
);
return [
[Security::AUTHENTICATION_ERROR],
[Security::ACCESS_DENIED_ERROR],
[Security::LAST_USERNAME],
];
}
public function testCheckRequestPath()
@@ -186,7 +200,7 @@ class HttpUtilsTest extends TestCase
->expects($this->any())
->method('match')
->with('/')
->will($this->throwException(new ResourceNotFoundException()))
->willThrowException(new ResourceNotFoundException())
;
$utils = new HttpUtils(null, $urlMatcher);
@@ -201,7 +215,7 @@ class HttpUtilsTest extends TestCase
->expects($this->any())
->method('matchRequest')
->with($request)
->will($this->throwException(new MethodNotAllowedException(array())))
->willThrowException(new MethodNotAllowedException([]))
;
$utils = new HttpUtils(null, $urlMatcher);
@@ -215,7 +229,7 @@ class HttpUtilsTest extends TestCase
->expects($this->any())
->method('match')
->with('/foo/bar')
->will($this->returnValue(array('_route' => 'foobar')))
->willReturn(['_route' => 'foobar'])
;
$utils = new HttpUtils(null, $urlMatcher);
@@ -230,23 +244,21 @@ class HttpUtilsTest extends TestCase
->expects($this->any())
->method('matchRequest')
->with($request)
->will($this->returnValue(array('_route' => 'foobar')))
->willReturn(['_route' => 'foobar'])
;
$utils = new HttpUtils(null, $urlMatcher);
$this->assertTrue($utils->checkRequestPath($request, 'foobar'));
}
/**
* @expectedException \RuntimeException
*/
public function testCheckRequestPathWithUrlMatcherLoadingException()
{
$this->expectException('RuntimeException');
$urlMatcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\UrlMatcherInterface')->getMock();
$urlMatcher
->expects($this->any())
->method('match')
->will($this->throwException(new \RuntimeException()))
->willThrowException(new \RuntimeException())
;
$utils = new HttpUtils(null, $urlMatcher);
@@ -259,19 +271,17 @@ class HttpUtilsTest extends TestCase
$urlMatcher
->expects($this->any())
->method('match')
->willReturn(array('_controller' => 'PathController'))
->willReturn(['_controller' => 'PathController'])
;
$utils = new HttpUtils(null, $urlMatcher);
$this->assertFalse($utils->checkRequestPath($this->getRequest(), 'path/index.html'));
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Matcher must either implement UrlMatcherInterface or RequestMatcherInterface
*/
public function testUrlMatcher()
{
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface');
new HttpUtils($this->getUrlGenerator(), new \stdClass());
}
@@ -284,12 +294,19 @@ class HttpUtilsTest extends TestCase
$this->assertEquals('/foo/bar', $utils->generateUri(new Request(), 'route_name'));
}
/**
* @expectedException \LogicException
* @expectedExceptionMessage You must provide a UrlGeneratorInterface instance to be able to use routes.
*/
public function testGenerateUriPreservesFragment()
{
$utils = new HttpUtils($this->getUrlGenerator('/foo/bar?param=value#fragment'));
$this->assertEquals('/foo/bar#fragment', $utils->generateUri(new Request(), 'route_name'));
$utils = new HttpUtils($this->getUrlGenerator('/foo/bar#fragment'));
$this->assertEquals('/foo/bar#fragment', $utils->generateUri(new Request(), 'route_name'));
}
public function testUrlGeneratorIsRequiredToGenerateUrl()
{
$this->expectException('LogicException');
$this->expectExceptionMessage('You must provide a UrlGeneratorInterface instance to be able to use routes.');
$utils = new HttpUtils();
$utils->generateUri(new Request(), 'route_name');
}
@@ -300,7 +317,7 @@ class HttpUtilsTest extends TestCase
$urlGenerator
->expects($this->any())
->method('generate')
->will($this->returnValue($generatedUrl))
->willReturn($generatedUrl)
;
return $urlGenerator;
@@ -12,9 +12,10 @@
namespace Symfony\Component\Security\Http\Tests\Logout;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Logout\CookieClearingLogoutHandler;
class CookieClearingLogoutHandlerTest extends TestCase
@@ -25,7 +26,7 @@ class CookieClearingLogoutHandlerTest extends TestCase
$response = new Response();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$handler = new CookieClearingLogoutHandler(array('foo' => array('path' => '/foo', 'domain' => 'foo.foo'), 'foo2' => array('path' => null, 'domain' => null)));
$handler = new CookieClearingLogoutHandler(['foo' => ['path' => '/foo', 'domain' => 'foo.foo', 'secure' => true, 'samesite' => Cookie::SAMESITE_STRICT], 'foo2' => ['path' => null, 'domain' => null]]);
$cookies = $response->headers->getCookies();
$this->assertCount(0, $cookies);
@@ -39,12 +40,16 @@ class CookieClearingLogoutHandlerTest extends TestCase
$this->assertEquals('foo', $cookie->getName());
$this->assertEquals('/foo', $cookie->getPath());
$this->assertEquals('foo.foo', $cookie->getDomain());
$this->assertEquals(Cookie::SAMESITE_STRICT, $cookie->getSameSite());
$this->assertTrue($cookie->isSecure());
$this->assertTrue($cookie->isCleared());
$cookie = $cookies['']['/']['foo2'];
$this->assertStringStartsWith('foo2', $cookie->getName());
$this->assertEquals('/', $cookie->getPath());
$this->assertNull($cookie->getDomain());
$this->assertNull($cookie->getSameSite());
$this->assertFalse($cookie->isSecure());
$this->assertTrue($cookie->isCleared());
}
}
@@ -12,7 +12,7 @@
namespace Symfony\Component\Security\Http\Tests\Logout;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Http\Logout\DefaultLogoutSuccessHandler;
class DefaultLogoutSuccessHandlerTest extends TestCase
@@ -20,13 +20,13 @@ class DefaultLogoutSuccessHandlerTest extends TestCase
public function testLogout()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$response = new Response();
$response = new RedirectResponse('/dashboard');
$httpUtils = $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')->getMock();
$httpUtils->expects($this->once())
->method('createRedirectResponse')
->with($request, '/dashboard')
->will($this->returnValue($response));
->willReturn($response);
$handler = new DefaultLogoutSuccessHandler($httpUtils, '/dashboard');
$result = $handler->onLogoutSuccess($request);
@@ -28,7 +28,7 @@ class SessionLogoutHandlerTest extends TestCase
$request
->expects($this->once())
->method('getSession')
->will($this->returnValue($session))
->willReturn($session)
;
$session
@@ -12,16 +12,16 @@
namespace Symfony\Component\Security\Http\Tests\RememberMe;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\RememberMe\AbstractRememberMeServices;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
class AbstractRememberMeServicesTest extends TestCase
{
public function testGetRememberMeParameter()
{
$service = $this->getService(null, array('remember_me_parameter' => 'foo'));
$service = $this->getService(null, ['remember_me_parameter' => 'foo']);
$this->assertEquals('foo', $service->getRememberMeParameter());
}
@@ -34,24 +34,36 @@ class AbstractRememberMeServicesTest extends TestCase
public function testAutoLoginReturnsNullWhenNoCookie()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null]);
$this->assertNull($service->autoLogin(new Request()));
}
public function testAutoLoginReturnsNullAfterLoginFail()
{
$service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null]);
$request = new Request();
$request->cookies->set('foo', 'foo');
$service->loginFail($request);
$this->assertNull($service->autoLogin($request));
}
/**
* @expectedException \RuntimeException
* @group legacy
*/
public function testAutoLoginThrowsExceptionWhenImplementationDoesNotReturnUserInterface()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$this->expectException('RuntimeException');
$service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null]);
$request = new Request();
$request->cookies->set('foo', 'foo');
$service
->expects($this->once())
->method('processAutoLoginCookie')
->will($this->returnValue(null))
->willReturn(null)
;
$service->autoLogin($request);
@@ -59,7 +71,7 @@ class AbstractRememberMeServicesTest extends TestCase
public function testAutoLogin()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null]);
$request = new Request();
$request->cookies->set('foo', 'foo');
@@ -67,13 +79,13 @@ class AbstractRememberMeServicesTest extends TestCase
$user
->expects($this->once())
->method('getRoles')
->will($this->returnValue(array()))
->willReturn([])
;
$service
->expects($this->once())
->method('processAutoLoginCookie')
->will($this->returnValue($user))
->willReturn($user)
;
$returnedToken = $service->autoLogin($request);
@@ -105,15 +117,15 @@ class AbstractRememberMeServicesTest extends TestCase
public function provideOptionsForLogout()
{
return array(
array(array('name' => 'foo', 'path' => '/', 'domain' => null, 'secure' => false, 'httponly' => true)),
array(array('name' => 'foo', 'path' => '/bar', 'domain' => 'baz.com', 'secure' => true, 'httponly' => false)),
);
return [
[['name' => 'foo', 'path' => '/', 'domain' => null, 'secure' => false, 'httponly' => true]],
[['name' => 'foo', 'path' => '/bar', 'domain' => 'baz.com', 'secure' => true, 'httponly' => false]],
];
}
public function testLoginFail()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null]);
$request = new Request();
$service->loginFail($request);
@@ -123,15 +135,14 @@ class AbstractRememberMeServicesTest extends TestCase
public function testLoginSuccessIsNotProcessedWhenTokenDoesNotContainUserInterfaceImplementation()
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => true, 'path' => null, 'domain' => null));
$service = $this->getService(null, ['name' => 'foo', 'always_remember_me' => true, 'path' => null, 'domain' => null]);
$request = new Request();
$response = new Response();
$account = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token
->expects($this->once())
->method('getUser')
->will($this->returnValue('foo'))
->willReturn('foo')
;
$service
@@ -146,7 +157,7 @@ class AbstractRememberMeServicesTest extends TestCase
public function testLoginSuccessIsNotProcessedWhenRememberMeIsNotRequested()
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo', 'path' => null, 'domain' => null));
$service = $this->getService(null, ['name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo', 'path' => null, 'domain' => null]);
$request = new Request();
$response = new Response();
$account = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
@@ -154,13 +165,13 @@ class AbstractRememberMeServicesTest extends TestCase
$token
->expects($this->once())
->method('getUser')
->will($this->returnValue($account))
->willReturn($account)
;
$service
->expects($this->never())
->method('onLoginSuccess')
->will($this->returnValue(null))
->willReturn(null)
;
$this->assertFalse($request->request->has('foo'));
@@ -170,7 +181,7 @@ class AbstractRememberMeServicesTest extends TestCase
public function testLoginSuccessWhenRememberMeAlwaysIsTrue()
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => true, 'path' => null, 'domain' => null));
$service = $this->getService(null, ['name' => 'foo', 'always_remember_me' => true, 'path' => null, 'domain' => null]);
$request = new Request();
$response = new Response();
$account = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
@@ -178,13 +189,13 @@ class AbstractRememberMeServicesTest extends TestCase
$token
->expects($this->once())
->method('getUser')
->will($this->returnValue($account))
->willReturn($account)
;
$service
->expects($this->once())
->method('onLoginSuccess')
->will($this->returnValue(null))
->willReturn(null)
;
$service->loginSuccess($request, $response, $token);
@@ -195,23 +206,23 @@ class AbstractRememberMeServicesTest extends TestCase
*/
public function testLoginSuccessWhenRememberMeParameterWithPathIsPositive($value)
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo[bar]', 'path' => null, 'domain' => null));
$service = $this->getService(null, ['name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo[bar]', 'path' => null, 'domain' => null]);
$request = new Request();
$request->request->set('foo', array('bar' => $value));
$request->request->set('foo', ['bar' => $value]);
$response = new Response();
$account = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token
->expects($this->once())
->method('getUser')
->will($this->returnValue($account))
->willReturn($account)
;
$service
->expects($this->once())
->method('onLoginSuccess')
->will($this->returnValue(true))
->willReturn(true)
;
$service->loginSuccess($request, $response, $token);
@@ -222,7 +233,7 @@ class AbstractRememberMeServicesTest extends TestCase
*/
public function testLoginSuccessWhenRememberMeParameterIsPositive($value)
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo', 'path' => null, 'domain' => null));
$service = $this->getService(null, ['name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo', 'path' => null, 'domain' => null]);
$request = new Request();
$request->request->set('foo', $value);
@@ -232,13 +243,13 @@ class AbstractRememberMeServicesTest extends TestCase
$token
->expects($this->once())
->method('getUser')
->will($this->returnValue($account))
->willReturn($account)
;
$service
->expects($this->once())
->method('onLoginSuccess')
->will($this->returnValue(true))
->willReturn(true)
;
$service->loginSuccess($request, $response, $token);
@@ -246,48 +257,46 @@ class AbstractRememberMeServicesTest extends TestCase
public function getPositiveRememberMeParameterValues()
{
return array(
array('true'),
array('1'),
array('on'),
array('yes'),
array(true),
);
return [
['true'],
['1'],
['on'],
['yes'],
[true],
];
}
public function testEncodeCookieAndDecodeCookieAreInvertible()
{
$cookieParts = array('aa', 'bb', 'cc');
$cookieParts = ['aa', 'bb', 'cc'];
$service = $this->getService();
$encoded = $this->callProtected($service, 'encodeCookie', array($cookieParts));
$this->assertInternalType('string', $encoded);
$encoded = $this->callProtected($service, 'encodeCookie', [$cookieParts]);
$this->assertIsString($encoded);
$decoded = $this->callProtected($service, 'decodeCookie', array($encoded));
$decoded = $this->callProtected($service, 'decodeCookie', [$encoded]);
$this->assertSame($cookieParts, $decoded);
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage cookie delimiter
*/
public function testThereShouldBeNoCookieDelimiterInCookieParts()
{
$cookieParts = array('aa', 'b'.AbstractRememberMeServices::COOKIE_DELIMITER.'b', 'cc');
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage('cookie delimiter');
$cookieParts = ['aa', 'b'.AbstractRememberMeServices::COOKIE_DELIMITER.'b', 'cc'];
$service = $this->getService();
$this->callProtected($service, 'encodeCookie', array($cookieParts));
$this->callProtected($service, 'encodeCookie', [$cookieParts]);
}
protected function getService($userProvider = null, $options = array(), $logger = null)
protected function getService($userProvider = null, $options = [], $logger = null)
{
if (null === $userProvider) {
$userProvider = $this->getProvider();
}
return $this->getMockForAbstractClass('Symfony\Component\Security\Http\RememberMe\AbstractRememberMeServices', array(
array($userProvider), 'foosecret', 'fookey', $options, $logger,
));
return $this->getMockForAbstractClass('Symfony\Component\Security\Http\RememberMe\AbstractRememberMeServices', [
[$userProvider], 'foosecret', 'fookey', $options, $logger,
]);
}
protected function getProvider()
@@ -296,7 +305,7 @@ class AbstractRememberMeServicesTest extends TestCase
$provider
->expects($this->any())
->method('supportsClass')
->will($this->returnValue(true))
->willReturn(true)
;
return $provider;
@@ -304,7 +313,7 @@ class AbstractRememberMeServicesTest extends TestCase
private function callProtected($object, $method, array $args)
{
$reflection = new \ReflectionClass(get_class($object));
$reflection = new \ReflectionClass(\get_class($object));
$reflectionMethod = $reflection->getMethod($method);
$reflectionMethod->setAccessible(true);
@@ -12,15 +12,16 @@
namespace Symfony\Component\Security\Http\Tests\RememberMe;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\Security\Http\RememberMe\PersistentTokenBasedRememberMeServices;
use Symfony\Component\Security\Core\Exception\TokenNotFoundException;
use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken;
use Symfony\Component\Security\Core\Exception\CookieTheftException;
use Symfony\Component\Security\Core\Exception\TokenNotFoundException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Http\RememberMe\PersistentTokenBasedRememberMeServices;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
class PersistentTokenBasedRememberMeServicesTest extends TestCase
{
@@ -35,14 +36,14 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
public function testAutoLoginReturnsNullWhenNoCookie()
{
$service = $this->getService(null, array('name' => 'foo'));
$service = $this->getService(null, ['name' => 'foo']);
$this->assertNull($service->autoLogin(new Request()));
}
public function testAutoLoginThrowsExceptionOnInvalidCookie()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => false, 'remember_me_parameter' => 'foo'));
$service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => false, 'remember_me_parameter' => 'foo']);
$request = new Request();
$request->request->set('foo', 'true');
$request->cookies->set('foo', 'foo');
@@ -53,19 +54,19 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
public function testAutoLoginThrowsExceptionOnNonExistentToken()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => false, 'remember_me_parameter' => 'foo'));
$service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => false, 'remember_me_parameter' => 'foo']);
$request = new Request();
$request->request->set('foo', 'true');
$request->cookies->set('foo', $this->encodeCookie(array(
$request->cookies->set('foo', $this->encodeCookie([
$series = 'fooseries',
$tokenValue = 'foovalue',
)));
]));
$tokenProvider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface')->getMock();
$tokenProvider
->expects($this->once())
->method('loadTokenBySeries')
->will($this->throwException(new TokenNotFoundException('Token not found.')))
->willThrowException(new TokenNotFoundException('Token not found.'))
;
$service->setTokenProvider($tokenProvider);
@@ -76,22 +77,22 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
public function testAutoLoginReturnsNullOnNonExistentUser()
{
$userProvider = $this->getProvider();
$service = $this->getService($userProvider, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600, 'secure' => false, 'httponly' => false));
$service = $this->getService($userProvider, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600, 'secure' => false, 'httponly' => false]);
$request = new Request();
$request->cookies->set('foo', $this->encodeCookie(array('fooseries', 'foovalue')));
$request->cookies->set('foo', $this->encodeCookie(['fooseries', 'foovalue']));
$tokenProvider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface')->getMock();
$tokenProvider
->expects($this->once())
->method('loadTokenBySeries')
->will($this->returnValue(new PersistentToken('fooclass', 'fooname', 'fooseries', 'foovalue', new \DateTime())))
->willReturn(new PersistentToken('fooclass', 'fooname', 'fooseries', 'foovalue', new \DateTime()))
;
$service->setTokenProvider($tokenProvider);
$userProvider
->expects($this->once())
->method('loadUserByUsername')
->will($this->throwException(new UsernameNotFoundException('user not found')))
->willThrowException(new UsernameNotFoundException('user not found'))
;
$this->assertNull($service->autoLogin($request));
@@ -101,9 +102,9 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
public function testAutoLoginThrowsExceptionOnStolenCookieAndRemovesItFromThePersistentBackend()
{
$userProvider = $this->getProvider();
$service = $this->getService($userProvider, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true));
$service = $this->getService($userProvider, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true]);
$request = new Request();
$request->cookies->set('foo', $this->encodeCookie(array('fooseries', 'foovalue')));
$request->cookies->set('foo', $this->encodeCookie(['fooseries', 'foovalue']));
$tokenProvider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface')->getMock();
$service->setTokenProvider($tokenProvider);
@@ -111,14 +112,14 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
$tokenProvider
->expects($this->once())
->method('loadTokenBySeries')
->will($this->returnValue(new PersistentToken('fooclass', 'foouser', 'fooseries', 'anotherFooValue', new \DateTime())))
->willReturn(new PersistentToken('fooclass', 'foouser', 'fooseries', 'anotherFooValue', new \DateTime()))
;
$tokenProvider
->expects($this->once())
->method('deleteTokenBySeries')
->with($this->equalTo('fooseries'))
->will($this->returnValue(null))
->willReturn(null)
;
try {
@@ -132,16 +133,16 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
public function testAutoLoginDoesNotAcceptAnExpiredCookie()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600));
$service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600]);
$request = new Request();
$request->cookies->set('foo', $this->encodeCookie(array('fooseries', 'foovalue')));
$request->cookies->set('foo', $this->encodeCookie(['fooseries', 'foovalue']));
$tokenProvider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface')->getMock();
$tokenProvider
->expects($this->once())
->method('loadTokenBySeries')
->with($this->equalTo('fooseries'))
->will($this->returnValue(new PersistentToken('fooclass', 'username', 'fooseries', 'foovalue', new \DateTime('yesterday'))))
->willReturn(new PersistentToken('fooclass', 'username', 'fooseries', 'foovalue', new \DateTime('yesterday')))
;
$service->setTokenProvider($tokenProvider);
@@ -155,7 +156,7 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
$user
->expects($this->once())
->method('getRoles')
->will($this->returnValue(array('ROLE_FOO')))
->willReturn(['ROLE_FOO'])
;
$userProvider = $this->getProvider();
@@ -163,19 +164,19 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
->expects($this->once())
->method('loadUserByUsername')
->with($this->equalTo('foouser'))
->will($this->returnValue($user))
->willReturn($user)
;
$service = $this->getService($userProvider, array('name' => 'foo', 'path' => null, 'domain' => null, 'secure' => false, 'httponly' => false, 'always_remember_me' => true, 'lifetime' => 3600));
$service = $this->getService($userProvider, ['name' => 'foo', 'path' => null, 'domain' => null, 'secure' => false, 'httponly' => false, 'always_remember_me' => true, 'lifetime' => 3600]);
$request = new Request();
$request->cookies->set('foo', $this->encodeCookie(array('fooseries', 'foovalue')));
$request->cookies->set('foo', $this->encodeCookie(['fooseries', 'foovalue']));
$tokenProvider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface')->getMock();
$tokenProvider
->expects($this->once())
->method('loadTokenBySeries')
->with($this->equalTo('fooseries'))
->will($this->returnValue(new PersistentToken('fooclass', 'foouser', 'fooseries', 'foovalue', new \DateTime())))
->willReturn(new PersistentToken('fooclass', 'foouser', 'fooseries', 'foovalue', new \DateTime()))
;
$service->setTokenProvider($tokenProvider);
@@ -189,9 +190,9 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
public function testLogout()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => '/foo', 'domain' => 'foodomain.foo', 'secure' => true, 'httponly' => false));
$service = $this->getService(null, ['name' => 'foo', 'path' => '/foo', 'domain' => 'foodomain.foo', 'secure' => true, 'httponly' => false]);
$request = new Request();
$request->cookies->set('foo', $this->encodeCookie(array('fooseries', 'foovalue')));
$request->cookies->set('foo', $this->encodeCookie(['fooseries', 'foovalue']));
$response = new Response();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
@@ -200,7 +201,7 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
->expects($this->once())
->method('deleteTokenBySeries')
->with($this->equalTo('fooseries'))
->will($this->returnValue(null))
->willReturn(null)
;
$service->setTokenProvider($tokenProvider);
@@ -216,7 +217,7 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
public function testLogoutSimplyIgnoresNonSetRequestCookie()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null]);
$request = new Request();
$response = new Response();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
@@ -238,7 +239,7 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
public function testLogoutSimplyIgnoresInvalidCookie()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null]);
$request = new Request();
$request->cookies->set('foo', 'somefoovalue');
$response = new Response();
@@ -258,7 +259,7 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
public function testLoginFail()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null]);
$request = new Request();
$this->assertFalse($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME));
@@ -268,7 +269,7 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
public function testLoginSuccessSetsCookieWhenLoggedInWithNonRememberMeTokenInterfaceImplementation()
{
$service = $this->getService(null, array('name' => 'foo', 'domain' => 'myfoodomain.foo', 'path' => '/foo/path', 'secure' => true, 'httponly' => true, 'lifetime' => 3600, 'always_remember_me' => true));
$service = $this->getService(null, ['name' => 'foo', 'domain' => 'myfoodomain.foo', 'path' => '/foo/path', 'secure' => true, 'httponly' => true, 'samesite' => Cookie::SAMESITE_STRICT, 'lifetime' => 3600, 'always_remember_me' => true]);
$request = new Request();
$response = new Response();
@@ -276,13 +277,13 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
$account
->expects($this->once())
->method('getUsername')
->will($this->returnValue('foo'))
->willReturn('foo')
;
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token
->expects($this->any())
->method('getUser')
->will($this->returnValue($account))
->willReturn($account)
;
$tokenProvider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface')->getMock();
@@ -305,6 +306,7 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
$this->assertTrue($cookie->getExpiresTime() > time() + 3590 && $cookie->getExpiresTime() < time() + 3610);
$this->assertEquals('myfoodomain.foo', $cookie->getDomain());
$this->assertEquals('/foo/path', $cookie->getPath());
$this->assertSame(Cookie::SAMESITE_STRICT, $cookie->getSameSite());
}
protected function encodeCookie(array $parts)
@@ -316,13 +318,13 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
return $r->invoke($service, $parts);
}
protected function getService($userProvider = null, $options = array(), $logger = null)
protected function getService($userProvider = null, $options = [], $logger = null)
{
if (null === $userProvider) {
$userProvider = $this->getProvider();
}
return new PersistentTokenBasedRememberMeServices(array($userProvider), 'foosecret', 'fookey', $options, $logger);
return new PersistentTokenBasedRememberMeServices([$userProvider], 'foosecret', 'fookey', $options, $logger);
}
protected function getProvider()
@@ -331,7 +333,7 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
$provider
->expects($this->any())
->method('supportsClass')
->will($this->returnValue(true))
->willReturn(true)
;
return $provider;
@@ -12,13 +12,13 @@
namespace Symfony\Component\Security\Http\Tests\RememberMe;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Http\RememberMe\ResponseListener;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Http\RememberMe\ResponseListener;
class ResponseListenerTest extends TestCase
{
@@ -26,9 +26,9 @@ class ResponseListenerTest extends TestCase
{
$cookie = new Cookie('rememberme');
$request = $this->getRequest(array(
$request = $this->getRequest([
RememberMeServicesInterface::COOKIE_ATTR_NAME => $cookie,
));
]);
$response = $this->getResponse();
$response->headers->expects($this->once())->method('setCookie')->with($cookie);
@@ -41,9 +41,9 @@ class ResponseListenerTest extends TestCase
{
$cookie = new Cookie('rememberme');
$request = $this->getRequest(array(
$request = $this->getRequest([
RememberMeServicesInterface::COOKIE_ATTR_NAME => $cookie,
));
]);
$response = $this->getResponse();
$response->headers->expects($this->never())->method('setCookie');
@@ -65,12 +65,10 @@ class ResponseListenerTest extends TestCase
public function testItSubscribesToTheOnKernelResponseEvent()
{
$listener = new ResponseListener();
$this->assertSame(array(KernelEvents::RESPONSE => 'onKernelResponse'), ResponseListener::getSubscribedEvents());
$this->assertSame([KernelEvents::RESPONSE => 'onKernelResponse'], ResponseListener::getSubscribedEvents());
}
private function getRequest(array $attributes = array())
private function getRequest(array $attributes = [])
{
$request = new Request();
@@ -95,9 +93,9 @@ class ResponseListenerTest extends TestCase
->disableOriginalConstructor()
->getMock();
$event->expects($this->any())->method('getRequest')->will($this->returnValue($request));
$event->expects($this->any())->method('isMasterRequest')->will($this->returnValue($type === HttpKernelInterface::MASTER_REQUEST));
$event->expects($this->any())->method('getResponse')->will($this->returnValue($response));
$event->expects($this->any())->method('getRequest')->willReturn($request);
$event->expects($this->any())->method('isMasterRequest')->willReturn(HttpKernelInterface::MASTER_REQUEST === $type);
$event->expects($this->any())->method('getResponse')->willReturn($response);
return $event;
}
@@ -12,25 +12,26 @@
namespace Symfony\Component\Security\Http\Tests\RememberMe;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices;
class TokenBasedRememberMeServicesTest extends TestCase
{
public function testAutoLoginReturnsNullWhenNoCookie()
{
$service = $this->getService(null, array('name' => 'foo'));
$service = $this->getService(null, ['name' => 'foo']);
$this->assertNull($service->autoLogin(new Request()));
}
public function testAutoLoginThrowsExceptionOnInvalidCookie()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => false, 'remember_me_parameter' => 'foo'));
$service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => false, 'remember_me_parameter' => 'foo']);
$request = new Request();
$request->request->set('foo', 'true');
$request->cookies->set('foo', 'foo');
@@ -42,14 +43,14 @@ class TokenBasedRememberMeServicesTest extends TestCase
public function testAutoLoginThrowsExceptionOnNonExistentUser()
{
$userProvider = $this->getProvider();
$service = $this->getService($userProvider, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600));
$service = $this->getService($userProvider, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600]);
$request = new Request();
$request->cookies->set('foo', $this->getCookie('fooclass', 'foouser', time() + 3600, 'foopass'));
$userProvider
->expects($this->once())
->method('loadUserByUsername')
->will($this->throwException(new UsernameNotFoundException('user not found')))
->willThrowException(new UsernameNotFoundException('user not found'))
;
$this->assertNull($service->autoLogin($request));
@@ -59,7 +60,7 @@ class TokenBasedRememberMeServicesTest extends TestCase
public function testAutoLoginDoesNotAcceptCookieWithInvalidHash()
{
$userProvider = $this->getProvider();
$service = $this->getService($userProvider, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600));
$service = $this->getService($userProvider, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600]);
$request = new Request();
$request->cookies->set('foo', base64_encode('class:'.base64_encode('foouser').':123456789:fooHash'));
@@ -67,14 +68,14 @@ class TokenBasedRememberMeServicesTest extends TestCase
$user
->expects($this->once())
->method('getPassword')
->will($this->returnValue('foopass'))
->willReturn('foopass')
;
$userProvider
->expects($this->once())
->method('loadUserByUsername')
->with($this->equalTo('foouser'))
->will($this->returnValue($user))
->willReturn($user)
;
$this->assertNull($service->autoLogin($request));
@@ -84,7 +85,7 @@ class TokenBasedRememberMeServicesTest extends TestCase
public function testAutoLoginDoesNotAcceptAnExpiredCookie()
{
$userProvider = $this->getProvider();
$service = $this->getService($userProvider, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600));
$service = $this->getService($userProvider, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600]);
$request = new Request();
$request->cookies->set('foo', $this->getCookie('fooclass', 'foouser', time() - 1, 'foopass'));
@@ -92,14 +93,14 @@ class TokenBasedRememberMeServicesTest extends TestCase
$user
->expects($this->once())
->method('getPassword')
->will($this->returnValue('foopass'))
->willReturn('foopass')
;
$userProvider
->expects($this->once())
->method('loadUserByUsername')
->with($this->equalTo('foouser'))
->will($this->returnValue($user))
->willReturn($user)
;
$this->assertNull($service->autoLogin($request));
@@ -117,12 +118,12 @@ class TokenBasedRememberMeServicesTest extends TestCase
$user
->expects($this->once())
->method('getRoles')
->will($this->returnValue(array('ROLE_FOO')))
->willReturn(['ROLE_FOO'])
;
$user
->expects($this->once())
->method('getPassword')
->will($this->returnValue('foopass'))
->willReturn('foopass')
;
$userProvider = $this->getProvider();
@@ -130,10 +131,10 @@ class TokenBasedRememberMeServicesTest extends TestCase
->expects($this->once())
->method('loadUserByUsername')
->with($this->equalTo($username))
->will($this->returnValue($user))
->willReturn($user)
;
$service = $this->getService($userProvider, array('name' => 'foo', 'always_remember_me' => true, 'lifetime' => 3600));
$service = $this->getService($userProvider, ['name' => 'foo', 'always_remember_me' => true, 'lifetime' => 3600]);
$request = new Request();
$request->cookies->set('foo', $this->getCookie('fooclass', $username, time() + 3600, 'foopass'));
@@ -146,15 +147,15 @@ class TokenBasedRememberMeServicesTest extends TestCase
public function provideUsernamesForAutoLogin()
{
return array(
array('foouser', 'Simple username'),
array('foo'.TokenBasedRememberMeServices::COOKIE_DELIMITER.'user', 'Username might contain the delimiter'),
);
return [
['foouser', 'Simple username'],
['foo'.TokenBasedRememberMeServices::COOKIE_DELIMITER.'user', 'Username might contain the delimiter'],
];
}
public function testLogout()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null, 'secure' => true, 'httponly' => false));
$service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null, 'secure' => true, 'httponly' => false]);
$request = new Request();
$response = new Response();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
@@ -171,7 +172,7 @@ class TokenBasedRememberMeServicesTest extends TestCase
public function testLoginFail()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => '/foo', 'domain' => 'foodomain.foo'));
$service = $this->getService(null, ['name' => 'foo', 'path' => '/foo', 'domain' => 'foodomain.foo']);
$request = new Request();
$service->loginFail($request);
@@ -184,14 +185,14 @@ class TokenBasedRememberMeServicesTest extends TestCase
public function testLoginSuccessIgnoresTokensWhichDoNotContainAnUserInterfaceImplementation()
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => true, 'path' => null, 'domain' => null));
$service = $this->getService(null, ['name' => 'foo', 'always_remember_me' => true, 'path' => null, 'domain' => null]);
$request = new Request();
$response = new Response();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token
->expects($this->once())
->method('getUser')
->will($this->returnValue('foo'))
->willReturn('foo')
;
$cookies = $response->headers->getCookies();
@@ -205,7 +206,7 @@ class TokenBasedRememberMeServicesTest extends TestCase
public function testLoginSuccess()
{
$service = $this->getService(null, array('name' => 'foo', 'domain' => 'myfoodomain.foo', 'path' => '/foo/path', 'secure' => true, 'httponly' => true, 'lifetime' => 3600, 'always_remember_me' => true));
$service = $this->getService(null, ['name' => 'foo', 'domain' => 'myfoodomain.foo', 'path' => '/foo/path', 'secure' => true, 'httponly' => true, 'samesite' => Cookie::SAMESITE_STRICT, 'lifetime' => 3600, 'always_remember_me' => true]);
$request = new Request();
$response = new Response();
@@ -214,17 +215,17 @@ class TokenBasedRememberMeServicesTest extends TestCase
$user
->expects($this->once())
->method('getPassword')
->will($this->returnValue('foopass'))
->willReturn('foopass')
;
$user
->expects($this->once())
->method('getUsername')
->will($this->returnValue('foouser'))
->willReturn('foouser')
;
$token
->expects($this->atLeastOnce())
->method('getUser')
->will($this->returnValue($user))
->willReturn($user)
;
$cookies = $response->headers->getCookies();
@@ -240,6 +241,7 @@ class TokenBasedRememberMeServicesTest extends TestCase
$this->assertTrue($cookie->getExpiresTime() > time() + 3590 && $cookie->getExpiresTime() < time() + 3610);
$this->assertEquals('myfoodomain.foo', $cookie->getDomain());
$this->assertEquals('/foo/path', $cookie->getPath());
$this->assertSame(Cookie::SAMESITE_STRICT, $cookie->getSameSite());
}
protected function getCookie($class, $username, $expires, $password)
@@ -260,13 +262,13 @@ class TokenBasedRememberMeServicesTest extends TestCase
return $r->invoke($service, $parts);
}
protected function getService($userProvider = null, $options = array(), $logger = null)
protected function getService($userProvider = null, $options = [], $logger = null)
{
if (null === $userProvider) {
$userProvider = $this->getProvider();
}
$service = new TokenBasedRememberMeServices(array($userProvider), 'foosecret', 'fookey', $options, $logger);
$service = new TokenBasedRememberMeServices([$userProvider], 'foosecret', 'fookey', $options, $logger);
return $service;
}
@@ -277,7 +279,7 @@ class TokenBasedRememberMeServicesTest extends TestCase
$provider
->expects($this->any())
->method('supportsClass')
->will($this->returnValue(true))
->willReturn(true)
;
return $provider;
@@ -25,12 +25,10 @@ class SessionAuthenticationStrategyTest extends TestCase
$strategy->onAuthentication($request, $this->getToken());
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage Invalid session authentication strategy "foo"
*/
public function testUnsupportedStrategy()
{
$this->expectException('RuntimeException');
$this->expectExceptionMessage('Invalid session authentication strategy "foo"');
$request = $this->getRequest();
$request->expects($this->never())->method('getSession');
@@ -61,7 +59,7 @@ class SessionAuthenticationStrategyTest extends TestCase
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
if (null !== $session) {
$request->expects($this->any())->method('getSession')->will($this->returnValue($session));
$request->expects($this->any())->method('getSession')->willReturn($session);
}
return $request;
+5 -8
View File
@@ -23,9 +23,8 @@ trait TargetPathTrait
*
* Usually, you do not need to set this directly.
*
* @param SessionInterface $session
* @param string $providerKey The name of your firewall
* @param string $uri The URI to set as the target path
* @param string $providerKey The name of your firewall
* @param string $uri The URI to set as the target path
*/
private function saveTargetPath(SessionInterface $session, $providerKey, $uri)
{
@@ -35,10 +34,9 @@ trait TargetPathTrait
/**
* Returns the URL (if any) the user visited that forced them to login.
*
* @param SessionInterface $session
* @param string $providerKey The name of your firewall
* @param string $providerKey The name of your firewall
*
* @return string
* @return string|null
*/
private function getTargetPath(SessionInterface $session, $providerKey)
{
@@ -48,8 +46,7 @@ trait TargetPathTrait
/**
* Removes the target path from the session.
*
* @param SessionInterface $session
* @param string $providerKey The name of your firewall
* @param string $providerKey The name of your firewall
*/
private function removeTargetPath(SessionInterface $session, $providerKey)
{
+12 -14
View File
@@ -16,20 +16,23 @@
}
],
"require": {
"php": ">=5.5.9",
"symfony/security-core": "~3.2",
"symfony/event-dispatcher": "~2.8|~3.0",
"symfony/http-foundation": "~2.8|~3.0",
"symfony/http-kernel": "~2.8|~3.0",
"php": "^5.5.9|>=7.0.8",
"symfony/security-core": "~3.2|~4.0",
"symfony/event-dispatcher": "~2.8|~3.0|~4.0",
"symfony/http-foundation": "~3.4.40|^4.4.7",
"symfony/http-kernel": "~3.3|~4.0",
"symfony/polyfill-php56": "~1.0",
"symfony/polyfill-php70": "~1.0",
"symfony/property-access": "~2.8|~3.0"
"symfony/property-access": "~2.8|~3.0|~4.0"
},
"require-dev": {
"symfony/routing": "~2.8|~3.0",
"symfony/security-csrf": "~2.8|~3.0",
"symfony/routing": "~2.8|~3.0|~4.0",
"symfony/security-csrf": "^2.8.41|~3.3.17|~3.4.11|^4.0.11",
"psr/log": "~1.0"
},
"conflict": {
"symfony/security-csrf": "<2.8.41|~3.0,<3.3.17|~3.4,<3.4.11|~4.0,<4.0.11"
},
"suggest": {
"symfony/security-csrf": "For using tokens to protect authentication/logout attempts",
"symfony/routing": "For using the HttpUtils class to create sub-requests, redirect the user, and match URLs"
@@ -40,10 +43,5 @@
"/Tests/"
]
},
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
}
}
"minimum-stability": "dev"
}
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"