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 中的任何内容确定调用
相关推荐
那你为何对我三笑留情5 天前
二、Spring Boot集成Spring Security之实现原理
java·spring boot·spring·spring security
那你为何对我三笑留情6 天前
一、Spring Boot集成Spring Security之自动装配
java·spring boot·spring·spring security
攸攸太上11 天前
Spring Security学习
java·学习·spring·spring security
G皮T2 个月前
【Spring Boot】用 Spring Security 实现后台登录及权限认证功能
spring boot·安全·spring·spring security·认证·登录·授权
左直拳3 个月前
Spring Boot项目的控制器貌似只能get不能post问题
spring boot·spring security·csrf·post不行
代码匠心3 个月前
从零开始学Spring Boot系列-集成Spring Security实现用户认证与授权
java·后端·springboot·spring security
langzitianya3 个月前
Spring Security6 设置免登录接口地址
java·后端·spring·spring security
兴趣广泛的程序猿4 个月前
关于Spring Security的CORS
spring·spring security·cors
Jack_hrx4 个月前
详解 Spring Security:全面保护 Java 应用程序的安全框架
java·安全·spring·spring cloud·spring security
Maiko Star4 个月前
(新)Spring Security如何实现登录认证(实战篇)
服务器·spring security