使用Spring Boot自动配置时Spring Security配置冲突问题
我正在为所有Spring项目开发通用的auth-starter,但在Demo应用中使用时遇到了以下问题:
- 通过
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports配置自动装配时,所有请求均返回403 Forbidden; - 删除该自动配置文件,在Demo应用中添加
@ComponentScan(basePackages = "my.company")后,请求可正常通过安全校验。
额外信息:
- 使用自动配置时,终端日志显示存在两个不同的
DefaultSecurityFilterChain; - 尝试添加
@AutoConfigureBefore(org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration.class)仅消除了重复日志,但403问题仍未解决; - 两种方式下都会调用自定义的
securityFilterChain方法,且Keycloak的PolicyEnforcer均可正常工作。
相关代码与配置
auth-starter安全配置类
package my.company.auth; // imports @EnableWebSecurity @EnableMethodSecurity @RequiredArgsConstructor @EnableConfigurationProperties({KeycloakProperties.class}) public class OAuth2ResourceServerSecurityConfiguration { private final KeycloakProperties keycloakProperties; @Bean public SecurityFilterChain simpleSecurityFilterChain(HttpSecurity http, ServletPolicyEnforcerFilter policyEnforcerFilter) throws Exception { http .csrf(AbstractHttpConfigurer::disable) .cors(AbstractHttpConfigurer::disable) .authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll()) .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())) .addFilterAfter(policyEnforcerFilter, BearerTokenAuthenticationFilter.class); return http.build(); } // some other code here }
auth-starter依赖配置(pom.xml)
<dependency> <artifactId>spring-boot-starter-security</artifactId> <groupId>org.springframework.boot</groupId> <version>${spring.boot.version}</version> </dependency> <dependency> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> <groupId>org.springframework.boot</groupId> <version>${spring.boot.version}</version> </dependency> <dependency> <artifactId>keycloak-policy-enforcer</artifactId> <groupId>org.keycloak</groupId> <version>${keycloak.version}</version> </dependency> <dependency> <artifactId>keycloak-core</artifactId> <groupId>org.keycloak</groupId> <version>${keycloak.version}</version> </dependency>
Demo应用依赖配置(pom.xml)
<dependency> <artifactId>auth-starter</artifactId> <groupId>my.company</groupId> <version>0.1.0-SNAPSHOT</version> </dependency>
版本信息
<spring.boot.version>3.3.1</spring.boot.version> <spring.security.version>6.3.1</spring.security.version> <spring.version>6.1.11</spring.version>
核心原因
用自动配置导入自定义安全配置时,Spring Security的默认自动配置逻辑可能仍在生效,导致多个SecurityFilterChain实例共存。即使添加@AutoConfigureBefore消除了重复日志,请求仍可能被优先级更高的默认安全链(比如默认要求认证的规则)拦截,返回403。而用@ComponentScan时,自定义的@EnableWebSecurity配置类会自动触发Spring Security自动配置的排除逻辑,只有自定义安全链生效,请求才能正常通过。
解决方案步骤
标记配置类为自动配置类
在OAuth2ResourceServerSecurityConfiguration上添加@Configuration和@AutoConfigureAfter(SecurityAutoConfiguration.class),明确这是自动配置类,并指定在Spring Security核心自动配置之后加载:@Configuration @EnableWebSecurity @EnableMethodSecurity @RequiredArgsConstructor @EnableConfigurationProperties({KeycloakProperties.class}) @AutoConfigureAfter(SecurityAutoConfiguration.class) public class OAuth2ResourceServerSecurityConfiguration { // ... 原有代码 }确认自动配置文件正确性
检查META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,确保已正确写入配置类全限定名:my.company.auth.OAuth2ResourceServerSecurityConfiguration排除默认OAuth2资源服务器自动配置
如果步骤1无效,在自动配置类上添加排除逻辑,或者在Demo应用配置中排除:// 在自动配置类上添加 @AutoConfigureBefore(OAuth2ResourceServerAutoConfiguration.class) @EnableAutoConfiguration(exclude = OAuth2ResourceServerAutoConfiguration.class)或者在Demo应用的
application.properties中添加:spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration提升自定义安全链优先级
给自定义的SecurityFilterChain设置最高优先级,确保它先被匹配:@Bean @Order(Ordered.HIGHEST_PRECEDENCE) public SecurityFilterChain simpleSecurityFilterChain(HttpSecurity http, ServletPolicyEnforcerFilter policyEnforcerFilter) throws Exception { // ... 原有代码 }
验证点
- 启动Demo应用后,查看日志确认仅加载了一个
DefaultSecurityFilterChain实例; - 测试请求,确认不再返回403,且JWT认证、Keycloak PolicyEnforcer功能正常。
内容的提问来源于stack exchange,提问作者Dinar_sd

