侧边栏壁纸
博主头像
前端小菜鸟 博主等级

聪明是一种天赋,而善良是一种选择。

  • 累计撰写 37 篇文章
  • 累计创建 24 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

SpringSecurity 自定义 AccessDeniedHandler 不生效的问题解决

fanfan
2024-03-11 / 0 评论 / 0 点赞 / 202 阅读 / 0 字
温馨提示:
本文最后更新于2024-03-11,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

SpringSecurity 自定义 AccessDeniedHandler 不生效的问题解决

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                // 禁用csrf(防止跨站请求伪造攻击)
                .csrf(AbstractHttpConfigurer::disable)
                // 使用无状态session,即不使用session缓存数据
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                // 设置白名单
                .authorizeHttpRequests(auth -> auth.requestMatchers(URL_WHITELIST).permitAll().anyRequest().authenticated())
                // 异常处理器
                .exceptionHandling(exception -> exception.authenticationEntryPoint(jwtAuthenticationEntryPoint).accessDeniedHandler(jwtAccessDeniedHandler))
                // 添加jwt过滤器
                .authenticationProvider(authenticationProvider()).addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }
@Component
public class JwtAccessDeniedHandler implements AccessDeniedHandler {
    private final Logger logger = LoggerFactory.getLogger(JwtAccessDeniedHandler.class);

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);

        Result<String> result = Result.failed("访问权限不足");
        String json = JSONUtil.toJsonStr(result);
        logger.info(json);

        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(json.getBytes(StandardCharsets.UTF_8));
        outputStream.flush();
        outputStream.close();
    }
}

在 Security配置类中 正确配置了 AccessDeniedHandler,但是异常时没有走AccessDeniedHandler,却走到了GlobalExceptionHandler。

由于GlobalExceptionHandler 全局异常处理器会比 AccessDeniedHandler 先捕获 AccessDeniedException 异常,因此当配置了 GlobalExceptionHandler 后,会发现 AccessDeniedHandler 失效了。

解决方法就是加一个AccessDeniedExceptionHandler继续往外抛

@ExceptionHandler(AccessDeniedException.class)
public void accessDeniedException(AccessDeniedException exception) throws AccessDeniedException {
	throw exception;
}

注意是security的AccessDeniedException

0
博主关闭了所有页面的评论