[Security] fixed error 500 instead of 403 if previous exception is provided to AccessDeniedException

This commit is contained in:
Tomasz Szymczyk 2013-12-19 13:59:41 +01:00 committed by Fabien Potencier
parent c33341df09
commit 616b6c5227

View File

@ -83,79 +83,95 @@ class ExceptionListener
$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()));
}
}
try {
if (null !== $this->accessDeniedHandler) {
$response = $this->accessDeniedHandler->handle($request, $exception);
if ($exception instanceof AccessDeniedException) {
$event->setException(new AccessDeniedHttpException($exception->getMessage(), $exception));
if (!$response instanceof Response) {
return;
}
} elseif (null !== $this->errorPage) {
$subRequest = $this->httpUtils->createRequest($request, $this->errorPage);
$subRequest->attributes->set(SecurityContextInterface::ACCESS_DENIED_ERROR, $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()));
}
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;
}
}
}
} elseif ($exception instanceof LogoutException) {
if (null !== $this->logger) {
$this->logger->info(sprintf('Logout exception occurred; wrapping with AccessDeniedHttpException (%s)', $exception->getMessage()));
if ($exception instanceof LogoutException) {
if (null !== $this->logger) {
$this->logger->info(sprintf('Logout exception occurred; wrapping with AccessDeniedHttpException (%s)', $exception->getMessage()));
}
return;
}
return;
} else {
return;
if (null === $exception->getPrevious()) {
return;
}
$exception = $exception->getPrevious();
}
$event->setResponse($response);