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

[Security] Fix ExceptionListener to catch correctly AccessDeniedException if is not first exception #9823

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 68 additions & 52 deletions 120 src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,79 +83,95 @@ public function onKernelException(GetResponseForExceptionEvent $event)
$exception = $event->getException();
$request = $event->getRequest();

// determine the actual cause for the exception
while (null !== $previous = $exception->getPrevious()) {
$exception = $previous;
}

if ($exception instanceof AuthenticationException) {
if (null !== $this->logger) {
$this->logger->info(sprintf('Authentication exception occurred; redirecting to authentication entry point (%s)', $exception->getMessage()));
}

try {
$response = $this->startAuthentication($request, $exception);
} catch (\Exception $e) {
$event->setException($e);

return;
}
} elseif ($exception instanceof AccessDeniedException) {
$event->setException(new AccessDeniedHttpException($exception->getMessage(), $exception));

$token = $this->context->getToken();
if (!$this->authenticationTrustResolver->isFullFledged($token)) {
while (null !== $exception) {
if ($exception instanceof AuthenticationException) {
if (null !== $this->logger) {
$this->logger->debug(sprintf('Access is denied (user is not fully authenticated) by "%s" at line %s; redirecting to authentication entry point', $exception->getFile(), $exception->getLine()));
$this->logger->info(sprintf('Authentication exception occurred; redirecting to authentication entry point (%s)', $exception->getMessage()));
}

try {
$insufficientAuthenticationException = new InsufficientAuthenticationException('Full authentication is required to access this resource.', 0, $exception);
$insufficientAuthenticationException->setToken($token);
$response = $this->startAuthentication($request, $insufficientAuthenticationException);
$response = $this->startAuthentication($request, $exception);

break;
} catch (\Exception $e) {
$event->setException($e);

return;
}
} else {
if (null !== $this->logger) {
$this->logger->debug(sprintf('Access is denied (and user is neither anonymous, nor remember-me) by "%s" at line %s', $exception->getFile(), $exception->getLine()));
}
}

if ($exception instanceof AccessDeniedException) {
$event->setException(new AccessDeniedHttpException($exception->getMessage(), $exception));

try {
if (null !== $this->accessDeniedHandler) {
$response = $this->accessDeniedHandler->handle($request, $exception);
$token = $this->context->getToken();
if (!$this->authenticationTrustResolver->isFullFledged($token)) {
if (null !== $this->logger) {
$this->logger->debug(sprintf('Access is denied (user is not fully authenticated) by "%s" at line %s; redirecting to authentication entry point', $exception->getFile(), $exception->getLine()));
}

if (!$response instanceof Response) {
return;
}
} elseif (null !== $this->errorPage) {
$subRequest = $this->httpUtils->createRequest($request, $this->errorPage);
$subRequest->attributes->set(SecurityContextInterface::ACCESS_DENIED_ERROR, $exception);
try {
$insufficientAuthenticationException = new InsufficientAuthenticationException('Full authentication is required to access this resource.', 0, $exception);
$insufficientAuthenticationException->setToken($token);
$response = $this->startAuthentication($request, $insufficientAuthenticationException);

break;
} catch (\Exception $e) {
$event->setException($e);

$response = $event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);
} else {
return;
}
} catch (\Exception $e) {
} else {
if (null !== $this->logger) {
$this->logger->error(sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $e->getMessage()));
$this->logger->debug(sprintf('Access is denied (and user is neither anonymous, nor remember-me) by "%s" at line %s', $exception->getFile(), $exception->getLine()));
}

$event->setException(new \RuntimeException('Exception thrown when handling an exception.', 0, $e));
try {
if (null !== $this->accessDeniedHandler) {
$response = $this->accessDeniedHandler->handle($request, $exception);

return;
if (!$response instanceof Response) {
return;
}

break;
}

if (null !== $this->errorPage) {
$subRequest = $this->httpUtils->createRequest($request, $this->errorPage);
$subRequest->attributes->set(SecurityContextInterface::ACCESS_DENIED_ERROR, $exception);

$response = $event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);

break;
}

return;

} catch (\Exception $e) {
if (null !== $this->logger) {
$this->logger->error(sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $e->getMessage()));
}

$event->setException(new \RuntimeException('Exception thrown when handling an exception.', 0, $e));

return;
}
}
}

if ($exception instanceof LogoutException) {
if (null !== $this->logger) {
$this->logger->info(sprintf('Logout exception occurred; wrapping with AccessDeniedHttpException (%s)', $exception->getMessage()));
}

return;
}
} elseif ($exception instanceof LogoutException) {
if (null !== $this->logger) {
$this->logger->info(sprintf('Logout exception occurred; wrapping with AccessDeniedHttpException (%s)', $exception->getMessage()));
if (null === $exception->getPrevious()) {
return;
}

return;
} else {
return;

$exception = $exception->getPrevious();
}

$event->setResponse($response);
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.