I'm new to building rest APi using spring boot.
Here is my controller
snippet
@PreAuthorize("hasRole('ADMIN')")
@PostMapping(value = "/api/post/posts", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PostDto> createPost(@Valid @RequestBody PostDto postDto) {
System.out.println("postDto : " + postDto.getId());
return new ResponseEntity<>(postService.createPost(postDto), HttpStatus.CREATED);
}
this is my Security
config
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) //give method level security
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().antMatchers(HttpMethod.GET, "/api/**").permitAll().anyRequest()
.authenticated().and().httpBasic();
}
@Override
@Bean
protected UserDetailsService userDetailsService() {
// In Memory Users
UserDetails ashish = User.builder().username("oxana").password(getPasswordEncoder().encode("password")).roles("USER").build();
UserDetails admin = User.builder().username("admin").password(getPasswordEncoder().encode("admin")).roles("ADMIN").build();
return new InMemoryUserDetailsManager(ashish, admin);
}
@Bean
PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
I'm trying land above exception here
@ExceptionHandler(Exception.class)
public ResponseEntity<Errors> handleGlobalException(Exception exception,
WebRequest webRequest){
Error errorDetails = new Error();
errorDetails.setErrorDesc(exception.getMessage());
errorDetails.setErrorCode(Error.ErrorCodeEnum.BAD_REQUEST);
Errors errors = new Errors();
errors.addErrorsItem(errorDetails);
return new ResponseEntity<>(errors, HttpStatus.INTERNAL_SERVER_ERROR);
}
but its not coming and giving a big mess of error, like this
"timestamp": "2022-02-21T11:39:28.797+00:00",
"status": 403,
"error": "Forbidden",
"trace": "org.springframework.security.access.AccessDeniedException: Access is denied\r\n\tat org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:73)\r\n\tat org.springframework.security.access.intercept.AbstractSecurityInterceptor.attemptAuthorization(AbstractSecurityInterceptor.java:238)\r\n\tat org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:208)\r\n\tat org.springframework.security.access.intercept.aopalliance.
Can anyone please suggest me, How can I handle or catch this exception to customize error, where user has no access to do something ?
Thanks
Update
Implemented AccessDeniedHandler
in below way
@ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "Dont have sufficient priviliges to perform this action")
public class AccessDeniedError implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exec)
throws IOException, ServletException {
response.sendRedirect("Dont have sufficient priviliges to perform this action");
}
}
And now able to get message like this
{
"timestamp": "2022-02-21T13:29:08.377+00:00",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/api/post/Dont%20have%20sufficient%20priviliges%20to%20perform%20this%20action"
}
Its somewhat better, but how can I take control of these variables ("error", "message", "status")
values from above response, so that I could add mine custom values in it ?