diff options
Diffstat (limited to 'Http')
21 files changed, 207 insertions, 163 deletions
diff --git a/Http/Authentication/DefaultAuthenticationSuccessHandler.php b/Http/Authentication/DefaultAuthenticationSuccessHandler.php index bfc0c8b..4cb4bb6 100644 --- a/Http/Authentication/DefaultAuthenticationSuccessHandler.php +++ b/Http/Authentication/DefaultAuthenticationSuccessHandler.php @@ -13,6 +13,7 @@ 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\Http\HttpUtils; use Symfony\Component\Security\Http\ParameterBagUtils; @@ -25,6 +26,8 @@ use Symfony\Component\Security\Http\ParameterBagUtils; */ class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface { + use TargetPathTrait; + protected $httpUtils; protected $options; protected $providerKey; @@ -113,8 +116,8 @@ class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandle return $targetUrl; } - if (null !== $this->providerKey && $targetUrl = $request->getSession()->get('_security.'.$this->providerKey.'.target_path')) { - $request->getSession()->remove('_security.'.$this->providerKey.'.target_path'); + if (null !== $this->providerKey && $targetUrl = $this->getTargetPath($request->getSession(), $this->providerKey)) { + $this->removeTargetPath($request->getSession(), $this->providerKey); return $targetUrl; } diff --git a/Http/Authentication/SimpleFormAuthenticatorInterface.php b/Http/Authentication/SimpleFormAuthenticatorInterface.php index 112688c..39c3133 100644 --- a/Http/Authentication/SimpleFormAuthenticatorInterface.php +++ b/Http/Authentication/SimpleFormAuthenticatorInterface.php @@ -11,11 +11,13 @@ namespace Symfony\Component\Security\Http\Authentication; -use Symfony\Component\Security\Core\Authentication\SimpleFormAuthenticatorInterface as BaseSimpleFormAuthenticatorInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface; /** * @author Jordi Boggiano <j.boggiano@seld.be> */ -interface SimpleFormAuthenticatorInterface extends BaseSimpleFormAuthenticatorInterface +interface SimpleFormAuthenticatorInterface extends SimpleAuthenticatorInterface { + public function createToken(Request $request, $username, $password, $providerKey); } diff --git a/Http/Authentication/SimplePreAuthenticatorInterface.php b/Http/Authentication/SimplePreAuthenticatorInterface.php index afa8049..63abb15 100644 --- a/Http/Authentication/SimplePreAuthenticatorInterface.php +++ b/Http/Authentication/SimplePreAuthenticatorInterface.php @@ -11,11 +11,13 @@ namespace Symfony\Component\Security\Http\Authentication; -use Symfony\Component\Security\Core\Authentication\SimplePreAuthenticatorInterface as BaseSimplePreAuthenticatorInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface; /** * @author Jordi Boggiano <j.boggiano@seld.be> */ -interface SimplePreAuthenticatorInterface extends BaseSimplePreAuthenticatorInterface +interface SimplePreAuthenticatorInterface extends SimpleAuthenticatorInterface { + public function createToken(Request $request, $providerKey); } diff --git a/Http/EntryPoint/DigestAuthenticationEntryPoint.php b/Http/EntryPoint/DigestAuthenticationEntryPoint.php index cdb98eb..9dfd592 100644 --- a/Http/EntryPoint/DigestAuthenticationEntryPoint.php +++ b/Http/EntryPoint/DigestAuthenticationEntryPoint.php @@ -65,16 +65,6 @@ class DigestAuthenticationEntryPoint implements AuthenticationEntryPointInterfac } /** - * @deprecated Since version 2.8, to be removed in 3.0. Use getSecret() instead. - */ - public function getKey() - { - @trigger_error(__method__.'() is deprecated since version 2.8 and will be removed in 3.0. Use getSecret() instead.', E_USER_DEPRECATED); - - return $this->getSecret(); - } - - /** * @return string */ public function getSecret() diff --git a/Http/Firewall/ContextListener.php b/Http/Firewall/ContextListener.php index 9ac37cd..4d6f3f8 100644 --- a/Http/Firewall/ContextListener.php +++ b/Http/Firewall/ContextListener.php @@ -15,7 +15,10 @@ use Psr\Log\LoggerInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver; +use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface; 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; @@ -39,8 +42,9 @@ class ContextListener implements ListenerInterface private $userProviders; private $dispatcher; private $registered; + private $trustResolver; - public function __construct(TokenStorageInterface $tokenStorage, array $userProviders, $contextKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null) + public function __construct(TokenStorageInterface $tokenStorage, array $userProviders, $contextKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, AuthenticationTrustResolverInterface $trustResolver = null) { if (empty($contextKey)) { throw new \InvalidArgumentException('$contextKey must not be empty.'); @@ -58,6 +62,7 @@ class ContextListener implements ListenerInterface $this->sessionKey = '_security_'.$contextKey; $this->logger = $logger; $this->dispatcher = $dispatcher; + $this->trustResolver = $trustResolver ?: new AuthenticationTrustResolver(AnonymousToken::class, RememberMeToken::class); } /** @@ -121,7 +126,7 @@ class ContextListener implements ListenerInterface $request = $event->getRequest(); $session = $request->getSession(); - if ((null === $token = $this->tokenStorage->getToken()) || ($token instanceof AnonymousToken)) { + if ((null === $token = $this->tokenStorage->getToken()) || $this->trustResolver->isAnonymous($token)) { if ($request->hasPreviousSession()) { $session->remove($this->sessionKey); } diff --git a/Http/Firewall/ExceptionListener.php b/Http/Firewall/ExceptionListener.php index a1cae2a..98f5ac0 100644 --- a/Http/Firewall/ExceptionListener.php +++ b/Http/Firewall/ExceptionListener.php @@ -22,6 +22,7 @@ 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; @@ -39,6 +40,8 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; */ class ExceptionListener { + use TargetPathTrait; + private $tokenStorage; private $providerKey; private $accessDeniedHandler; @@ -200,7 +203,15 @@ class ExceptionListener } } - return $this->authenticationEntryPoint->start($request, $authException); + $response = $this->authenticationEntryPoint->start($request, $authException); + + if (!$response instanceof 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)); + } + + return $response; } /** @@ -210,7 +221,7 @@ class ExceptionListener { // session isn't required when using HTTP basic authentication mechanism for example if ($request->hasSession() && $request->isMethodSafe() && !$request->isXmlHttpRequest()) { - $request->getSession()->set('_security.'.$this->providerKey.'.target_path', $request->getUri()); + $this->saveTargetPath($request->getSession(), $this->providerKey, $request->getUri()); } } } diff --git a/Http/Firewall/LogoutListener.php b/Http/Firewall/LogoutListener.php index e19d39c..47583be 100644 --- a/Http/Firewall/LogoutListener.php +++ b/Http/Firewall/LogoutListener.php @@ -11,13 +11,10 @@ namespace Symfony\Component\Security\Http\Firewall; -use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderAdapter; -use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Exception\InvalidArgumentException; use Symfony\Component\Security\Core\Exception\LogoutException; use Symfony\Component\Security\Csrf\CsrfToken; use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface; @@ -49,24 +46,8 @@ class LogoutListener implements ListenerInterface * @param array $options An array of options to process a logout attempt * @param CsrfTokenManagerInterface $csrfTokenManager A CsrfTokenManagerInterface instance */ - public function __construct(TokenStorageInterface $tokenStorage, HttpUtils $httpUtils, LogoutSuccessHandlerInterface $successHandler, array $options = array(), $csrfTokenManager = null) + public function __construct(TokenStorageInterface $tokenStorage, HttpUtils $httpUtils, LogoutSuccessHandlerInterface $successHandler, array $options = array(), CsrfTokenManagerInterface $csrfTokenManager = null) { - if ($csrfTokenManager instanceof CsrfProviderInterface) { - $csrfTokenManager = new CsrfProviderAdapter($csrfTokenManager); - } elseif (null !== $csrfTokenManager && !$csrfTokenManager instanceof CsrfTokenManagerInterface) { - throw new InvalidArgumentException('The CSRF token manager should be an instance of CsrfProviderInterface or CsrfTokenManagerInterface.'); - } - - if (isset($options['intention'])) { - if (isset($options['csrf_token_id'])) { - throw new \InvalidArgumentException(sprintf('You should only define an option for one of "intention" or "csrf_token_id" for the "%s". Use the "csrf_token_id" as it replaces "intention".', __CLASS__)); - } - - @trigger_error('The "intention" option for the '.__CLASS__.' is deprecated since version 2.8 and will be removed in 3.0. Use the "csrf_token_id" option instead.', E_USER_DEPRECATED); - - $options['csrf_token_id'] = $options['intention']; - } - $this->tokenStorage = $tokenStorage; $this->httpUtils = $httpUtils; $this->options = array_merge(array( diff --git a/Http/Firewall/SimpleFormAuthenticationListener.php b/Http/Firewall/SimpleFormAuthenticationListener.php index 331d018..7c940c3 100644 --- a/Http/Firewall/SimpleFormAuthenticationListener.php +++ b/Http/Firewall/SimpleFormAuthenticationListener.php @@ -12,17 +12,14 @@ namespace Symfony\Component\Security\Http\Firewall; use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderAdapter; -use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Security\Core\Exception\InvalidArgumentException; use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException; 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\Core\Authentication\SimpleFormAuthenticatorInterface; +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; @@ -57,30 +54,13 @@ class SimpleFormAuthenticationListener extends AbstractAuthenticationListener * @param SimpleFormAuthenticatorInterface $simpleAuthenticator A SimpleFormAuthenticatorInterface instance * * @throws \InvalidArgumentException In case no simple authenticator is provided - * @throws InvalidArgumentException In case an invalid CSRF token manager is passed */ - 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, $csrfTokenManager = null, SimpleFormAuthenticatorInterface $simpleAuthenticator = null) + 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) { if (!$simpleAuthenticator) { throw new \InvalidArgumentException('Missing simple authenticator'); } - if ($csrfTokenManager instanceof CsrfProviderInterface) { - $csrfTokenManager = new CsrfProviderAdapter($csrfTokenManager); - } elseif (null !== $csrfTokenManager && !$csrfTokenManager instanceof CsrfTokenManagerInterface) { - throw new InvalidArgumentException('The CSRF token manager should be an instance of CsrfProviderInterface or CsrfTokenManagerInterface.'); - } - - if (isset($options['intention'])) { - if (isset($options['csrf_token_id'])) { - throw new \InvalidArgumentException(sprintf('You should only define an option for one of "intention" or "csrf_token_id" for the "%s". Use the "csrf_token_id" as it replaces "intention".', __CLASS__)); - } - - @trigger_error('The "intention" option for the '.__CLASS__.' is deprecated since version 2.8 and will be removed in 3.0. Use the "csrf_token_id" option instead.', E_USER_DEPRECATED); - - $options['csrf_token_id'] = $options['intention']; - } - $this->simpleAuthenticator = $simpleAuthenticator; $this->csrfTokenManager = $csrfTokenManager; diff --git a/Http/Firewall/SimplePreAuthenticationListener.php b/Http/Firewall/SimplePreAuthenticationListener.php index 8f1f6fd..2b4b593 100644 --- a/Http/Firewall/SimplePreAuthenticationListener.php +++ b/Http/Firewall/SimplePreAuthenticationListener.php @@ -15,7 +15,7 @@ use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterfac use Psr\Log\LoggerInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Security\Core\Authentication\SimplePreAuthenticatorInterface; +use Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface; use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Exception\AuthenticationException; diff --git a/Http/Firewall/UsernamePasswordFormAuthenticationListener.php b/Http/Firewall/UsernamePasswordFormAuthenticationListener.php index 866d0c3..426457d 100644 --- a/Http/Firewall/UsernamePasswordFormAuthenticationListener.php +++ b/Http/Firewall/UsernamePasswordFormAuthenticationListener.php @@ -11,8 +11,6 @@ namespace Symfony\Component\Security\Http\Firewall; -use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderAdapter; -use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; use Symfony\Component\HttpFoundation\Request; use Psr\Log\LoggerInterface; use Symfony\Component\Security\Csrf\CsrfToken; @@ -26,7 +24,6 @@ use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterfac 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\InvalidArgumentException; use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException; use Symfony\Component\Security\Core\Security; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -41,24 +38,8 @@ 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, $csrfTokenManager = null) + 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) { - if ($csrfTokenManager instanceof CsrfProviderInterface) { - $csrfTokenManager = new CsrfProviderAdapter($csrfTokenManager); - } elseif (null !== $csrfTokenManager && !$csrfTokenManager instanceof CsrfTokenManagerInterface) { - throw new InvalidArgumentException('The CSRF token manager should be an instance of CsrfProviderInterface or CsrfTokenManagerInterface.'); - } - - if (isset($options['intention'])) { - if (isset($options['csrf_token_id'])) { - throw new \InvalidArgumentException(sprintf('You should only define an option for one of "intention" or "csrf_token_id" for the "%s". Use the "csrf_token_id" as it replaces "intention".', __CLASS__)); - } - - @trigger_error('The "intention" option for the '.__CLASS__.' is deprecated since version 2.8 and will be removed in 3.0. Use the "csrf_token_id" option instead.', E_USER_DEPRECATED); - - $options['csrf_token_id'] = $options['intention']; - } - parent::__construct($tokenStorage, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, array_merge(array( 'username_parameter' => '_username', 'password_parameter' => '_password', diff --git a/Http/Logout/LogoutUrlGenerator.php b/Http/Logout/LogoutUrlGenerator.php index 761e56a..ada733b 100644 --- a/Http/Logout/LogoutUrlGenerator.php +++ b/Http/Logout/LogoutUrlGenerator.php @@ -11,8 +11,6 @@ namespace Symfony\Component\Security\Http\Logout; -use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderAdapter; -use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; @@ -47,14 +45,8 @@ class LogoutUrlGenerator * @param string $csrfParameter The CSRF token parameter name * @param CsrfTokenManagerInterface $csrfTokenManager A CsrfTokenManagerInterface instance */ - public function registerListener($key, $logoutPath, $csrfTokenId, $csrfParameter, $csrfTokenManager = null) + public function registerListener($key, $logoutPath, $csrfTokenId, $csrfParameter, CsrfTokenManagerInterface $csrfTokenManager = null) { - if ($csrfTokenManager instanceof CsrfProviderInterface) { - $csrfTokenManager = new CsrfProviderAdapter($csrfTokenManager); - } elseif (null !== $csrfTokenManager && !$csrfTokenManager instanceof CsrfTokenManagerInterface) { - throw new \InvalidArgumentException('The CSRF token manager should be an instance of CsrfProviderInterface or CsrfTokenManagerInterface.'); - } - $this->listeners[$key] = array($logoutPath, $csrfTokenId, $csrfParameter, $csrfTokenManager); } diff --git a/Http/RememberMe/AbstractRememberMeServices.php b/Http/RememberMe/AbstractRememberMeServices.php index 8627bc8..c22105b 100644 --- a/Http/RememberMe/AbstractRememberMeServices.php +++ b/Http/RememberMe/AbstractRememberMeServices.php @@ -85,16 +85,6 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface } /** - * @deprecated Since version 2.8, to be removed in 3.0. Use getSecret() instead. - */ - public function getKey() - { - @trigger_error(__method__.'() is deprecated since version 2.8 and will be removed in 3.0. Use getSecret() instead.', E_USER_DEPRECATED); - - return $this->getSecret(); - } - - /** * @return string */ public function getSecret() diff --git a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php index 807a4a7..edfa208 100644 --- a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php +++ b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php @@ -19,8 +19,6 @@ 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; -use Symfony\Component\Security\Core\Util\SecureRandomInterface; -use Psr\Log\LoggerInterface; /** * Concrete implementation of the RememberMeServicesInterface which needs @@ -34,27 +32,6 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices private $tokenProvider; /** - * Constructor. - * - * Note: The $secureRandom parameter is deprecated since version 2.8 and will be removed in 3.0. - * - * @param array $userProviders - * @param string $secret - * @param string $providerKey - * @param array $options - * @param LoggerInterface $logger - * @param SecureRandomInterface $secureRandom - */ - public function __construct(array $userProviders, $secret, $providerKey, array $options = array(), LoggerInterface $logger = null, SecureRandomInterface $secureRandom = null) - { - if (null !== $secureRandom) { - @trigger_error('The $secureRandom parameter in '.__METHOD__.' is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED); - } - - parent::__construct($userProviders, $secret, $providerKey, $options, $logger); - } - - /** * Sets the token provider. * * @param TokenProviderInterface $tokenProvider diff --git a/Http/SecurityEvents.php b/Http/SecurityEvents.php index 46c8257..550acb4 100644 --- a/Http/SecurityEvents.php +++ b/Http/SecurityEvents.php @@ -17,10 +17,7 @@ final class SecurityEvents * The INTERACTIVE_LOGIN event occurs after a user is logged in * interactively for authentication based on http, cookies or X509. * - * The event listener method receives a - * Symfony\Component\Security\Http\Event\InteractiveLoginEvent instance. - * - * @Event + * @Event("Symfony\Component\Security\Http\Event\InteractiveLoginEvent") * * @var string */ @@ -30,10 +27,7 @@ final class SecurityEvents * The SWITCH_USER event occurs before switch to another user and * before exit from an already switched user. * - * The event listener method receives a - * Symfony\Component\Security\Http\Event\SwitchUserEvent instance. - * - * @Event + * @Event("Symfony\Component\Security\Http\Event\SwitchUserEvent") * * @var string */ diff --git a/Http/Session/SessionAuthenticationStrategy.php b/Http/Session/SessionAuthenticationStrategy.php index ccfa6ba..dd258a0 100644 --- a/Http/Session/SessionAuthenticationStrategy.php +++ b/Http/Session/SessionAuthenticationStrategy.php @@ -47,10 +47,7 @@ class SessionAuthenticationStrategy implements SessionAuthenticationStrategyInte return; case self::MIGRATE: - // Destroying the old session is broken in php 5.4.0 - 5.4.10 - // See php bug #63379 - $destroy = PHP_VERSION_ID < 50400 || PHP_VERSION_ID >= 50411; - $request->getSession()->migrate($destroy); + $request->getSession()->migrate(true); return; diff --git a/Http/Tests/Firewall/ContextListenerTest.php b/Http/Tests/Firewall/ContextListenerTest.php index ae1199a..0213330 100644 --- a/Http/Tests/Firewall/ContextListenerTest.php +++ b/Http/Tests/Firewall/ContextListenerTest.php @@ -18,6 +18,7 @@ use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\Security\Http\Firewall\ContextListener; @@ -85,6 +86,13 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase $this->assertFalse($session->has('_security_session')); } + public function testOnKernelResponseWillRemoveSessionOnAnonymousToken() + { + $session = $this->runSessionOnKernelResponse(new AnonymousToken('secret', 'anon.'), 'C:10:"serialized"'); + + $this->assertFalse($session->has('_security_session')); + } + public function testOnKernelResponseWithoutSession() { $tokenStorage = new TokenStorage(); diff --git a/Http/Tests/Firewall/ExceptionListenerTest.php b/Http/Tests/Firewall/ExceptionListenerTest.php index 3d409e5..db0a242 100644 --- a/Http/Tests/Firewall/ExceptionListenerTest.php +++ b/Http/Tests/Firewall/ExceptionListenerTest.php @@ -65,6 +65,20 @@ class ExceptionListenerTest extends \PHPUnit_Framework_TestCase ); } + public function testExceptionWhenEntryPointReturnsBadValue() + { + $event = $this->createEvent(new AuthenticationException()); + + $entryPoint = $this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface'); + $entryPoint->expects($this->once())->method('start')->will($this->returnValue('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()); + } + /** * @dataProvider getAccessDeniedExceptionProvider */ diff --git a/Http/Tests/Session/SessionAuthenticationStrategyTest.php b/Http/Tests/Session/SessionAuthenticationStrategyTest.php index 4aef4b2..a1f960f 100644 --- a/Http/Tests/Session/SessionAuthenticationStrategyTest.php +++ b/Http/Tests/Session/SessionAuthenticationStrategyTest.php @@ -39,10 +39,6 @@ class SessionAuthenticationStrategyTest extends \PHPUnit_Framework_TestCase public function testSessionIsMigrated() { - if (PHP_VERSION_ID >= 50400 && PHP_VERSION_ID < 50411) { - $this->markTestSkipped('We cannot destroy the old session on PHP 5.4.0 - 5.4.10.'); - } - $session = $this->getMock('Symfony\Component\HttpFoundation\Session\SessionInterface'); $session->expects($this->once())->method('migrate')->with($this->equalTo(true)); @@ -50,19 +46,6 @@ class SessionAuthenticationStrategyTest extends \PHPUnit_Framework_TestCase $strategy->onAuthentication($this->getRequest($session), $this->getToken()); } - public function testSessionIsMigratedWithPhp54Workaround() - { - if (PHP_VERSION_ID < 50400 || PHP_VERSION_ID >= 50411) { - $this->markTestSkipped('This PHP version is not affected.'); - } - - $session = $this->getMock('Symfony\Component\HttpFoundation\Session\SessionInterface'); - $session->expects($this->once())->method('migrate')->with($this->equalTo(false)); - - $strategy = new SessionAuthenticationStrategy(SessionAuthenticationStrategy::MIGRATE); - $strategy->onAuthentication($this->getRequest($session), $this->getToken()); - } - public function testSessionIsInvalidated() { $session = $this->getMock('Symfony\Component\HttpFoundation\Session\SessionInterface'); diff --git a/Http/Tests/Util/TargetPathTraitTest.php b/Http/Tests/Util/TargetPathTraitTest.php new file mode 100644 index 0000000..b2c4dc7 --- /dev/null +++ b/Http/Tests/Util/TargetPathTraitTest.php @@ -0,0 +1,76 @@ +<?php + +namespace Symfony\Component\Security\Http\Tests\Util; + +use Symfony\Component\HttpFoundation\Session\SessionInterface; +use Symfony\Component\Security\Http\Util\TargetPathTrait; + +class TargetPathTraitTest extends \PHPUnit_Framework_TestCase +{ + public function testSetTargetPath() + { + $obj = new TestClassWithTargetPathTrait(); + + $session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface') + ->getMock(); + + $session->expects($this->once()) + ->method('set') + ->with('_security.firewall_name.target_path', '/foo'); + + $obj->doSetTargetPath($session, 'firewall_name', '/foo'); + } + + public function testGetTargetPath() + { + $obj = new TestClassWithTargetPathTrait(); + + $session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface') + ->getMock(); + + $session->expects($this->once()) + ->method('get') + ->with('_security.cool_firewall.target_path') + ->willReturn('/bar'); + + $actualUri = $obj->doGetTargetPath($session, 'cool_firewall'); + $this->assertEquals( + '/bar', + $actualUri + ); + } + + public function testRemoveTargetPath() + { + $obj = new TestClassWithTargetPathTrait(); + + $session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface') + ->getMock(); + + $session->expects($this->once()) + ->method('remove') + ->with('_security.best_firewall.target_path'); + + $obj->doRemoveTargetPath($session, 'best_firewall'); + } +} + +class TestClassWithTargetPathTrait +{ + use TargetPathTrait; + + public function doSetTargetPath(SessionInterface $session, $providerKey, $uri) + { + $this->saveTargetPath($session, $providerKey, $uri); + } + + public function doGetTargetPath(SessionInterface $session, $providerKey) + { + return $this->getTargetPath($session, $providerKey); + } + + public function doRemoveTargetPath(SessionInterface $session, $providerKey) + { + $this->removeTargetPath($session, $providerKey); + } +} diff --git a/Http/Util/TargetPathTrait.php b/Http/Util/TargetPathTrait.php new file mode 100644 index 0000000..986adb0 --- /dev/null +++ b/Http/Util/TargetPathTrait.php @@ -0,0 +1,58 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Http\Util; + +use Symfony\Component\HttpFoundation\Session\SessionInterface; + +/** + * Trait to get (and set) the URL the user last visited before being forced to authenticate. + */ +trait TargetPathTrait +{ + /** + * Sets the target path the user should be redirected to after authentication. + * + * 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 + */ + private function saveTargetPath(SessionInterface $session, $providerKey, $uri) + { + $session->set('_security.'.$providerKey.'.target_path', $uri); + } + + /** + * Returns the URL (if any) the user visited that forced them to login. + * + * @param SessionInterface $session + * @param string $providerKey The name of your firewall + * + * @return string + */ + private function getTargetPath(SessionInterface $session, $providerKey) + { + return $session->get('_security.'.$providerKey.'.target_path'); + } + + /** + * Removes the target path from the session. + * + * @param SessionInterface $session + * @param string $providerKey The name of your firewall + */ + private function removeTargetPath(SessionInterface $session, $providerKey) + { + $session->remove('_security.'.$providerKey.'.target_path'); + } +} diff --git a/Http/composer.json b/Http/composer.json index 24708ac..f19d0e4 100644 --- a/Http/composer.json +++ b/Http/composer.json @@ -16,18 +16,18 @@ } ], "require": { - "php": ">=5.3.9", - "symfony/security-core": "~2.8", - "symfony/event-dispatcher": "~2.1|~3.0.0", - "symfony/http-foundation": "~2.4|~3.0.0", - "symfony/http-kernel": "~2.4|~3.0.0", + "php": ">=5.5.9", + "symfony/security-core": "~2.8|~3.0", + "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/http-foundation": "~2.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0", "symfony/polyfill-php56": "~1.0", "symfony/polyfill-php70": "~1.0", - "symfony/property-access": "~2.3|~3.0.0" + "symfony/property-access": "~2.8|~3.0" }, "require-dev": { - "symfony/routing": "~2.2|~3.0.0", - "symfony/security-csrf": "~2.4|~3.0.0", + "symfony/routing": "~2.8|~3.0", + "symfony/security-csrf": "~2.8|~3.0", "psr/log": "~1.0" }, "suggest": { @@ -43,7 +43,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.1-dev" } } } |