当前位置:   article > 正文

Spring Security中配置AccessDeniedHandler没有生效

accessdeniedhandler

现象

在 WebSecurityConfigurerAdapter 配置了如下代码:

  1. // 自定义未授权和未登录异常
  2. http.exceptionHandling()
  3. .accessDeniedHandler(new RestAccessDeniedHandler())
  4. .authenticationEntryPoint(new RestAuthenticationEntryPoint());

在 Controller 层 REST 接口中添加有 @PreAuthorize 注解:

  1. @PreAuthorize(value = "hasAuthority('Users.Update')")
  2. @GetMapping("/hello")
  3. public ResponseEntity<?> hello(@RequestParam(value = "name", required = false, defaultValue = "Tom") String name) {
  4. return ResponseEntity.ok(RestResponse.buildResponse("Hi: " + name));
  5. }

访问接口 /hello,报服务端 500 错误,没有执行我们设置的 accessDeniedHandler 来处理权限不足的异常。

原因

@PreAuthorize 注解的异常,抛出 AccessDeniedException 异常,不会被 accessDeniedHandler 捕获,而是会被全局异常捕获。全局异常处理 AccessDeniedException 的相关示例代码:

  1. @Slf4j
  2. @RestControllerAdvice
  3. public class GlobalExceptionHandler {
  4. @ExceptionHandler(Exception.class)
  5. public ResponseEntity<RestResponse<Object>> handleException(Exception exception) {
  6. String message = exception.getLocalizedMessage();
  7. log.error("全局异常捕获Exception:{}", message, exception);
  8. HttpStatus httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
  9. if (exception instanceof BadCredentialsException) {
  10. httpStatus = HttpStatus.UNAUTHORIZED;
  11. }
  12. if (exception instanceof HttpRequestMethodNotSupportedException) {
  13. httpStatus = HttpStatus.METHOD_NOT_ALLOWED;
  14. }
  15. return RestResponse.buildError(httpStatus, message);
  16. }
  17. @ExceptionHandler(CommonException.class)
  18. public ResponseEntity<RestResponse<Object>> handleException(CommonException exception) {
  19. String message = exception.getLocalizedMessage();
  20. log.error("全局异常捕获CommonException:{}", message);
  21. return RestResponse.buildError(exception.getBusinessStatus(), message);
  22. }
  23. @ExceptionHandler(AccessDeniedException.class)
  24. public ResponseEntity<RestResponse<Object>> handleException(AccessDeniedException exception) {
  25. String message = exception.getLocalizedMessage();
  26. log.error("全局异常捕获AccessDeniedException:{}", message);
  27. return RestResponse.buildError(HttpStatus.FORBIDDEN, Forbidden);
  28. }
  29. }

如果需要被 accessDeniedHandler 捕获处理,则需要这么写 WebSecurityConfigurerAdapter 的代码:

  1. http.cors().and()
  2. .authorizeRequests().antMatchers("/hello0").permitAll()
  3. // 注意hasRole、hasAuthority 如果出现异常,会调用设置的 accessDeniedHandler 方法
  4. .antMatchers("/hello").hasAuthority("Users.Update")
  5. .anyRequest().authenticated();
  6. // 自定义未授权和未登录异常
  7. http.exceptionHandling()
  8. .accessDeniedHandler(new RestAccessDeniedHandler())
  9. .authenticationEntryPoint(new RestAuthenticationEntryPoint());

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/68917
推荐阅读
相关标签
  

闽ICP备14008679号