You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Boot中配置非安全Filter于Spring Security之后并控制其顺序

如何将非安全自定义Filter置于Spring Security Filter链之后并控制顺序

核心逻辑

Spring Boot中所有Servlet Filter的执行顺序由优先级(Order)决定:Spring Security默认Filter链的优先级是SecurityProperties.DEFAULT_FILTER_ORDER(值为-100),只要让你的非安全自定义Filter优先级大于-100,就能确保它们在Security Filter验证通过后才执行。


方案1:通过@Component+@Order快速注册

如果自定义Filter不需要特殊URL匹配,直接用@Component注册到Spring容器,搭配@Order指定优先级即可:

@Component
@Order(1) // 数值大于-100即可,数值越小优先级越高
public class AuditLogFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        // 示例业务逻辑:记录请求日志
        System.out.println("执行审计日志Filter");
        chain.doFilter(req, res);
    }
}

@Component
@Order(2) // 数值比1大,在AuditLogFilter之后执行
public class ResponseWrapFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        // 示例业务逻辑:统一包装响应格式
        System.out.println("执行响应包装Filter");
        chain.doFilter(req, res);
    }
}

提示:如果不指定@Order,Spring会给组件分配默认最低优先级(Ordered.LOWEST_PRECEDENCE),也会在Security Filter之后,但无法控制多个自定义Filter的执行顺序。


方案2:用FilterRegistrationBean精细控制

如果需要指定Filter仅对特定URL生效,或者不想让Filter被自动扫描注册,推荐用FilterRegistrationBean显式配置:

@Configuration
public class CustomFilterConfig {

    @Bean
    public FilterRegistrationBean<AuditLogFilter> auditLogFilterRegistration() {
        FilterRegistrationBean<AuditLogFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new AuditLogFilter());
        registration.addUrlPatterns("/api/**"); // 仅对/api开头的请求生效
        registration.setOrder(1); // 确保在Security之后执行
        return registration;
    }

    @Bean
    public FilterRegistrationBean<ResponseWrapFilter> responseWrapFilterRegistration() {
        FilterRegistrationBean<ResponseWrapFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new ResponseWrapFilter());
        registration.addUrlPatterns("/api/**");
        registration.setOrder(2); // 优先级低于AuditLogFilter,后执行
        return registration;
    }
}

// 自定义Filter无需加@Component
public class AuditLogFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        System.out.println("执行审计日志Filter");
        chain.doFilter(req, res);
    }
}

public class ResponseWrapFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        System.out.println("执行响应包装Filter");
        chain.doFilter(req, res);
    }
}

验证执行顺序

在每个Filter的doFilter方法中添加日志输出,启动服务后发起请求,就能从控制台日志确认顺序:

  • 首先会看到Spring Security相关Filter的日志(比如UsernamePasswordAuthenticationFilter)
  • 之后按你设置的Order顺序执行自定义Filter

注意事项

  • 绝对不要把这些非安全Filter添加到Spring Security的SecurityFilterChain配置中,否则它们会被纳入安全校验链,不符合需求。
  • 如果你的Spring Security配置自定义了SecurityFilterChain的优先级(比如通过@Order修改了默认的-100),那么自定义Filter的Order值要大于这个自定义的优先级数值。

内容的提问来源于stack exchange,提问作者hotmeatballsoup

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 12:18:21