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 中的任何内容确定调用
相关推荐
消失的旧时光-194318 小时前
第十三课:权限系统如何设计?——RBAC 与 Spring Security 架构
java·架构·spring security·rbac
编程彩机10 天前
互联网大厂Java面试:从Spring Security到微服务架构场景解析
kafka·spring security·微服务架构·jwt·java面试·分布式追踪
编程彩机12 天前
互联网大厂Java面试:从Spring Security到消息队列的场景解析
消息队列·spring security·微服务架构·java面试·分布式系统
indexsunny14 天前
互联网大厂Java面试实战:从Spring Boot到微服务架构的三轮提问
java·spring boot·微服务·eureka·kafka·mybatis·spring security
Micro麦可乐14 天前
最新Spring Security实战教程(十五)快速集成 GitHub 与 Gitee 的社交登录
java·spring boot·spring·gitee·github·spring security·社交登陆
indexsunny15 天前
互联网大厂Java面试实战:Spring Boot与微服务在电商场景中的应用
java·spring boot·redis·微服务·kafka·spring security·电商
这儿有个昵称18 天前
Java大厂面试实录:从Spring MVC到微服务的技术深度探讨
java·redis·spring·mybatis·spring security·spring mvc·oauth2
qq_3181215921 天前
互联网大厂Java面试故事:在线教育微服务架构、缓存优化与AI智能教学全流程解析
java·spring boot·redis·微服务·kafka·spring security·在线教育
予枫的编程笔记23 天前
【Java进阶】Spring Security详解
java·spring security·security
indexsunny23 天前
互联网大厂Java面试实战:音视频场景中的Spring Boot与Kafka技术问答
java·spring boot·redis·面试·kafka·spring security·互联网大厂