Skip to content
基础

一句话答案

Filter 基于 Servlet 规范拦截请求/响应(Tomcat 级),Interceptor 基于 Spring MVC 拦截 Controller 方法(更细粒度)。

核心要点

核心架构:

Spring Security 基于 Servlet Filter Chain 实现,但不是直接注册多个 Servlet Filter,而是用一个 DelegatingFilterProxy 委托给 Spring 管理的 FilterChainProxy

HTTP 请求
  → DelegatingFilterProxy(Servlet Filter,桥接 Spring)
    → FilterChainProxy(Spring Bean,管理多条 SecurityFilterChain)
      → SecurityFilterChain(匹配 URL 模式,包含 15+ 个内部 Filter)
        → SecurityContextPersistenceFilter  // 加载/保存 SecurityContext
        → UsernamePasswordAuthenticationFilter  // 表单登录
        → BearerTokenAuthenticationFilter  // JWT/OAuth2 Token 认证
        → AuthorizationFilter  // 权限校验(@PreAuthorize 等)
        → ExceptionTranslationFilter  // 认证/授权异常处理
        → ...

关键设计:

  1. 多条 SecurityFilterChain:可以为不同 URL 配置不同的安全策略(如 /api/** 用 JWT,/admin/** 用 Session)
  2. Filter 顺序固定:Spring Security 内部 Filter 有严格的顺序,不能随意调整
  3. 自定义 Filter:可以通过 addFilterBefore/After 插入自定义过滤器(如自定义 JWT 验证逻辑)
java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    return http
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/public/**").permitAll()
            .anyRequest().authenticated()
        )
        .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
        .build();
}

与 JWT 的关系(→ 衔接 Q12-Q13):

  • JWT 认证通常通过自定义 OncePerRequestFilter 实现
  • 从请求头提取 Token → 解析验证 → 构建 Authentication 对象 → 放入 SecurityContext
  • 后续的 AuthorizationFilter 基于 SecurityContext 中的权限信息做访问控制
追问与易错

追问方向:

  • Filter 和 Interceptor 谁先执行?
  • 什么场景用哪个?
  • preHandle 返回 false 会怎样?

易错点:

  • ❌ Filter 和 Interceptor 功能一样——基础不同
  • ❌ Interceptor 能拿到方法参数——preHandle 拿不到

💡 记忆锚点

Filter = 大门保安(Servlet容器级,所有请求都过,先于Spring);Interceptor = 楼层前台(Spring MVC级,只拦Controller,能拿到Handler信息)。执行顺序:Filter先 -> DispatcherServlet -> Interceptor -> Controller。Spring Security就是一堆Filter组成的安检流水线。