Spring Security之跨域和CORS

1.跨域

跨域,实质上是浏览器的一种保护处理。如果产生了跨域,服务器在返回结果时就会被浏览器拦截(注意:此时请求是可以正常发起的,只是浏览器对其进行了拦截),导致响应的内容不可用

1.1 产生跨域的几种情况

Spring Security之跨域和CORS_第1张图片
也就是请求的URL和页面所在的URL的首部不同时就会产生跨域

1.2 解决跨域之JSONP

实现原理:
浏览器允许一些带src属性的标签跨域,也就是在某些标签的src属性上写url地址是不会产生跨域问题

第一步:使用script标签去加载json信息

<script src="http://test/json"></script>

这样就可以获取到信息了

第二步:后台将返回的数据进行包装

jsonp({
	"name":"test",
	"age":"123"
})

而对于JS而言,这个其实就对应一个普通的函数调用:

jsonp(...params)

所以需要定义一个jsonp函数:

var jsonp = function (data){
	console.log(data)
}

第三步:后台与前台约定返回jsonp格式的条件

可以约定一个callback参数来指定是否返回jsonp格式的数据

http://test?callback=jsonp

后台可以根据这个参数来决定返回什么格式的数据

1.3 CORS解决跨域

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

浏览器在发起真正的请求之前,会发起一个OPTIONS类型的预检请求,用于请求服务器是否允许跨域,在得到许可的情况下才会发起 Real Request

常用的几种CORS请求头

Access-Control-Allow-Origin

取值表示允许的站点,使用URL首部匹配原则

Access-Control-Allow-Origin: http://test

Access-Control-Allow-Origin: *    //匹配所有站点

Access-Control-Allow-Methods

仅仅在预检请求的响应中指定有效,用于表明服务器允许可跨域的方法类型,多个方法用逗号隔开

Access-Control-Allow-Headers

仅仅在预检有效,用于表明服务器允许携带的首部字段,如果请求头里面有其中没有的头类型,则不允许跨域

Access-Control-Max-Age 、

表示此次预检请求的有效期,在有效期内,预检请求不需要再次发起

CORS控制场景

浏览器将请求分为两类,一类是简单请求,一类是非简单请求,满足下列条件的就是简单请求,否则即使非简单请求:

1、请求方式:HEAD、GET、POST
    2、请求头信息:
        Accept
        Accept-Language
        Content-Language
        Last-Event-ID
        Content-Type 对应的值是以下三个中的任意一个
                                application/x-www-form-urlencoded
                                multipart/form-data
                                text/plain
 
注意:同时满足以上两个条件时,则是简单请求,否则为复杂请求

简单请求和复杂请求的区别:

简单请求:一次请求
非简单请求:两次请求,在发送数据之前会先发第一次请求做预检,只有预检通过后在发一次请求作为数据传输。

关于预检请求:

请求方式:OPTIONS
“预检”其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息
如何“预检”
 => 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过
    Access-Control-Request-Method
 => 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过
    Access-Control-Request-Headers

2.基于Spring Security的CORS支持

首先编写一个配置源:

@Bean
public CorsConfigurationSource corsConfigurationSource(){
	CorsConfigurationSource corsConfigurationSource = new CorsConfigurationSource();
	// 设置Access-Control-Allow-Origin
	corsConfigurationSource .setAllowedOrigins(Arrays.asList("http://www.baidu.com"));
	// 设置Access-Control-Allow-Methods
	corsConfigurationSource .setAllowedMethods(Arrays.asList("POST","GET"));
	// 允许带凭证
	corsConfigurationSource.setAllowCredentials(true);
	// 对所有的url生效
	UrlBasedCorsConfiguratioSource source = new UrlBasedCorsConfiguratioSource ();
	source.registerCorsConfiguration("/**",corsConfigurationSource );
	return source
}

开启CORS:

http....
	// 开启CORS
	.cors()
	.and()
	......

你可能感兴趣的:(springSecurity)