如何在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
相关产品推荐
相关产品推荐

