Spring 跨域使用与原理(@CrossOrigin注解,Java配置类方式,xml方式)

Spring CORS 跨域使用与原理(@CrossOrigin注解,Java配置类方式,xml方式)

出于安全原因,浏览器禁止AJAX调用当前源之外的资源。

跨域资源共享(CORS)是由大多数浏览器实现的W3C规范,它允许您以一种灵活的方式指定授权哪种跨域请求,而不是使用一些不太安全、功能不太强大的hack(如IFrame或JSONP)。

Spring Framework 4.2 GA为CORS提供了一流的开箱即用支持,为我们提供了一种比典型的基于过滤器的解决方案更简单、更强大的配置方式。

一、注解方式使用

1.方法上添加@CrossOrigin注解
@RestController
@RequestMapping("/account")
public class AccountController {

	@CrossOrigin
	@GetMapping("/{id}")
	public Account retrieve(@PathVariable Long id) {
		// ...
	}

	@DeleteMapping("/{id}")
	public void remove(@PathVariable Long id) {
		// ...
	}
}

使用此种方式只会对当前方法生效。

2.Controller上添加@CrossOrigin注解
@CrossOrigin
@RestController
@RequestMapping("/account")
public class AccountController {

	@GetMapping("/{id}")
	public Account retrieve(@PathVariable Long id) {
		// ...
	}

	@DeleteMapping("/{id}")
	public void remove(@PathVariable Long id) {
		// ...
	}
}

使用此种方式会对整个Controller生效。

3.@CrossOrigin的两个参数使用
  1. origins: 允许可访问的域列表
  2. maxAge:准备响应前的缓存持续的最大时间(以秒为单位)
@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

	@GetMapping("/{id}")
	public Account retrieve(@PathVariable Long id) {
		// ...
	}

	@DeleteMapping("/{id}")
	public void remove(@PathVariable Long id) {
		// ...
	}
}

这两个参数也可以分开单独使用,如下所示:

@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

	@CrossOrigin(origins = "http://domain2.com")
	@GetMapping("/{id}")
	public Account retrieve(@PathVariable Long id) {
		// ...
	}

	@DeleteMapping("/{id}")
	public void remove(@PathVariable Long id) {
		// ...
	}
}
4.注意事项

如果有正在使用Spring Security,需要在Spring Security中启用CORS,以允许它利用Spring MVC定义的配置。如下所示:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.cors().and()...
	}
}

二、CORS全局配置使用

除了细粒度的、基于注释的配置之外,我们还可以自定义一些全局CORS配置。类似于使用过滤器,但可以在Spring MVC中声明,并结合细粒度的@CrossOrigin配置。默认情况下,所有的origin和GET、HEAD和POST方法都可以使用。

1.Java配置类方式

使用非常简单,如下所示:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

	@Override
	public void addCorsMappings(CorsRegistry registry) {
		registry.addMapping("/**");
	}
}

如果是使用的Spring Boot,建议只声明一个WebMvcConfigurer bean,如下所示:

@Configuration
public class MyConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**");
            }
        };
    }
}

除此之外,我们还可以自定义更多的其他属性,比如将CORS配置应用于特定的路径模式:

@Override
public void addCorsMappings(CorsRegistry registry) {
	registry.addMapping("/api/**")
		.allowedOrigins("http://domain2.com")
		.allowedMethods("PUT", "DELETE")
			.allowedHeaders("header1", "header2", "header3")
		.exposedHeaders("header1", "header2")
		.allowCredentials(false).maxAge(3600);
}

同样,此处我们要注意Spring Security使用的情况,具体实现参考注解使用中的实现。

2.XML配置文件方式

当然,我们也可以使用xml配置文件的方式来进行全局配置,如下所示:

<mvc:cors>
	<mvc:mapping path="/**" />
</mvc:cors>

同样也可以在xml中自定义CORS映射,如下所示:

<mvc:cors>

	<mvc:mapping path="/api/**"
		allowed-origins="http://domain1.com, http://domain2.com"
		allowed-methods="GET, PUT"
		allowed-headers="header1, header2, header3"
		exposed-headers="header1, header2" allow-credentials="false"
		max-age="123" />

	<mvc:mapping path="/resources/**"
		allowed-origins="http://domain1.com" />

</mvc:cors>

三、原理解释

CORS请求(包括带有OPTIONS方法的飞行前请求)被自动分派给已注册的各种HandlerMappings。它们处理CORS预飞行请求,并通过CorsProcessor实现(默认为DefaultCorsProcessor)拦截CORS简单和实际请求,以便添加相关的CORS响应头(如Access-Control-Allow-Origin)。CorsConfiguration允许您指定应该如何处理CORS请求:allowed origins, headers, methods, etc等。

可以通过多种方式提供,如:

  • AbstractHandlerMapping#setCorsConfiguration()允许在路径模式(如/api/)上指定多个CorsConfiguration映射的Map
  • 子类可以通过重写AbstractHandlerMapping#getCorsConfiguration(Object, HttpServletRequest)方法来提供他们自己的CorsConfiguration
  • 处理程序可以实现CorsConfigurationSource接口(就像ResourceHttpRequestHandler现在做的那样),以便为每个请求提供CorsConfiguration。

除此之外,还可以使用基于CORS的过滤器支持,作为上述其他方法的替代方案,Spring Framework还提供了CorsFilter。在这种情况下,不使用@CrossOrigin或WebMvcConfigurer# addcorsmapping (CorsRegistry),我们可以像下面这样在Spring Boot中声明过滤器:

@Configuration
public class MyConfiguration {

	@Bean
	public FilterRegistrationBean corsFilter() {
		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		CorsConfiguration config = new CorsConfiguration();
		config.setAllowCredentials(true);
		config.addAllowedOrigin("http://domain1.com");
		config.addAllowedHeader("*");
		config.addAllowedMethod("*");
		source.registerCorsConfiguration("/**", config);
		FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
		bean.setOrder(0);
		return bean;
	}
}

以上内容参考自Spring官方文档:https://spring.io/blog/2015/06/08/cors-support-in-spring-framework

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值