Skip to content

Commit 9b2acc0

Browse files
committed
Rework firewall access denied rule
1 parent 91c5b14 commit 9b2acc0

File tree

2 files changed

+97
-12
lines changed

2 files changed

+97
-12
lines changed

src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,6 @@ private function handleAccessDeniedException(GetResponseForExceptionEvent $event
131131
} catch (\Exception $e) {
132132
$event->setException($e);
133133
}
134-
135-
return;
136134
}
137135

138136
if (null !== $this->logger) {
@@ -150,7 +148,7 @@ private function handleAccessDeniedException(GetResponseForExceptionEvent $event
150148
$subRequest = $this->httpUtils->createRequest($event->getRequest(), $this->errorPage);
151149
$subRequest->attributes->set(Security::ACCESS_DENIED_ERROR, $exception);
152150

153-
$event->setResponse($event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true));
151+
$event->setResponse($event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST));
154152
$event->allowCustomResponseCode();
155153
}
156154
} catch (\Exception $e) {

src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php

Lines changed: 96 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,15 @@ public function testAccessDeniedExceptionFullFledgedAndWithAccessDeniedHandlerAn
130130
{
131131
$event = $this->createEvent($exception);
132132

133-
$accessDeniedHandler = $this->getMockBuilder('Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface')->getMock();
134-
$accessDeniedHandler->expects($this->once())->method('handle')->will($this->returnValue(new Response('error')));
133+
$listener = $this->createExceptionListener(
134+
null,
135+
$this->createTrustResolver(true),
136+
null,
137+
null,
138+
null,
139+
$this->createCustomAccessDeniedHandler(new Response('error'))
140+
);
135141

136-
$listener = $this->createExceptionListener(null, $this->createTrustResolver(true), null, null, null, $accessDeniedHandler);
137142
$listener->onKernelException($event);
138143

139144
$this->assertEquals('error', $event->getResponse()->getContent());
@@ -147,16 +152,70 @@ public function testAccessDeniedExceptionNotFullFledged(\Exception $exception, \
147152
{
148153
$event = $this->createEvent($exception);
149154

150-
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
151-
$tokenStorage->expects($this->once())->method('getToken')->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock()));
152-
153-
$listener = $this->createExceptionListener($tokenStorage, $this->createTrustResolver(false), null, $this->createEntryPoint());
155+
$listener = $this->createExceptionListener(
156+
$this->createTokenStorage(),
157+
$this->createTrustResolver(false),
158+
null,
159+
$this->createEntryPoint()
160+
);
154161
$listener->onKernelException($event);
155162

156163
$this->assertEquals('OK', $event->getResponse()->getContent());
157164
$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
158165
}
159166

167+
/**
168+
* @dataProvider getAccessDeniedExceptionProvider
169+
*/
170+
public function testAccessDeniedExceptionNotFullFledgedAndWithAccessDeniedHandlerAndWithoutErrorPage(\Exception $exception, \Exception $eventException = null)
171+
{
172+
$event = $this->createEvent($exception);
173+
174+
$listener = $this->createExceptionListener(
175+
$this->createTokenStorage(),
176+
$this->createTrustResolver(false),
177+
null,
178+
$this->createEntryPoint(),
179+
null,
180+
$this->createCustomAccessDeniedHandler(new Response('denied', 403))
181+
);
182+
$listener->onKernelException($event);
183+
184+
$this->assertEquals('denied', $event->getResponse()->getContent());
185+
$this->assertEquals(403, $event->getResponse()->getStatusCode());
186+
$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
187+
}
188+
189+
190+
/**
191+
* @dataProvider getAccessDeniedExceptionProvider
192+
*/
193+
public function testAccessDeniedExceptionNotFullFledgedAndWithoutAccessDeniedHandlerAndWithErrorPage(\Exception $exception, \Exception $eventException = null)
194+
{
195+
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
196+
$kernel->expects($this->once())->method('handle')->will($this->returnValue(new Response('Unauthorized', 401)));
197+
198+
$event = $this->createEvent($exception, $kernel);
199+
200+
$httpUtils = $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')->getMock();
201+
$httpUtils->expects($this->once())->method('createRequest')->will($this->returnValue(Request::create('/error')));
202+
203+
$listener = $this->createExceptionListener(
204+
$this->createTokenStorage(),
205+
$this->createTrustResolver(true),
206+
$httpUtils,
207+
null,
208+
'/error'
209+
);
210+
$listener->onKernelException($event);
211+
212+
$this->assertTrue($event->isAllowingCustomResponseCode());
213+
214+
$this->assertEquals('Unauthorized', $event->getResponse()->getContent());
215+
$this->assertEquals(401, $event->getResponse()->getStatusCode());
216+
$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
217+
}
218+
160219
public function getAccessDeniedExceptionProvider()
161220
{
162221
return [
@@ -168,6 +227,28 @@ public function getAccessDeniedExceptionProvider()
168227
];
169228
}
170229

230+
private function createTokenStorage()
231+
{
232+
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
233+
$tokenStorage
234+
->expects($this->once())
235+
->method('getToken')
236+
->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock()));
237+
238+
return $tokenStorage;
239+
}
240+
241+
private function createCustomAccessDeniedHandler(Response $response)
242+
{
243+
$accessDeniedHandler = $this->getMockBuilder('Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface')->getMock();
244+
$accessDeniedHandler
245+
->expects($this->once())
246+
->method('handle')
247+
->will($this->returnValue($response));
248+
249+
return $accessDeniedHandler;
250+
}
251+
171252
private function createEntryPoint(Response $response = null)
172253
{
173254
$entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
@@ -193,8 +274,14 @@ private function createEvent(\Exception $exception, $kernel = null)
193274
return new GetResponseForExceptionEvent($kernel, Request::create('/'), HttpKernelInterface::MASTER_REQUEST, $exception);
194275
}
195276

196-
private function createExceptionListener(TokenStorageInterface $tokenStorage = null, AuthenticationTrustResolverInterface $trustResolver = null, HttpUtils $httpUtils = null, AuthenticationEntryPointInterface $authenticationEntryPoint = null, $errorPage = null, AccessDeniedHandlerInterface $accessDeniedHandler = null)
197-
{
277+
private function createExceptionListener(
278+
TokenStorageInterface $tokenStorage = null,
279+
AuthenticationTrustResolverInterface $trustResolver = null,
280+
HttpUtils $httpUtils = null,
281+
AuthenticationEntryPointInterface $authenticationEntryPoint = null,
282+
$errorPage = null,
283+
AccessDeniedHandlerInterface $accessDeniedHandler = null
284+
) {
198285
return new ExceptionListener(
199286
$tokenStorage ?: $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(),
200287
$trustResolver ?: $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface')->getMock(),

0 commit comments

Comments
 (0)