Skip to content

Commit 9073c94

Browse files
committed
Rework firewall access denied rule
1 parent 91c5b14 commit 9073c94

File tree

2 files changed

+96
-12
lines changed

2 files changed

+96
-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: 95 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,69 @@ 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+
* @dataProvider getAccessDeniedExceptionProvider
191+
*/
192+
public function testAccessDeniedExceptionNotFullFledgedAndWithoutAccessDeniedHandlerAndWithErrorPage(\Exception $exception, \Exception $eventException = null)
193+
{
194+
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
195+
$kernel->expects($this->once())->method('handle')->will($this->returnValue(new Response('Unauthorized', 401)));
196+
197+
$event = $this->createEvent($exception, $kernel);
198+
199+
$httpUtils = $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')->getMock();
200+
$httpUtils->expects($this->once())->method('createRequest')->will($this->returnValue(Request::create('/error')));
201+
202+
$listener = $this->createExceptionListener(
203+
$this->createTokenStorage(),
204+
$this->createTrustResolver(true),
205+
$httpUtils,
206+
null,
207+
'/error'
208+
);
209+
$listener->onKernelException($event);
210+
211+
$this->assertTrue($event->isAllowingCustomResponseCode());
212+
213+
$this->assertEquals('Unauthorized', $event->getResponse()->getContent());
214+
$this->assertEquals(401, $event->getResponse()->getStatusCode());
215+
$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
216+
}
217+
160218
public function getAccessDeniedExceptionProvider()
161219
{
162220
return [
@@ -168,6 +226,28 @@ public function getAccessDeniedExceptionProvider()
168226
];
169227
}
170228

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

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

0 commit comments

Comments
 (0)