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

如何配置过滤器:仅/login路由用LDAP认证,其余路由用自定义JWT Filter?

解决方案:分离LDAP与JWT的过滤器链配置

这个问题核心是Spring Security过滤器链的匹配范围和优先级配置错误——如果只定义一个全局过滤器链,所有请求都会经过链内的所有过滤器,导致非/login路径同时触发JWT和LDAP认证,冲突失败。正确的做法是创建两个独立的SecurityFilterChain,分别处理/login和其他路径,让它们互不干扰。

步骤1:配置LDAP专属过滤器链(仅处理/login)

创建一个优先级更高的过滤器链,只匹配/login路径,启用Basic Auth并绑定LDAP认证逻辑:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    // 1. LDAP认证专用过滤器链:仅处理/login,优先级更高
    @Bean
    @Order(1) // 数值越小优先级越高,确保/login请求先匹配此链
    public SecurityFilterChain ldapLoginFilterChain(HttpSecurity http) throws Exception {
        http
            .securityMatcher("/login") // 明确指定此链只处理/login路径
            .csrf(csrf -> csrf.disable()) // API场景下关闭CSRF
            .authorizeHttpRequests(auth -> auth
                .anyRequest().authenticated() // /login必须经过认证
            )
            .httpBasic(basic -> basic
                .authenticationManager(ldapAuthenticationManager()) // 绑定LDAP认证管理器
            );
        return http.build();
    }

    // LDAP认证管理器配置
    @Bean
    public AuthenticationManager ldapAuthenticationManager() throws Exception {
        return AuthenticationManagerBuilder.newInstance()
            .ldapAuthentication()
            .userDnPatterns("uid={0},ou=users") // 根据你的LDAP结构调整
            .groupSearchBase("ou=groups")
            .contextSource()
            .url("ldap://localhost:389/dc=example,dc=com") // 你的LDAP服务地址
            .and()
            .build();
    }
}

步骤2:配置JWT专属过滤器链(处理所有非/login路径)

创建优先级稍低的过滤器链,匹配除/login外的所有路径,添加你的自定义JWT过滤器:

// 继续在SecurityConfig类中添加
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

// 2. JWT认证专用过滤器链:处理所有非/login路径
@Bean
@Order(2)
public SecurityFilterChain jwtFilterChain(HttpSecurity http, JwtAuthenticationFilter jwtAuthFilter) throws Exception {
    http
        .securityMatcher("/**") // 匹配所有路径,但/login已被前面的链处理,不会进入此链
        .csrf(csrf -> csrf.disable())
        .authorizeHttpRequests(auth -> auth
            .anyRequest().authenticated() // 所有非/login路径必须经过JWT认证
        )
        .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class) // 添加自定义JWT过滤器
        .sessionManagement(session -> session
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS) // JWT无需会话,设置为无状态
        );
    return http.build();
}

为什么这样配置能解决问题?

Spring Security会按照@Order的优先级从小到大匹配过滤器链:

  • 当请求是/login时,会优先匹配@Order(1)的LDAP链,只会执行Basic Auth和LDAP认证逻辑,不会触发JWT过滤器;
  • 当请求是其他路径时,会匹配@Order(2)的JWT链,只会执行自定义JWT过滤器,不会进入LDAP链的逻辑,彻底避免了过滤器冲突。

注意事项

  1. 确保@Order的顺序正确:LDAP链的优先级必须高于JWT链,否则/login会被JWT链先匹配;
  2. 调整LDAP配置中的userDnPatterns、contextSource.url等参数,匹配你的实际LDAP服务器结构;
  3. 如果你的JWT过滤器需要自定义认证逻辑,确保在配置类中正确注入JwtAuthenticationFilter。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 02:22:42