概述
介绍
作为一个配置HttpSecurity的SecurityConfigurer,CorsConfigurer的配置任务如下 :
- 配置如下安全过滤器
FilterCorsFilter- 如果
CorsConfigurer上设置了属性configurationSource,则基于它创建一个CorsFilter并使用; - 否则如果名称为
corsFilter的bean存在,则使用该CorsFilter; - 否则如果名称为
corsConfigurationSource的bean存在,则基于它创建一个CorsFilter并使用; - 否则如果名称为
mvcHandlerMappingIntrospector的bean存在,则基于它创建一个CorsFilter并使用。名称为
mvcHandlerMappingIntrospector的bean存在表明Spring MVC被使用,因为使用了Spring MVC的话,Spring MVC的配置机制(WebMvcConfigurationSupport)会注册一个类型为HandlerMappingIntrospector名称为mvcHandlerMappingIntrospector的bean到容器。
- 如果
继承关系

使用
// HttpSecurity 代码片段
public CorsConfigurer<HttpSecurity> cors() throws Exception {
return getOrApply(new CorsConfigurer<>());
}
源代码
源代码版本 Spring Security Config 5.1.4.RELEASE
package org.springframework.security.config.annotation.web.configurers;
// 省略 imports
public class CorsConfigurer<H extends HttpSecurityBuilder<H>>
extends AbstractHttpConfigurer<CorsConfigurer<H>, H> {
private static final String HANDLER_MAPPING_INTROSPECTOR =
"org.springframework.web.servlet.handler.HandlerMappingIntrospector";
private static final String CORS_CONFIGURATION_SOURCE_BEAN_NAME = "corsConfigurationSource";
private static final String CORS_FILTER_BEAN_NAME = "corsFilter";
private CorsConfigurationSource configurationSource;
/**
* Creates a new instance
*
* @see HttpSecurity#cors()
*/
public CorsConfigurer() {
}
public CorsConfigurer<H> configurationSource(
CorsConfigurationSource configurationSource) {
this.configurationSource = configurationSource;
return this;
}
@Override
public void configure(H http) throws Exception {
ApplicationContext context = http.getSharedObject(ApplicationContext.class);
CorsFilter corsFilter = getCorsFilter(context);
if (corsFilter == null) {
throw new IllegalStateException(
"Please configure either a " + CORS_FILTER_BEAN_NAME + " bean or a "
+ CORS_CONFIGURATION_SOURCE_BEAN_NAME + "bean.");
}
http.addFilter(corsFilter);
}
private CorsFilter getCorsFilter(ApplicationContext context) {
if (this.configurationSource != null) {
return new CorsFilter(this.configurationSource);
}
boolean containsCorsFilter = context
.containsBeanDefinition(CORS_FILTER_BEAN_NAME);
if (containsCorsFilter) {
return context.getBean(CORS_FILTER_BEAN_NAME, CorsFilter.class);
}
boolean containsCorsSource = context
.containsBean(CORS_CONFIGURATION_SOURCE_BEAN_NAME);
if (containsCorsSource) {
CorsConfigurationSource configurationSource = context.getBean(
CORS_CONFIGURATION_SOURCE_BEAN_NAME, CorsConfigurationSource.class);
return new CorsFilter(configurationSource);
}
boolean mvcPresent = ClassUtils.isPresent(HANDLER_MAPPING_INTROSPECTOR,
context.getClassLoader());
if (mvcPresent) {
return MvcCorsFilter.getMvcCorsFilter(context);
}
return null;
}
static class MvcCorsFilter {
private static final String HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME =
"mvcHandlerMappingIntrospector";
/**
* This needs to be isolated into a separate class as Spring MVC is an optional
* dependency and will potentially cause ClassLoading issues
* @param context
* @return
*/
private static CorsFilter getMvcCorsFilter(ApplicationContext context) {
if (!context.containsBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {
throw new NoSuchBeanDefinitionException(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME,
"A Bean named " + HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME +" of type "
+ HandlerMappingIntrospector.class.getName()
+ " is required to use MvcRequestMatcher. Please ensure Spring Security & Spring MVC "
+ "are configured in a shared ApplicationContext.");
}
HandlerMappingIntrospector mappingIntrospector =
context.getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME,
HandlerMappingIntrospector.class);
return new CorsFilter(mappingIntrospector);
}
}
}
本文深入解析了Spring Security中CorsConfigurer的配置逻辑与实现细节,包括如何通过不同的方式配置CorsFilter,以及与SpringMVC的集成关系。
932

被折叠的 条评论
为什么被折叠?



