Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c06f322

Browse filesBrowse files
weaverryanfabpot
authored andcommitted
Avoiding session migration for stateless firewall UsernamePasswordJsonAuthenticationListener
1 parent 9586c43 commit c06f322
Copy full SHA for c06f322

File tree

6 files changed

+63
-5
lines changed
Filter options

6 files changed

+63
-5
lines changed

‎src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/JsonLoginFactory.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/JsonLoginFactory.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ protected function createListener($container, $id, $config, $userProvider)
8989
$listener->replaceArgument(4, isset($config['success_handler']) ? new Reference($this->createAuthenticationSuccessHandler($container, $id, $config)) : null);
9090
$listener->replaceArgument(5, isset($config['failure_handler']) ? new Reference($this->createAuthenticationFailureHandler($container, $id, $config)) : null);
9191
$listener->replaceArgument(6, array_intersect_key($config, $this->options));
92+
$listener->addMethodCall('setSessionAuthenticationStrategy', array(new Reference('security.authentication.session_strategy.'.$id)));
9293

9394
$listenerId .= '.'.$id;
9495
$container->setDefinition($listenerId, $listener);

‎src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,11 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
377377

378378
$this->logoutOnUserChangeByContextKey[$contextKey] = array($id, $logoutOnUserChange);
379379
$listeners[] = new Reference($this->createContextListener($container, $contextKey, $logoutOnUserChange));
380+
$sessionStrategyId = 'security.authentication.session_strategy';
381+
} else {
382+
$sessionStrategyId = 'security.authentication.session_strategy_noop';
380383
}
384+
$container->setAlias(new Alias('security.authentication.session_strategy.'.$id, false), $sessionStrategyId);
381385

382386
$config->replaceArgument(6, $contextKey);
383387

‎src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@
6262
<service id="security.authentication.session_strategy" class="Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy">
6363
<argument>%security.authentication.session_strategy.strategy%</argument>
6464
</service>
65+
<service id="security.authentication.session_strategy_noop" class="Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy" public="false">
66+
<argument>none</argument>
67+
</service>
6568
<service id="Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface" alias="security.authentication.session_strategy" />
6669

6770
<service id="security.encoder_factory.generic" class="Symfony\Component\Security\Core\Encoder\EncoderFactory">

‎src/Symfony/Bundle/SecurityBundle/composer.json

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/composer.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"require": {
1919
"php": "^5.5.9|>=7.0.8",
2020
"ext-xml": "*",
21-
"symfony/security": "~3.4.11|^4.0.11",
21+
"symfony/security": "~3.4.12|^4.0.12|^4.1.1",
2222
"symfony/dependency-injection": "^3.4.3|^4.0.3",
2323
"symfony/http-kernel": "~3.4|~4.0",
2424
"symfony/polyfill-php70": "~1.0"

‎src/Symfony/Component/Security/Http/Firewall/UsernamePasswordJsonAuthenticationListener.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/Firewall/UsernamePasswordJsonAuthenticationListener.php
+16-4Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
3434
use Symfony\Component\Security\Http\HttpUtils;
3535
use Symfony\Component\Security\Http\SecurityEvents;
36+
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
3637

3738
/**
3839
* UsernamePasswordJsonAuthenticationListener is a stateless implementation of
@@ -52,6 +53,7 @@ class UsernamePasswordJsonAuthenticationListener implements ListenerInterface
5253
private $logger;
5354
private $eventDispatcher;
5455
private $propertyAccessor;
56+
private $sessionStrategy;
5557

5658
public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler = null, AuthenticationFailureHandlerInterface $failureHandler = null, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $eventDispatcher = null, PropertyAccessorInterface $propertyAccessor = null)
5759
{
@@ -139,7 +141,7 @@ private function onSuccess(Request $request, TokenInterface $token)
139141
$this->logger->info('User has been authenticated successfully.', array('username' => $token->getUsername()));
140142
}
141143

142-
$this->migrateSession($request);
144+
$this->migrateSession($request, $token);
143145

144146
$this->tokenStorage->setToken($token);
145147

@@ -185,11 +187,21 @@ private function onFailure(Request $request, AuthenticationException $failed)
185187
return $response;
186188
}
187189

188-
private function migrateSession(Request $request)
190+
/**
191+
* Call this method if your authentication token is stored to a session.
192+
*
193+
* @final since version 3.4
194+
*/
195+
public function setSessionAuthenticationStrategy(SessionAuthenticationStrategyInterface $sessionStrategy)
196+
{
197+
$this->sessionStrategy = $sessionStrategy;
198+
}
199+
200+
private function migrateSession(Request $request, TokenInterface $token)
189201
{
190-
if (!$request->hasSession() || !$request->hasPreviousSession()) {
202+
if (!$this->sessionStrategy || !$request->hasSession() || !$request->hasPreviousSession()) {
191203
return;
192204
}
193-
$request->getSession()->migrate(true);
205+
$this->sessionStrategy->onAuthentication($request, $token);
194206
}
195207
}

‎src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordJsonAuthenticationListenerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordJsonAuthenticationListenerTest.php
+38Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,42 @@ public function testAttemptAuthenticationIfRequestPathMatchesCheckPath()
212212
$this->listener->handle($event);
213213
$this->assertSame('ok', $event->getResponse()->getContent());
214214
}
215+
216+
public function testNoErrorOnMissingSessionStrategy()
217+
{
218+
$this->createListener();
219+
$request = new Request(array(), array(), array(), array(), array(), array('HTTP_CONTENT_TYPE' => 'application/json'), '{"username": "dunglas", "password": "foo"}');
220+
$this->configurePreviousSession($request);
221+
$event = new GetResponseEvent($this->getMockBuilder(KernelInterface::class)->getMock(), $request, KernelInterface::MASTER_REQUEST);
222+
223+
$this->listener->handle($event);
224+
$this->assertEquals('ok', $event->getResponse()->getContent());
225+
}
226+
227+
public function testMigratesViaSessionStrategy()
228+
{
229+
$this->createListener();
230+
$request = new Request(array(), array(), array(), array(), array(), array('HTTP_CONTENT_TYPE' => 'application/json'), '{"username": "dunglas", "password": "foo"}');
231+
$this->configurePreviousSession($request);
232+
$event = new GetResponseEvent($this->getMockBuilder(KernelInterface::class)->getMock(), $request, KernelInterface::MASTER_REQUEST);
233+
234+
$sessionStrategy = $this->getMockBuilder('Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface')->getMock();
235+
$sessionStrategy->expects($this->once())
236+
->method('onAuthentication')
237+
->with($request, $this->isInstanceOf(TokenInterface::class));
238+
$this->listener->setSessionAuthenticationStrategy($sessionStrategy);
239+
240+
$this->listener->handle($event);
241+
$this->assertEquals('ok', $event->getResponse()->getContent());
242+
}
243+
244+
private function configurePreviousSession(Request $request)
245+
{
246+
$session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock();
247+
$session->expects($this->any())
248+
->method('getName')
249+
->willReturn('test_session_name');
250+
$request->setSession($session);
251+
$request->cookies->set('test_session_name', 'session_cookie_val');
252+
}
215253
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.