phenomenon
The following code is configured in websecurityconfigureradapter:
// Customize unauthorized and non-login exceptions
http.exceptionHandling()
.accessDeniedHandler(new RestAccessDeniedHandler())
.authenticationEntryPoint(new RestAuthenticationEntryPoint());
The @preauthorize annotation is added to the rest interface of the controller layer:
@PreAuthorize(value = "hasAuthority('Users.Update')")
@GetMapping("/hello")
public ResponseEntity<?> hello(@RequestParam(value = "name", required = false, defaultValue = "Tom") String name) {
return ResponseEntity.ok(RestResponse.buildResponse("Hi: " + name));
}
The provider interface/Hello reports a server 500 error and does not execute the accessdeniedhandler we set to handle exceptions with insufficient permissions.
reason
The @preauthorize annotated exception throws an accessdeniedexception, which will not be caught by the accessdeniedhandler, but by the global exception. Example code for global exception handling accessdeniedexception:
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<RestResponse<Object>> handleException(Exception exception) {
String message = exception.getLocalizedMessage();
log.error("Exception: {}", message, exception);
HttpStatus httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
if (exception instanceof BadCredentialsException) {
httpStatus = HttpStatus.UNAUTHORIZED;
}
if (exception instanceof HttpRequestMethodNotSupportedException) {
httpStatus = HttpStatus.METHOD_NOT_ALLOWED;
}
return RestResponse.buildError(httpStatus, message);
}
@ExceptionHandler(CommonException.class)
public ResponseEntity<RestResponse<Object>> handleException(CommonException exception) {
String message = exception.getLocalizedMessage();
log.error("CommonException:{}", message);
return RestResponse.buildError(exception.getBusinessStatus(), message);
}
@ExceptionHandler(AccessDeniedException.class)
public ResponseEntity<RestResponse<Object>> handleException(AccessDeniedException exception) {
String message = exception.getLocalizedMessage();
log.error("AccessDeniedException: {}", message);
return RestResponse.buildError(HttpStatus.FORBIDDEN, Forbidden);
}
}
If it needs to be captured and processed by accessdeniedhandler, you need to write the code of websecurityconfigureradapter as follows:
http.cors().and()
.authorizeRequests().antMatchers("/hello0").permitAll()
// Note that hasRole, hasAuthority will call the set accessDeniedHandler method if an exception occurs.
.antMatchers("/hello").hasAuthority("Users.Update")
.anyRequest().authenticated();
// Customize unauthorized and non-login exceptions
http.exceptionHandling()
.accessDeniedHandler(new RestAccessDeniedHandler())
.authenticationEntryPoint(new RestAuthenticationEntryPoint());
Similar Posts:
- Spring: How to Solve Global exception @restcontrolleradvice
- [Solved] Using JDK dynamic agent to customize SPI Error: UndeclaredThrowableException
- Hyperf captures PHP error levels, such as notice, warning and error, and returns them to the front-end
- [Two Solutions] non-static method xxx() cannot be referenced from a static context
- Roman to Integer LeetCode Java
- Convert Object to List>, avoiding Unchecked cast: ‘java.lang.Object’ to ‘java.util.List
- Interaction between web browser and JavaScript in WPF
- Quartz: add transaction rollback error [How to Solve]
- [Solved] java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id “null”
- Java error: No enclosing instance of type E is accessible. Must qualify the allocation with an enclosing