I want to catch the spring boot access denied exception when for example a user is about to access a page that is for an admin.
I have this exception handler in my GlobalExceptionHandler (@ControllerAdvice)
@ExceptionHandler(AccessDeniedException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
public String handleAccessDenied(AccessDeniedException e, Model model) {
model.addAttribute("errorMessage", e.getMessage());
return "error";
}
I tried using a CustomAccessDeniedHandler:
@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
throw accessDeniedException;
}
}
and in my SecurityConfig i added this to my filterChain:
.exceptionHandling(eh -> eh.accessDeniedHandler(customAccessDeniedHandler))
And now i get an Access Denied in my terminal: org.springframework.security.authorization.AuthorizationDeniedException: Access Denied
I want to catch this with my GlobalExceptionHandler (tried using AuthorizationDeniedException in ExceptionHandler)
Note: I dont use JWT
What am i missing?
Spring Security throws AccessDeniedException
in FilterSecurityInterceptor
, before the request reaches any controller, so @ControllerAdvice
cannot catch it.
Instead, you can try to handle it inside AccessDeniedHandler
. In your code, exception is throwing again, so it's not caught anywhere.
Try to change handler to do something like this:
@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(
HttpServletRequest request,
HttpServletResponse response,
AccessDeniedException accessDeniedException
) throws IOException {
request.setAttribute("errorMessage", accessDeniedException.getMessage());
response.sendRedirect("/access-denied");
}
}
Then add a controller to handle /access-denied
:
@Controller
public class ErrorController {
@GetMapping("/access-denied")
public String accessDenied(Model model, HttpServletRequest request) {
String msg = (String) request.getAttribute("errorMessage");
model.addAttribute("errorMessage", msg);
return "error";
}
}
This way you can show a custom error page with your message.