千家信息网

什么是SpringSecurity过滤器

发表于:2025-11-09 作者:千家信息网编辑
千家信息网最后更新 2025年11月09日,这篇文章主要介绍"什么是SpringSecurity过滤器",在日常操作中,相信很多人在什么是SpringSecurity过滤器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家
千家信息网最后更新 2025年11月09日什么是SpringSecurity过滤器

这篇文章主要介绍"什么是SpringSecurity过滤器",在日常操作中,相信很多人在什么是SpringSecurity过滤器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"什么是SpringSecurity过滤器"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

前置知识

我们知道Spring Security是通过Filter的方式来完成它的核心流程。但是:

  1. Spring Security到底拥有哪些Filter?

  2. 这些Filter是如何注入容器?

  3. 我们如何自定义自己的Filter?

web.xml配置

前面我们已经介绍过了,最开始如果我们要配置Filter,一般是通过web.xml的方式:

     deleFilter     org.springframework.web.filter.DelegatingFilterProxy             targetBeanName        spring-bean-name                      deleFilter     /*  

SpringBoot中添加Filter

在SpringBoot中可以通过@WebFilter和@ServletComponentScan注解,注入自定义的Filter。

@WebFilter(filterName = "myFilter",urlPatterns = "/*")public class MyFilter implements Filter {    @Override    public void init(FilterConfig filterConfig) throws ServletException {    }    @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {    }    @Override    public void destroy() {    }}@SpringBootApplication@ServletComponentScan(basePackages = "vip.mycollege.filter")public class StartApplication {    public static void main(String[] args) {        SpringApplication.run(StartApplication.class, args);    }}

也可以通过FilterRegistrationBean的方式,注入自定义的Filter。

@Configurationpublic class FilterConfig {    @Bean    public FilterRegistrationBean filterRegistrationBean(){        FilterRegistrationBean bean = new FilterRegistrationBean();        bean.setFilter(new MyFilter());        bean.addUrlPatterns("/*");        return bean;    }}

也可以通过DelegatingFilterProxyRegistrationBean的方式。

@Configurationpublic class FilterConfig {    @Bean("proxyFilter")    public Filter filter (){        return new Filter() {            @Override            public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {            }            @Override            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {            }            @Override            public void destroy() {            }            @Bean    public DelegatingFilterProxyRegistrationBean delegatingFilterProxyRegistrationBean(){        DelegatingFilterProxyRegistrationBean bean = new DelegatingFilterProxyRegistrationBean("proxyFilter");        bean.addUrlPatterns("/*");        return bean;    }}

DelegatingFilterProxyRegistrationBean和FilterRegistrationBean都继承了AbstractFilterRegistrationBean,从名字上看就知道是一个RegistrationBean,也就是说会在Servlet容器启动的时候被注入。

DelegatingFilterProxyRegistrationBean会在Servlet容器中注册一个DelegatingFilterProxy,用来代理Spring IoC容器中某个指定名称的Filter bean。

FilterChainProxy

SpringBoot有一个SecurityFilterAutoConfiguration的自动配置类,就会配置一个name为springSecurityFilterChain的DelegatingFilterProxyRegistrationBean,这个类的url-pattern默认为/*,也就是说会过滤所有的请求。

name是springSecurityFilterChain是一个什么鬼呢?

答案是:FilterChainProxy。

这个类是在HttpSecurityBeanDefinitionParser的registerFilterChainProxyIfNecessary方法中注册。

HttpSecurityBeanDefinitionParser也是一个BeanDefinitionParser,因此它会通过parse方法来构建Filter类。

整个流程现在就清晰了:

  1. SpringBoot通过自动配置类搞了个DelegatingFilterProxyRegistrationBean

  2. DelegatingFilterProxyRegistrationBean会在Servlet启动的时候注册一个DelegatingFilterProxy

  3. DelegatingFilterProxy会默认会拦截所有的请求,然后交个一个别名为springSecurityFilterChain的FilterChainProxy

  4. FilterChainProxy在持有一个SecurityFilterChain的list

  5. SecurityFilterChain本身又持有一个Filter列表,可以通过match找出url匹配的Request交个filters处理

FilterChainProxy除了持有过滤器,默认内置了一个StrictHttpFirewall一个HTTP防火墙,它采用了严格模式,遇到任何可疑的请求,会通过抛出异常RequestRejectedException拒绝该请求。

现在我们知道了Spring Security如何收集利用Filter了。

但是,Spring Security到底背着我们弄了哪些Filter呢?

我只想说很多,要知道有哪些也很简单,在FilterChainProxy打一个断点,debug,看一下filterChains变量中的filters列表就能看到有哪些filter

默认情况下filterChains只有一个filte,就是DefaultSecurityFilterChain,看名字就知道这是一个SecurityFilterChain,他包含了一个Filter列表,默认有:

  1. WebAsyncManagerIntegrationFilter:与处理异步请求映射的 WebAsyncManager 进行集成

  2. SecurityContextPersistenceFilter: 请求前保存和请求后清除SecurityContextHolder中的安全上下文

  3. HeaderWriterFilter:将头信息加入响应中

  4. CsrfFilter:处理跨站请求伪造

  5. LogoutFilter:处理登出

  6. UsernamePasswordAuthenticationFilter:处理基于表单的登录

  7. DefaultLoginPageGeneratingFilter:如果没有配置登录页,生成默认登录页

  8. DefaultLogoutPageGeneratingFilter:如果没有登出页,生成默认登出页

  9. BasicAuthenticationFilter:处理HTTP BASIC认证

  10. RequestCacheAwareFilter:处理请求的缓存

  11. SecurityContextHolderAwareRequestFilter:包装请求对象request

  12. AnonymousAuthenticationFilter:检测SecurityContextHolder是否存在Authentication,如不存在提供一个匿名 Authentication

  13. SessionManagementFilter:管理 session 的过滤器

  14. ExceptionTranslationFilter:处理 AccessDeniedException 和 AuthenticationException 异常

  15. FilterSecurityInterceptor: 权限校验相关

重要Filter

UsernamePasswordAuthenticationFilter

UsernamePasswordAuthenticationFilter本身没啥好说的,它就是一个Filter,但是因为它用得多,所以说一下。

Filter肯定先看doFilter方法,UsernamePasswordAuthenticationFilter的主要认证逻辑在attemptAuthentication:

@Overridepublic Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)        throws AuthenticationException {    if (this.postOnly && !request.getMethod().equals("POST")) {        throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());    }    String username = obtainUsername(request);    username = (username != null) ? username : "";    username = username.trim();    String password = obtainPassword(request);    password = (password != null) ? password : "";    UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);    setDetails(request, authRequest);    return this.getAuthenticationManager().authenticate(authRequest);}

很简单,就是从request中获取username和password的字段,封装成UsernamePasswordAuthenticationToken,然后扔给AuthenticationManager去执行认证,当然,最终认证逻辑肯定是像DaoAuthenticationProvider 这样的AuthenticationProvider执行。

FilterSecurityInterceptor

FilterSecurityInterceptor主要是用来做权限校验的,具体的鉴权逻辑主要在AbstractSecurityInterceptor中。

FilterSecurityInterceptor也是一个Filter,所以,还是先看doFilter方法,调用了invoke:

public void invoke(FilterInvocation filterInvocation) throws IOException, ServletException {        //一次请求中避免重复检查                if (isApplied(filterInvocation) && this.observeOncePerRequest) {                        filterInvocation.getChain().doFilter(filterInvocation.getRequest(), filterInvocation.getResponse());                        return;                }                // 第一次调用,先设置标记,避免重复调用                if (filterInvocation.getRequest() != null && this.observeOncePerRequest) {                        filterInvocation.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);                }        // 业务逻辑调用之前,执行检查鉴权操作主要就是在这里面完成                InterceptorStatusToken token = super.beforeInvocation(filterInvocation);                try {            // 执行具体的业务逻辑                        filterInvocation.getChain().doFilter(filterInvocation.getRequest(), filterInvocation.getResponse());                }                finally {                        super.finallyInvocation(token);                }        // 业务逻辑调用之后,主要是处理返回结果                super.afterInvocation(token, null);        }

FilterInvocation就是FilterInvocation、ServletResponse、FilterChain的简单封装。

我们看到整个invoke的逻辑非常清晰,很像AOP的around结构。

ExceptionTranslationFilter

ExceptionTranslationFilter的逻辑有点奇怪,它主要是为了处理 AccessDeniedException 和 AuthenticationException 异常。但是并不是处理它前面产生的异常,而是它后面的Filter产生的异常,因为它前面Filter如果异常了根本到不了它这里。

它后面,默认就只有FilterSecurityInterceptor了,主要会产生AccessDeniedException授权异常,AuthenticationException是因为有一个再认证的过程。

过滤器

  • WebAsyncManagerIntegrationFilter

  • SecurityContextPersistenceFilter

  • ChannelProcessingFilter

  • ConcurrentSessionFilter

  • HeaderWriterFilter

  • CorsFilter

  • CsrfFilter

  • LogoutFilter

  • OAuth3AuthorizationRequestRedirectFilter

  • Saml2WebSsoAuthenticationRequestFilter

  • X509AuthenticationFilter

  • AbstractPreAuthenticatedProcessingFilter

  • CasAuthenticationFilter

  • OAuth3LoginAuthenticationFilter

  • Saml2WebSsoAuthenticationFilter

  • UsernamePasswordAuthenticationFilter

  • ConcurrentSessionFilter

  • OpenIDAuthenticationFilter

  • DefaultLoginPageGeneratingFilter

  • DefaultLogoutPageGeneratingFilter

  • DigestAuthenticationFilter

  • BearerTokenAuthenticationFilter

  • BasicAuthenticationFilter

  • RequestCacheAwareFilter

  • SecurityContextHolderAwareRequestFilter

  • JaasApiIntegrationFilter

  • RememberMeAuthenticationFilter

  • AnonymousAuthenticationFilter

  • OAuth3AuthorizationCodeGrantFilter

  • SessionManagementFilter

  • ExceptionTranslationFilter

  • SwitchUserFilter

  • FilterSecurityInterceptor

到此,关于"什么是SpringSecurity过滤器"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0