Skip to content

Commit ff4d97b

Browse files
weaverryanfabpot
authored andcommitted
Adding new TargetPathTrait to get/set the authentication "target_path"
1 parent 7835757 commit ff4d97b

File tree

4 files changed

+143
-3
lines changed

4 files changed

+143
-3
lines changed

Authentication/DefaultAuthenticationSuccessHandler.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
1515
use Symfony\Component\HttpFoundation\Request;
16+
use Symfony\Component\Security\Http\Util\TargetPathTrait;
1617
use Symfony\Component\Security\Http\HttpUtils;
1718
use Symfony\Component\Security\Http\ParameterBagUtils;
1819

@@ -25,6 +26,8 @@
2526
*/
2627
class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface
2728
{
29+
use TargetPathTrait;
30+
2831
protected $httpUtils;
2932
protected $options;
3033
protected $providerKey;
@@ -113,8 +116,8 @@ protected function determineTargetUrl(Request $request)
113116
return $targetUrl;
114117
}
115118

116-
if (null !== $this->providerKey && $targetUrl = $request->getSession()->get('_security.'.$this->providerKey.'.target_path')) {
117-
$request->getSession()->remove('_security.'.$this->providerKey.'.target_path');
119+
if (null !== $this->providerKey && $targetUrl = $this->getTargetPath($request->getSession(), $this->providerKey)) {
120+
$this->removeTargetPath($request->getSession(), $this->providerKey);
118121

119122
return $targetUrl;
120123
}

Firewall/ExceptionListener.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
2323
use Symfony\Component\Security\Core\Exception\InsufficientAuthenticationException;
2424
use Symfony\Component\Security\Core\Exception\LogoutException;
25+
use Symfony\Component\Security\Http\Util\TargetPathTrait;
2526
use Symfony\Component\Security\Http\HttpUtils;
2627
use Symfony\Component\HttpFoundation\Request;
2728
use Psr\Log\LoggerInterface;
@@ -39,6 +40,8 @@
3940
*/
4041
class ExceptionListener
4142
{
43+
use TargetPathTrait;
44+
4245
private $tokenStorage;
4346
private $providerKey;
4447
private $accessDeniedHandler;
@@ -210,7 +213,7 @@ protected function setTargetPath(Request $request)
210213
{
211214
// session isn't required when using HTTP basic authentication mechanism for example
212215
if ($request->hasSession() && $request->isMethodSafe() && !$request->isXmlHttpRequest()) {
213-
$request->getSession()->set('_security.'.$this->providerKey.'.target_path', $request->getUri());
216+
$this->saveTargetPath($request->getSession(), $this->providerKey, $request->getUri());
214217
}
215218
}
216219
}

Tests/Util/TargetPathTraitTest.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
namespace Symfony\Component\Security\Http\Tests\Util;
4+
5+
use Symfony\Component\HttpFoundation\Session\SessionInterface;
6+
use Symfony\Component\Security\Http\Util\TargetPathTrait;
7+
8+
class TargetPathTraitTest extends \PHPUnit_Framework_TestCase
9+
{
10+
public function testSetTargetPath()
11+
{
12+
$obj = new TestClassWithTargetPathTrait();
13+
14+
$session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')
15+
->getMock();
16+
17+
$session->expects($this->once())
18+
->method('set')
19+
->with('_security.firewall_name.target_path', '/foo');
20+
21+
$obj->doSetTargetPath($session, 'firewall_name', '/foo');
22+
}
23+
24+
public function testGetTargetPath()
25+
{
26+
$obj = new TestClassWithTargetPathTrait();
27+
28+
$session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')
29+
->getMock();
30+
31+
$session->expects($this->once())
32+
->method('get')
33+
->with('_security.cool_firewall.target_path')
34+
->willReturn('/bar');
35+
36+
$actualUri = $obj->doGetTargetPath($session, 'cool_firewall');
37+
$this->assertEquals(
38+
'/bar',
39+
$actualUri
40+
);
41+
}
42+
43+
public function testRemoveTargetPath()
44+
{
45+
$obj = new TestClassWithTargetPathTrait();
46+
47+
$session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')
48+
->getMock();
49+
50+
$session->expects($this->once())
51+
->method('remove')
52+
->with('_security.best_firewall.target_path');
53+
54+
$obj->doRemoveTargetPath($session, 'best_firewall');
55+
}
56+
}
57+
58+
class TestClassWithTargetPathTrait
59+
{
60+
use TargetPathTrait;
61+
62+
public function doSetTargetPath(SessionInterface $session, $providerKey, $uri)
63+
{
64+
$this->saveTargetPath($session, $providerKey, $uri);
65+
}
66+
67+
public function doGetTargetPath(SessionInterface $session, $providerKey)
68+
{
69+
return $this->getTargetPath($session, $providerKey);
70+
}
71+
72+
public function doRemoveTargetPath(SessionInterface $session, $providerKey)
73+
{
74+
$this->removeTargetPath($session, $providerKey);
75+
}
76+
}

Util/TargetPathTrait.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Http\Util;
13+
14+
use Symfony\Component\HttpFoundation\Session\SessionInterface;
15+
16+
/**
17+
* Trait to get (and set) the URL the user last visited before being forced to authenticate.
18+
*/
19+
trait TargetPathTrait
20+
{
21+
/**
22+
* Set the target path the user should be redirected to after authentication.
23+
*
24+
* Usually, you do not need to set this directly.
25+
*
26+
* @param SessionInterface $session
27+
* @param string $providerKey The name of your firewall
28+
* @param string $uri The URI to set as the target path
29+
*/
30+
private function saveTargetPath(SessionInterface $session, $providerKey, $uri)
31+
{
32+
$session->set('_security.'.$providerKey.'.target_path', $uri);
33+
}
34+
35+
/**
36+
* Returns the URL (if any) the user visited that forced them to login.
37+
*
38+
* @param SessionInterface $session
39+
* @param string $providerKey The name of your firewall
40+
*
41+
* @return string
42+
*/
43+
private function getTargetPath(SessionInterface $session, $providerKey)
44+
{
45+
return $session->get('_security.'.$providerKey.'.target_path');
46+
}
47+
48+
/**
49+
* Removes the target path from the session.
50+
*
51+
* @param SessionInterface $session
52+
* @param string $providerKey The name of your firewall
53+
*/
54+
private function removeTargetPath(SessionInterface $session, $providerKey)
55+
{
56+
$session->remove('_security.'.$providerKey.'.target_path');
57+
}
58+
}

0 commit comments

Comments
 (0)