diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php index 00adb6f1c611..6466cc37a64f 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php @@ -25,6 +25,7 @@ class RememberMeFactory implements SecurityFactoryInterface 'domain' => null, 'secure' => false, 'httponly' => true, + 'samesite' => null, 'always_remember_me' => false, 'remember_me_parameter' => '_remember_me', ); diff --git a/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeServices.php b/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeServices.php index 64ea8352ac3b..bc287098535c 100644 --- a/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeServices.php +++ b/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeServices.php @@ -271,7 +271,7 @@ protected function cancelCookie(Request $request) $this->logger->debug('Clearing remember-me cookie.', array('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'] ?? null)); } /** diff --git a/src/Symfony/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServices.php b/src/Symfony/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServices.php index d18c35616481..ff6305f45482 100644 --- a/src/Symfony/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServices.php +++ b/src/Symfony/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServices.php @@ -84,7 +84,9 @@ protected function processAutoLoginCookie(array $cookieParts, Request $request) $this->options['path'], $this->options['domain'], $this->options['secure'], - $this->options['httponly'] + $this->options['httponly'], + false, + $this->options['samesite'] ?? null ) ); @@ -117,7 +119,9 @@ protected function onLoginSuccess(Request $request, Response $response, TokenInt $this->options['path'], $this->options['domain'], $this->options['secure'], - $this->options['httponly'] + $this->options['httponly'], + false, + $this->options['samesite'] ?? null ) ); } diff --git a/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php b/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php index d6254dff0a2a..ab5aba9444f1 100644 --- a/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php +++ b/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php @@ -81,7 +81,9 @@ protected function onLoginSuccess(Request $request, Response $response, TokenInt $this->options['path'], $this->options['domain'], $this->options['secure'], - $this->options['httponly'] + $this->options['httponly'], + false, + $this->options['samesite'] ?? null ) ); } diff --git a/src/Symfony/Component/Security/Http/Tests/RememberMe/PersistentTokenBasedRememberMeServicesTest.php b/src/Symfony/Component/Security/Http/Tests/RememberMe/PersistentTokenBasedRememberMeServicesTest.php index b35215229f56..b8d113c8cca0 100644 --- a/src/Symfony/Component/Security/Http/Tests/RememberMe/PersistentTokenBasedRememberMeServicesTest.php +++ b/src/Symfony/Component/Security/Http/Tests/RememberMe/PersistentTokenBasedRememberMeServicesTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Security\Http\Tests\RememberMe; use PHPUnit\Framework\TestCase; +use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken; @@ -268,7 +269,7 @@ public function testLoginFail() 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, array('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(); @@ -305,6 +306,7 @@ public function testLoginSuccessSetsCookieWhenLoggedInWithNonRememberMeTokenInte $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) diff --git a/src/Symfony/Component/Security/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php b/src/Symfony/Component/Security/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php index 7405519964cd..b687a816f43a 100644 --- a/src/Symfony/Component/Security/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php +++ b/src/Symfony/Component/Security/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Security\Http\Tests\RememberMe; use PHPUnit\Framework\TestCase; +use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; use Symfony\Component\HttpFoundation\Request; @@ -205,7 +206,7 @@ public function testLoginSuccessIgnoresTokensWhichDoNotContainAnUserInterfaceImp 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, array('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(); @@ -240,6 +241,7 @@ public function testLoginSuccess() $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)