在Spring Boot的自动配置中,如何定义一个CorsConfigurationSource?

后端开发 2026-07-10

我正在构建一个面向公司特定的Spring Boot自动配置。代码看起来大致是这样的:

@AutoConfiguration
@AutoConfigureBefore(SecurityAutoConfiguration.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(JwtAuthenticationConverter.class)
public class WebMvcSecurityAutoConfiguration {
  @Bean
  public JwtAuthenticationConverter jwtAuthenticationConverter() {
    JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
    converter.setJwtGrantedAuthoritiesConverter(ClaimsToRolesConverter::convert);
    return converter;
  }

  @Bean
  @ConditionalOnMissingBean
  CorsConfigurationSource corsConfigurationSource(WebMvcSecurityProperties properties) {
    CorsConfiguration configuration = new CorsConfiguration();
    Cors cors = properties.cors();
    configuration.setAllowedOrigins(cors.origins());
    configuration.setAllowedHeaders(
        cors.allowedHeaders() != null ? cors.allowedHeaders() : List.of(CorsConfiguration.ALL));
    configuration.setAllowedMethods(
        cors.allowedMethods() != null ? cors.allowedMethods() : List.of(CorsConfiguration.ALL));
    configuration.setAllowCredentials(true);
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
  }
}

当我在一个Spring Boot(3.5.x)应用中使用所得到的库时,CorsConfigurationSource 未被使用。

这是我使用它的方式:

@Bean
    SecurityFilterChain securityFilterChain(
            HttpSecurity http,
            JwtAuthenticationConverter jwtAuthenticationConverter,
            CorsConfigurationSource corsConfigurationSource
    ) throws Exception {
        return http.authorizeHttpRequests(auth ->
                auth.requestMatchers(HttpMethod.GET).permitAll()
                        .requestMatchers(HttpMethod.POST, "/api/orders").permitAll()
                        .anyRequest().authenticated())
                .oauth2ResourceServer(oauth2 -> oauth2
                        .jwt(jwt ->
                                jwt.jwtAuthenticationConverter(jwtAuthenticationConverter)
                        )
                )
                .cors(configurer -> configurer.configurationSource(corsConfigurationSource))
                .csrf(AbstractHttpConfigurer::disable)
             .build();
    }

自动配置报告也显示了这一点:

   WebMvcSecurityAutoConfiguration#corsConfigurationSource:
      Did not match:
         - @ConditionalOnMissingBean (types: org.springframework.web.cors.CorsConfigurationSource; SearchStrategy: all) found beans of type 'org.springframework.web.cors.CorsConfigurationSource' mvcHandlerMappingIntrospector (OnBeanCondition)

然而,如果在应用自身的安全配置中定义了 CorsConfigurationSource,它确实会被使用。

为什么自动配置的 CorsConfigurationSource 没有优先被采用?我也尝试在自动配置中添加 @Order(HIGHEST_PRECEDENCE),但这没有改变任何东西。

如果我移除 @ConditionalOnMissingBean,就会使用源Bean,但这也意味着应用无法通过自己的Bean覆盖自动配置,这是本应可以实现的。

解决方案

看起来解决办法是这样添加Bean名称:

  @Bean
  @ConditionalOnMissingBean(name = "corsConfigurationSource")
  CorsConfigurationSource corsConfigurationSource(WebMvcSecurityProperties properties) {
    CorsConfiguration configuration = new CorsConfiguration();
    Cors cors = properties.cors();
    configuration.setAllowedOrigins(cors.origins());
    configuration.setAllowedHeaders(
        cors.allowedHeaders() != null ? cors.allowedHeaders() : List.of(CorsConfiguration.ALL));
    configuration.setAllowedMethods(
        cors.allowedMethods() != null ? cors.allowedMethods() : List.of(CorsConfiguration.ALL));
    configuration.setAllowCredentials(true);
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
  }

这将使该Bean在应用中默认可用;如果应用本身声明了同名的Bean,自动配置会让位。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章