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

使用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自动配置的排除逻辑,只有自定义安全链生效,请求才能正常通过。

解决方案步骤

  1. 标记配置类为自动配置类
    在OAuth2ResourceServerSecurityConfiguration上添加@Configuration和@AutoConfigureAfter(SecurityAutoConfiguration.class),明确这是自动配置类,并指定在Spring Security核心自动配置之后加载:

    @Configuration
    @EnableWebSecurity
    @EnableMethodSecurity
    @RequiredArgsConstructor
    @EnableConfigurationProperties({KeycloakProperties.class})
    @AutoConfigureAfter(SecurityAutoConfiguration.class)
    public class OAuth2ResourceServerSecurityConfiguration {
        // ... 原有代码
    }
    
  2. 确认自动配置文件正确性
    检查META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,确保已正确写入配置类全限定名:

    my.company.auth.OAuth2ResourceServerSecurityConfiguration
    
  3. 排除默认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
    
  4. 提升自定义安全链优先级
    给自定义的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:22:04