PreAuthorize error handling
Spring Boot docs on error handling: http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-error-handling. One way you can control the JSON is by adding a @Bean
of type ErrorAttributes
.
@BeanErrorAttributes errorAttributes() { return new MyErrorAttributes();}
Implement AccessDeniedHandler
@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); try { ObjectMapper mapper = new ObjectMapper(); SomeJsonModel jsonResponse =new SomeJsonModel(); mapper.writeValue(response.getOutputStream(), jsonResponse); } catch (Exception e) { throw new ServletException(); }}
SomeJsonModel will be your own POJO/model class which you can controlAnd add that access denied handler in Resource Server Configuration
@Overridepublic void configure(HttpSecurity http) throws Exception { http.requestMatchers() .antMatchers(SECURED_PATTERN).and().authorizeRequests() .antMatchers(HttpMethod.POST,SECURED_PATTERN).access(SECURED_WRITE_SCOPE) .anyRequest().access(SECURED_READ_SCOPE).and() .exceptionHandling().authenticationEntryPoint(newAuthExceptionEntryPoint()) .accessDeniedHandler(new MyAccessDeniedHandler());}
It was not working for me when I implemented AccessDeniedHandler. So I created a ExceptionHandler function inside AuthenticationEntryPoint and marked the class as@ControllerAdvice.
Please find the code below
@ControllerAdvice@Component public class EmrExceptionHandler implements AuthenticationEntryPoint { private static final Logger logger = LoggerFactory.getLogger(EmrExceptionHandler.class); @Override public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException authException) throws IOException, ServletException { logger.error("Unauthorized error: {}", authException.getMessage()); httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value()); httpServletResponse.getWriter().write(convertObjectToJson(new ErrorResponse(ResponseMessages.NOT_AUTHORIZED))); } @ExceptionHandler(value = {AccessDeniedException.class}) public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException accessDeniedException) throws IOException { logger.error("AccessDenied error: {}", accessDeniedException.getMessage()); httpServletResponse.setStatus(HttpStatus.FORBIDDEN.value()); httpServletResponse.getWriter().write(convertObjectToJson(new ErrorResponse(ResponseMessages.NOT_PERMITTED))); } public String convertObjectToJson(Object object) throws JsonProcessingException { if (object == null) { return null; } ObjectMapper mapper = new ObjectMapper(); return mapper.writeValueAsString(object); }}