bug #40231 [HttpKernel] Configure `session.cookie_secure` earlier (tamcy)

This PR was merged into the 4.4 branch.

Discussion
----------

[HttpKernel] Configure `session.cookie_secure` earlier

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #40221
| License       | MIT
| Doc PR        | N/A

This PR does what @stof had suggested in #40221, allow me to quote him directly:

> 1. avoid setting auto as a value for the ini setting in the NativeSessionStorage initialization
> 2. ensuring that SessionListener resolves the auto value by the time the SessionListener runs, and not by the time the getSession() method is called in the Request session factory callback

Commits
-------

e82918cd60 [HttpKernel] Configure `session.cookie_secure` earlier
This commit is contained in:
Nicolas Grekas 2021-02-25 18:12:57 +01:00
commit 87aeb8da13
3 changed files with 22 additions and 5 deletions

View File

@ -389,6 +389,9 @@ class NativeSessionStorage implements SessionStorageInterface
$this->emulateSameSite = $value;
continue;
}
if ('cookie_secure' === $key && 'auto' === $value) {
continue;
}
ini_set('url_rewriter.tags' !== $key ? 'session.'.$key : $key, $value);
}
}

View File

@ -14,6 +14,7 @@ namespace Symfony\Component\HttpKernel\EventListener;
use Psr\Container\ContainerInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
/**
* Sets the session in the request.
@ -33,10 +34,12 @@ class SessionListener extends AbstractSessionListener
$this->container = $container;
}
protected function getSession(): ?SessionInterface
public function onKernelRequest(GetResponseEvent $event)
{
if (!$this->container->has('session')) {
return null;
parent::onKernelRequest($event);
if (!$event->isMasterRequest() || !$this->container->has('session')) {
return;
}
if ($this->container->has('session_storage')
@ -46,6 +49,13 @@ class SessionListener extends AbstractSessionListener
) {
$storage->setOptions(['cookie_secure' => true]);
}
}
protected function getSession(): ?SessionInterface
{
if (!$this->container->has('session')) {
return null;
}
return $this->container->get('session');
}

View File

@ -59,7 +59,7 @@ class SessionListenerTest extends TestCase
$listener = new SessionListener($container);
$event = $this->createMock(RequestEvent::class);
$event->expects($this->once())->method('isMasterRequest')->willReturn(true);
$event->expects($this->exactly(2))->method('isMasterRequest')->willReturn(true);
$event->expects($this->once())->method('getRequest')->willReturn($request);
$listener->onKernelRequest($event);
@ -203,12 +203,16 @@ class SessionListenerTest extends TestCase
$listener = new SessionListener($container);
$listener->onKernelRequest($event);
// storage->setOptions() should have been called already
$container->set('session_storage', null);
$sessionStorage = null;
$subRequest = $masterRequest->duplicate();
// at this point both master and subrequest have a closure to build the session
$masterRequest->getSession();
// calling the factory on the subRequest should not trigger a second call to storage->sesOptions()
// calling the factory on the subRequest should not trigger a second call to storage->setOptions()
$subRequest->getSession();
}
}