Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring boot : How could I customize the forbidden error json

I was wondering if I could customize the following forbidden JSON error:

Actual Response

{
  "timestamp": "2018-09-26T06:11:05.047+0000",
  "status": 403,
  "error": "Forbidden",
  "message": "Access Denied",
  "path": "/api/rest/hello/me"
}

Custom Response - I get it when the user request does not have permissions.

{ 
  "code": 403,
  "message": "Access denied by the system",
  "status": "Failure"
}

My Web security class

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  private JwtTokenProvider jwtTokenProvider;

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();
    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    http.authorizeRequests()//
        .antMatchers("/rest/hello/signin").permitAll()//
        .anyRequest().authenticated();
    http.apply(new JwtTokenFilterConfigurer(jwtTokenProvider));
  @Bean
  public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder(12);
  }
}
like image 267
Rabikatha Avatar asked Sep 26 '18 06:09

Rabikatha


People also ask

How do I send a custom error message in REST API spring boot?

The most basic way of returning an error message from a REST API is to use the @ResponseStatus annotation. We can add the error message in the annotation's reason field. Although we can only return a generic error message, we can specify exception-specific error messages.

How do I create a custom exception in spring boot?

Define a class that extends the RuntimeException class. You can define the @ExceptionHandler method to handle the exceptions as shown. This method should be used for writing the Controller Advice class file. Now, use the code given below to throw the exception from the API.


1 Answers

You can create custom handler using the Jackson ObjectMapper like this:

@Bean
public AccessDeniedHandler accessDeniedHandler() {
    return (request, response, ex) -> {
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);

        ServletOutputStream out = response.getOutputStream();
        new ObjectMapper().writeValue(out, new MyCustomErrorDTO());
        out.flush();
    };
}

And configure your HttpSecurity like this:

http.exceptionHandling().accessDeniedHandler(accessDeniedHandler());

Also, you can try throw AuthenticationException:

@Bean
public AuthenticationFailureHandler failureHandler() {
    return (request, response, ex) -> { throw ex; };
}

And handle them in @RestControllerAdvice:

@RestControllerAdvice
public class AdviseController {

    @ExceptionHandler(AuthenticationException.class)
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public MyCustomErrorDTO handleAuthenticationException(AuthenticationException ex) {
        return new MyCustomErrorDTO();
    }
}

But I'm not sure that it will work, you can check it out.

like image 196
Artiow Avatar answered Oct 13 '22 16:10

Artiow