Spring Security 6.1.x 系列(2)—— 基于过滤器的基础原理(一)

一、过滤器

Spring SecurityServlet 支持基于 Servlet 过滤器,因此首先了解过滤器的作用会很有帮助。

下图为单个 HTTP 请求的处理程序的典型分层。

客户端向应用程序发送一个请求,运行容器创建一个FilterChain(过滤链),其中包括所有的Filter实例和Servlet。过滤器根据URI路径处理请求响应

在一个SpringMvcSpring Boot)应用程序中,一般只有一个Servlet实例,也就是 DispatcherServlet,他们按照指定的顺序(每个Filter实例实例的顺序非常重要),共同协作。

一个简单的自定义过滤器代码示例:

java 复制代码
// 使用@ServletComponentScan添加在启动类上扫描该自定义过滤器

@WebFilter(filterName = "simpleFilter", urlPatterns = {"/*"})
@Slf4j
public class SimpleFilter3 implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("业务处理开始");
        filterChain.doFilter(servletRequest, servletResponse);
        log.info("业务处理结束");
    }

    public void destroy() {
        log.info("销毁");
    }
}

二、DelegatingFilterProxy

Spring提供了一个名为DelegatingFilterProxy的实现,它允许Servlet容器和Spring IoC容器的生命周期之间进行桥接。

Servlet容器使用自己的标准注册Filter实例,但它不知道Spring IoC容器中定义的过滤器Bean。在有了DelegatingFilterProxy后就可以很方便的在Servlet中使用Spring IoC容器来管理过滤器Bean

请求响应 过程中,DelegatingFilterProxySpring IoC容器中查询注册的过滤器Bean对象,然后调用Bean的过滤方法。

下图为DelegatingFilterProxy是如何让使用Filter实例和FilterChain的。

DelegatingFilterProxy源码中可以看到该类包含了Spring IoC容器和被代理的过滤器:

一个简单的DelegatingFilterProxy使用代码示例:

java 复制代码
// Spring定义的Bean Filter
@Component("simpleFilter")
@Slf4j
public class SimpleFilter2 implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("业务处理开始");
        filterChain.doFilter(servletRequest, servletResponse);
        log.info("业务处理结束");
    }

    public void destroy() {
        log.info("销毁");
    }
}

@Configuration
public class SimpleConfig {
    
    @Bean
    public DelegatingFilterProxyRegistrationBean delegatingFilterProxyRegistrationBean() {
        DelegatingFilterProxyRegistrationBean delegatingFilterProxy = new DelegatingFilterProxyRegistrationBean("simpleFilter");
        delegatingFilterProxy.addUrlPatterns("/*");
        delegatingFilterProxy.setOrder(-5);
        Map<String, String> initParameters = new HashMap<>();
        initParameters.put("targetFilterLifecycle", "true");
        delegatingFilterProxy.setInitParameters(initParameters);
        return delegatingFilterProxy;
    }
}

三、FilterChainProxy

Spring Security提供FilterChainProxy代理类,是Spring Security使用的核心,用于代理Spring Security中所有的SecurityFilterChain,而在SecurityFilterChain 中又包含多个Spring Security声明的Filter

下图FilterChainProxy在整个请求响应过程中的作用。

FilterChainProxy源码中可以看到该类代理了Spring Security中所有的SecurityFilterChain

FilterChainProxy本质上是一个特殊的过滤器,通过DelegatingFilterProxy进行代理,所有其也是一个Bean对象。

SecurityFilterChain过滤链中通常都是Bean对象,通过FilterChainProxy进行注册与直接通过Servlet容器或通过DelegatingFilterProxy进行注册相比,FilterChainProxy注册有很多优势:

  • 它为 Spring Security 的所有 Servlet 支持提供了一个起点 ,如果需要对 Spring SecurityServlet 支持进行故障诊断可以在在 FilterchainProxy 中添加一个调试点。
  • 可以执行一些不被视为可有可无的任务,例如,清除了 SecurityContext 以避免内存泄漏、应用 Spring SecurityHttpFirewall 来保护应用程序免受某些类型的攻击
  • 在确定何时应该调用 SecurityFilterChain 方面提供了更大的灵活性,在 Servlet 容器中,Filter 实例仅基于URL 被调用。FilterChainProxy 可以通过使用 RequestMatcher 接口根据 HttpServletRequest 中的任何内容确定调用
相关推荐
Micro麦可乐3 天前
最新Spring Security实战教程(七)方法级安全控制@PreAuthorize注解的灵活运用
java·spring boot·后端·spring·intellij-idea·spring security
pitt199713 天前
AI 大模型统一集成|微服务 + 认证中心:如何保障大模型 API 的安全调用!
微服务·spring security·cookie·session·大模型api·认证中心
ccmjga2 个月前
升级 SpringBoot3 全项目讲解 — Spring Boot 3 中如何发Http请求?
java·spring boot·后端·docker·gradle·springboot·spring security
ccmjga2 个月前
升级 SpringBoot3 全项目讲解 — 别再使用 Optional 了,请使用 Jspecify 来替代它
java·spring boot·后端·docker·gradle·mybatis·spring security
朝屯暮蒙vi2 个月前
(五)Spring Boot学习——spring security +jwt使用(前后端分离模式)
spring boot·学习·spring·spring security
小筱在线3 个月前
Spring Boot安全加固:基于Spring Security的权限管理
spring boot·安全·spring·spring security
ccmjga3 个月前
升级 SpringBoot3 全项目讲解 — 为什么 SpringBoot3 应该抛弃 Maven,搭配 Gradle 来使用?
java·spring boot·后端·docker·gradle·maven·spring security
ccmjga3 个月前
升级 Spring Boot 3 配置讲解 — 新版本的秒杀系统怎么做?
java·spring boot·后端·spring·gradle·maven·spring security
ccmjga3 个月前
升级 Spring Boot 3 配置讲解 — JDK 23 会给 SpringBoot 带来什么特性?
java·spring boot·后端·spring·gradle·spring security
linmoo19864 个月前
Spring Security 6 系列之五 - 授权管理
spring security·acl·访问控制·abac·授权管理·rabc