【Spring Security】AccessDeniedHandler 用户无权限操作接口时处理

文章目录

前言

AccessDeniedHandler 接口负责处理用户在没有足够权限访问某资源时的行为。当用户尝试访问他们没有权限的资源时,这个处理器被触发。

官方是给了几个默认的处理器,当然,我们也可以自己自定义处理器,那么先简单介绍一下官方的处理器,然后再自己写一个自定义处理器。

官方给的处理器

AccessDeniedHandlerImpl

当用户访问一个无权限访问的接口时,触发的处理器。

AccessDeniedHandlerImpl 中可以设置一个重定向的路径,其中 AccessDeniedHandlerImpl 中还会返回一个 403 的状态码。

java 复制代码
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowCredentials(true);

        http
                // 退出登录
                .exceptionHandling()
                // 无权限访问资源处理器
                .accessDeniedHandler(accessDeniedHandler());
    }

    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        AccessDeniedHandlerImpl accessDeniedHandler = new AccessDeniedHandlerImpl();
        // 设置重定向的错误页面
        accessDeniedHandler.setErrorPage("/access-denied");
        return accessDeniedHandler;
    }

InvalidSessionAccessDeniedHandler

InvalidSessionAccessDeniedHandler 是当用户的会话时间到期后,执行的处理器。

java 复制代码
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowCredentials(true);

        http
                // 退出登录
                .exceptionHandling()
                // 无权限访问资源处理器
                .accessDeniedHandler(accessDeniedHandler());
    }

    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
    	// 会话时间到期后执行的处理器
        return new InvalidSessionAccessDeniedHandler(invalidSessionStrategy());
    }

    @Bean
    public InvalidSessionStrategy invalidSessionStrategy() {
        // 使用 SimpleRedirectInvalidSessionStrategy 或自定义实现
        return new SimpleRedirectInvalidSessionStrategy("/session-invalid");
    }

RequestMatcherDelegatingAccessDeniedHandler

RequestMatcherDelegatingAccessDeniedHandler 是用来灵活处理不同类型请求的访问拒绝逻辑,比如URL模式、HTTP方法等。

java 复制代码
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowCredentials(true);

        http
                // 退出登录
                .exceptionHandling()
                // 无权限访问资源处理器
                .accessDeniedHandler(accessDeniedHandler());
    }

    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        LinkedHashMap<RequestMatcher, AccessDeniedHandler> handlerMap = new LinkedHashMap<>();

        AccessDeniedHandlerImpl userAccessDeniedHandler = new AccessDeniedHandlerImpl();
        // 设置重定向的错误页面
        userAccessDeniedHandler.setErrorPage("/user-access-denied");
        handlerMap.put(new AntPathRequestMatcher("/user/**"), userAccessDeniedHandler);

        RequestMatcherDelegatingAccessDeniedHandler accessDeniedHandler = new RequestMatcherDelegatingAccessDeniedHandler(
                handlerMap,
                // 默认的执行处理器
                new AccessDeniedHandlerImpl());
        return accessDeniedHandler;
    }

DelegatingAccessDeniedHandler

DelegatingAccessDeniedHandler 是根据你出现权限访问错误后,根据出现的错误进行设置规则。

java 复制代码
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowCredentials(true);

        http
                // 退出登录
                .exceptionHandling()
                // 无权限访问资源处理器
                .accessDeniedHandler(accessDeniedHandler());
    }

    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        LinkedHashMap<Class<? extends AccessDeniedException>, AccessDeniedHandler> handlers = new LinkedHashMap<>();
        // 出现 AuthorizationServiceException 时执行
        handlers.put(AuthorizationServiceException.class, new AccessDeniedHandlerImpl());
        // 出现 MissingCsrfTokenException 时执行
        handlers.put(MissingCsrfTokenException.class, new AccessDeniedHandlerImpl());

        return new DelegatingAccessDeniedHandler(
                handlers,
                // 默认执行的处理方式
                new AccessDeniedHandlerImpl());
    }

自定义处理器

java 复制代码
package com.security.handler.access;

import com.alibaba.fastjson2.JSON;
import com.security.controller.vo.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
@Slf4j
public class CustomAccessDeniedHandlerImpl implements AccessDeniedHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        log.info("CustomAccessDeniedHandlerImpl 授权失败处理 ...");
        /**
         * 设置响应状态值
         */
        response.setStatus(403);
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        String json = JSON.toJSONString(
                ResponseResult.builder()
                        .code(403)
                        .message("认证失败!")
                        .build());

        // JSON信息
        response.getWriter().println(json);
    }

}
java 复制代码
package com.security.config;

import com.security.handler.access.CustomAccessDeniedHandlerImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.web.cors.CorsConfiguration;



@Configuration
@EnableWebSecurity
// 开启限制访问资源所需权限
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfigurationTest extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowCredentials(true);

        http
                // 退出登录
                .exceptionHandling()
                // 无权限访问资源处理器
                .accessDeniedHandler(accessDeniedHandler());
    }

    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        return new CustomAccessDeniedHandlerImpl();
    }


}

End

相关推荐
颜酱5 小时前
图结构完全解析:从基础概念到遍历实现
javascript·后端·算法
Coder_Boy_5 小时前
技术让开发更轻松的底层矛盾
java·大数据·数据库·人工智能·深度学习
invicinble5 小时前
对tomcat的提供的功能与底层拓扑结构与实现机制的理解
java·tomcat
较真的菜鸟5 小时前
使用ASM和agent监控属性变化
java
黎雁·泠崖6 小时前
【魔法森林冒险】5/14 Allen类(三):任务进度与状态管理
java·开发语言
qq_12498707537 小时前
基于SSM的动物保护系统的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·毕业设计·ssm·计算机毕业设计
Coder_Boy_7 小时前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端
Mr_sun.7 小时前
Day06——权限认证-项目集成
java
瑶山7 小时前
Spring Cloud微服务搭建四、集成RocketMQ消息队列
java·spring cloud·微服务·rocketmq·dashboard
abluckyboy7 小时前
Java 实现求 n 的 n^n 次方的最后一位数字
java·python·算法