Spring的跨域的几个方案

网友投稿 264 2022-08-27


Spring的跨域的几个方案

目录1.@CrossOrigin2.addCorsMappings3.CorsFIlter

1.@CrossOrigin

@CrossOrigin可以添加到方法上,也可以添加到Controller上

AbstractHandlerMethodMapping的内部类MappingRegistry的register:

public void register(T mapping, Object handler, Method method) {

// Assert that the handler method is not a suspending one.

if (KotlinDetector.isKotlinType(method.getDeclaringClass())) {

Class>[] parameterTypes = method.getParameterTypes();

if ((parameterTypes.length > 0) && "kotlin.coroutines.Continuation".equals(parameterTypes[parameterTypes.length - 1].getName())) {

throw new IllegalStateException("Unsupported suspending handler method detected: " + method);

}

}

this.readWriteLock.writeLock().lock();

try {

HandlerMethod handlerMethod = createHandlerMethod(handler, method);

validateMethodMapping(handlerMethod, mapping);

this.mappingLookup.put(mapping, handlerMethod);

List directUrls = getDirectUrls(mapping);

for (String url : directUrls) {

this.urlLookup.add(url, mapping);

}

String name = null;

if (getNamingStrategy() != null) {

name = getNamingStrategy().getName(handlerMethod, mapping);

addMappingName(name, handlerMethod);

}

CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping);

if (corsConfig != null) {

this.corsLookup.put(handlerMethod, corsConfig);

}

this.registry.put(mapping, new MappingRegistration<>(mapping, handlerMethod, directUrls, name));

}

finally {

this.readWriteLock.writeLock().unlock();

}

}

@CrossOrigin 注解在AbstractHandlerMethodMapping的内部类MappingRegistry的register方法中完成解析,@CrossOrigin注解中的内容会被解析成一个配置对象CorsConfiguration将@CrossOrigin所标记的请求方法对象HandlerMethod和CorsConfiguration一一对应存入corsLookup的map集合中当请求到达DispatcherServlet的doDispatch方法之后,调用AbstractHandlerMapping的getHandler方法获取执行链HandlerExecutionChain时,会从map中获取CorsConfiguration对象根据获取到的CorsConfiguration对象构建一个CorsInterceptor拦截器在CorsInterceptor拦截器中触发对CorsProcessor的processRequest方法调用,跨域请求的校验工作将在该方法中完成。

2.addCorsMappings

@CrossOrigin是添加在不同的Controller中 全局配置

@Configuration

public class WebMvcConfig implements WebMvcConfigurer {

@Override

public void addCorsMappings(CorsRegistry registry) {

registry.addMapping("/**")

.allowedMethods("*")

.allowedOrigins("*")

.allowedHeaders("*")

.allowCredentials(false)

.exposedHeaders("")

.maxAge(3600);

}

}

全局配置和@CrossOrigin注解相同,都是在CorsInterceptor拦截器中触发对CorsProcessor的processRequest方法调用,最终在该方法中完成跨域请求的校验工作

registry.addMapping(“/**”)方法中配置了一个CorsRegistration对象,该对象中包含了一个路径拦截规则,同时CorsRegistration还包含了一个CorsConfiguration配置对象,该对象用来保存这里跨域相关的配置。在WebMvcConfigurationSupport的requestMappingHandlerMapping方法中触发了addCorsMappings方法执行,将获取到的CorsRegistration对象重新组装成一个UrlBasedCorsConfigurationSource对象,该对象保存了拦截规则和CorsConfiguration对象的映射关系。将新建的UrlBasedCorsConfigurationSource对象赋值给AbstractHandlerMapping的corsConfigurationSource属性当请求到达时的处理方法和@CrossOrigin注解处理流程一样,在AbstractHandlerMapping的getHandler方法处理,从corsConfigurationSource中获取CorsConfiguration配置对象,而@CrossOrigin从map中获取CorsConfiguration对象。如果两处都可以获取到CorsConfiguration对象,则获取到的对象属性值进行合并。根据获取到的CorsConfiguration对象构造CorsInterceptor拦截器在CorsInterceptor拦截器中触发对CorsProcessor的processRequest方法调用,跨域请求的校验工作将在该方法中完成。

这里的跨域校验是通过DispatcherServlet中的方法触发的,DispatcherServlet在Filter之后执行

3.CorsFIlter

@Configuration

public class WebMvcConfig {

@Bean

FilterRegistrationBean corsFilter() {

FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();

CorsConfiguration corsConfiguration = new CorsConfiguration();

corsConfiguration.setAllowedHeaders(Arrays.asList("*"));

corsConfiguration.setAllowedMethods(Arrays.asList("*"));

corsConfiguration.setAllowedOrigins(Arrays.asList("http://localhost:8081"));

corsConfiguration.setMaxAge(3600L);

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

source.registerCorsConfiguration("http:///**", corsConfiguration);

registrationBean.setFilter(new CorsFilter(source));

registrationBean.setOrder(-1);

return registrationBean;

}

}

手动创建CorsConfiguration对象创建UrlBasedCorsConfigurationSource对象,将过滤器的拦截规则和CorsConfiguration对象之间的映射关系由UrlBasedCorsConfigurationSource中的corsConfiguration变量保存起来。最后创建CorsFilter 设置优先级

CorsFilter的doFilterInternal方法:

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

CorsConfiguration corsConfiguration = this.configSource.getCorsConfiguration(request);

boolean isValid = this.processor.processRequest(corsConfiguration, request, response);

if (isValid && !CorsUtils.isPreFlightRequest(request)) {

filterChain.doFilter(request, response);

}

}

触发对CorsProcessor的processRequest方法调用,跨域请求的校验工作将在该方法中完成


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:接口自动化测试世界里的“身份证”—测试工具Jmeter实践篇,Postman接口自动化测试
下一篇:Python真的适合初学者吗?原因是什么?(小白学python有用吗?)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~