在Spring Boot的自动配置中,如何定义一个CorsConfigurationSource?
我正在构建一个面向公司特定的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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。