zoukankan      html  css  js  c++  java
  • Spring Security中配置AccessDeniedHandler没有生效

    现象

    在 WebSecurityConfigurerAdapter 配置了如下代码:

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

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

    @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));
    }
    

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

    原因

    @PreAuthorize 注解的异常,抛出 AccessDeniedException 异常,不会被 accessDeniedHandler 捕获,而是会被全局异常捕获。全局异常处理 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);
        }
    
    }
    

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

    http.cors().and()
            .authorizeRequests().antMatchers("/hello0").permitAll()
            // 注意hasRole、hasAuthority 如果出现异常,会调用设置的 accessDeniedHandler 方法
            .antMatchers("/hello").hasAuthority("Users.Update")
            .anyRequest().authenticated();
            
    // 自定义未授权和未登录异常
    http.exceptionHandling()
            .accessDeniedHandler(new RestAccessDeniedHandler())
            .authenticationEntryPoint(new RestAuthenticationEntryPoint());
    
  • 相关阅读:
    2019年Pycharm最新激活码_学生党适用
    Day14_分享昨天看到的一句话
    监督学习算法_k-近邻(kNN)分类算法_源代码
    Python学习需要安装的工具
    Python基础学习资料推荐
    总结一下公司项目使用各种较新的前端技术和 Api 的一些经验。
    由 Session 和 Cookie 的区别说起
    我理解的正确的代码
    回忆我是如何赢得一次踢毽子比赛
    日常的例子说明 throttle 和 debounce 的区别
  • 原文地址:https://www.cnblogs.com/liudecai/p/15469246.html
Copyright © 2011-2022 走看看