Merge branch '2.3' into 2.5
* 2.3: adapted previous commit for 2.3 [Security] Don't send remember cookie for sub request [HttpKernel] Fix UriSigner::check when _hash is not at the end of the uri Conflicts: src/Symfony/Component/Security/Http/Tests/RememberMe/ResponseListenerTest.php
This commit is contained in:
commit
b1819d4498
@ -33,5 +33,7 @@ class UriSignerTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertTrue($signer->check($signer->sign('http://example.com/foo')));
|
||||
$this->assertTrue($signer->check($signer->sign('http://example.com/foo?foo=bar')));
|
||||
|
||||
$this->assertTrue($signer->sign('http://example.com/foo?foo=bar&bar=foo') === $signer->sign('http://example.com/foo?bar=foo&foo=bar'));
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,15 @@ class UriSigner
|
||||
*/
|
||||
public function sign($uri)
|
||||
{
|
||||
$url = parse_url($uri);
|
||||
if (isset($url['query'])) {
|
||||
parse_str($url['query'], $params);
|
||||
} else {
|
||||
$params = array();
|
||||
}
|
||||
|
||||
$uri = $this->buildUrl($url, $params);
|
||||
|
||||
return $uri.(false === (strpos($uri, '?')) ? '?' : '&').'_hash='.$this->computeHash($uri);
|
||||
}
|
||||
|
||||
@ -58,15 +67,43 @@ class UriSigner
|
||||
*/
|
||||
public function check($uri)
|
||||
{
|
||||
if (!preg_match('/^(.*)(?:\?|&)_hash=(.+?)$/', $uri, $matches)) {
|
||||
$url = parse_url($uri);
|
||||
if (isset($url['query'])) {
|
||||
parse_str($url['query'], $params);
|
||||
} else {
|
||||
$params = array();
|
||||
}
|
||||
|
||||
if (empty($params['_hash'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->computeHash($matches[1]) === $matches[2];
|
||||
$hash = urlencode($params['_hash']);
|
||||
unset($params['_hash']);
|
||||
|
||||
return $this->computeHash($this->buildUrl($url, $params)) === $hash;
|
||||
}
|
||||
|
||||
private function computeHash($uri)
|
||||
{
|
||||
return urlencode(base64_encode(hash_hmac('sha256', $uri, $this->secret, true)));
|
||||
}
|
||||
|
||||
private function buildUrl(array $url, array $params = array())
|
||||
{
|
||||
ksort($params);
|
||||
$url['query'] = http_build_query($params);
|
||||
|
||||
$scheme = isset($url['scheme']) ? $url['scheme'].'://' : '';
|
||||
$host = isset($url['host']) ? $url['host'] : '';
|
||||
$port = isset($url['port']) ? ':'.$url['port'] : '';
|
||||
$user = isset($url['user']) ? $url['user'] : '';
|
||||
$pass = isset($url['pass']) ? ':'.$url['pass'] : '';
|
||||
$pass = ($user || $pass) ? "$pass@" : '';
|
||||
$path = isset($url['path']) ? $url['path'] : '';
|
||||
$query = isset($url['query']) && $url['query'] ? '?'.$url['query'] : '';
|
||||
$fragment = isset($url['fragment']) ? '#'.$url['fragment'] : '';
|
||||
|
||||
return $scheme.$user.$pass.$host.$port.$path.$query.$fragment;
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Security\Http\RememberMe;
|
||||
|
||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
@ -27,6 +28,10 @@ class ResponseListener implements EventSubscriberInterface
|
||||
*/
|
||||
public function onKernelResponse(FilterResponseEvent $event)
|
||||
{
|
||||
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$request = $event->getRequest();
|
||||
$response = $event->getResponse();
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\Security\Http\Tests\RememberMe;
|
||||
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\Security\Http\RememberMe\ResponseListener;
|
||||
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@ -34,6 +35,21 @@ class ResponseListenerTest extends \PHPUnit_Framework_TestCase
|
||||
$listener->onKernelResponse($this->getEvent($request, $response));
|
||||
}
|
||||
|
||||
public function testRememberMeCookieIsNotSendWithResponseForSubRequests()
|
||||
{
|
||||
$cookie = new Cookie('rememberme');
|
||||
|
||||
$request = $this->getRequest(array(
|
||||
RememberMeServicesInterface::COOKIE_ATTR_NAME => $cookie,
|
||||
));
|
||||
|
||||
$response = $this->getResponse();
|
||||
$response->headers->expects($this->never())->method('setCookie');
|
||||
|
||||
$listener = new ResponseListener();
|
||||
$listener->onKernelResponse($this->getEvent($request, $response, HttpKernelInterface::SUB_REQUEST));
|
||||
}
|
||||
|
||||
public function testRememberMeCookieIsNotSendWithResponse()
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
@ -71,13 +87,14 @@ class ResponseListenerTest extends \PHPUnit_Framework_TestCase
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function getEvent($request, $response)
|
||||
private function getEvent($request, $response, $type = HttpKernelInterface::MASTER_REQUEST)
|
||||
{
|
||||
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\FilterResponseEvent')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$event->expects($this->any())->method('getRequest')->will($this->returnValue($request));
|
||||
$event->expects($this->any())->method('getRequestType')->will($this->returnValue($type));
|
||||
$event->expects($this->any())->method('getResponse')->will($this->returnValue($response));
|
||||
|
||||
return $event;
|
||||
|
Reference in New Issue
Block a user