配置多套Spring Security时SAML与Basic认证无法同时生效问题咨询
问题根因
- 多个
WebSecurityConfigurerAdapter未配置专属的requestMatcher,高优先级的过滤器链会默认拦截所有请求,低优先级的链永远不会被触发 - 原始
BasicConfig中没有显式开启Basic认证过滤器,也未配置对应认证逻辑,导致尝试Basic认证时直接返回403 forbidden - 两个配置类的构造函数名称与类名不匹配,属于语法错误,会导致配置类初始化异常,是效果偶发不稳定的核心诱因
- 修改后的
BasicConfig新增antMatchers("/**").permitAll()配置,直接绕过了所有认证逻辑,破坏了SAML的正常认证流程
修复方案
核心思路是用请求头匹配逻辑区分两个过滤器链的生效场景:携带Basic认证头的请求走Basic认证链,其余请求走SAML认证链,两个链互不干扰,所有业务端点同时支持两种认证方式。
修复后完整配置如下:
import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher; import org.springframework.security.web.util.matcher.OrRequestMatcher; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @Configuration @EnableWebSecurity public class SecurityConfig { @Value("${enable_csrf}") private Boolean enableCsrf; @Autowired private SamlUserService samlUserService; // 替换为你自己实现的Basic认证用户查询服务 @Autowired private UserDetailsService basicUserDetailsService; @Configuration @Order(1) public static class BasicConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // 匹配规则:携带Basic认证头的请求 + /secure/basic登录页请求 http.requestMatcher(new OrRequestMatcher( new RequestHeaderRequestMatcher("Authorization", "Basic *"), new AntPathRequestMatcher("/secure/basic") )) .authorizeRequests() .antMatchers("/secure/basic").permitAll() .anyRequest().authenticated() .and() // 开启Basic认证能力 .httpBasic() .and() .userDetailsService(basicUserDetailsService); if (!enableCsrf) { http.csrf().disable(); } } } @Configuration @Order(2) public static class SamlConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/secure/sso").permitAll() .antMatchers("/saml/**").permitAll() .anyRequest().authenticated() .and() .apply(saml()) .userDetailsService(samlUserService) .serviceProvider() .keyStore() .storeFilePath("path") .password("password") .keyname("alias") .keyPassword("password") .and() .protocol("https") .hostname(String.format("%s:%s","localhost", "8080")) .basePath("/") .and() .identityProvider() .metadataFilePath("metadata"); if (!enableCsrf) { http.csrf().disable(); } } } }
配置说明
- Basic认证链仅对匹配规则内的请求生效,其余所有请求走SAML认证逻辑,两个链不会产生冲突
- 显式开启了Basic认证过滤器,配置了对应的用户查询服务,可正常处理Basic认证请求
- 修正了原配置中构造函数名称不匹配、参数未注入的问题,消除了配置初始化异常导致的不稳定问题
- 两个登录入口
/secure/sso和/secure/basic均可正常访问,所有业务端点同时支持两种认证方式
内容的提问来源于stack exchange,提问作者cunglabuon
相关产品推荐
相关产品推荐

