浅谈CORS(跨域资源分享),并给出Spring Security处理Preflight的方法
来源:互联网 发布:量化炒股软件 编辑:程序博客网 时间:2024/06/10 04:20
我之前就写过有关AngularJS+Spring Boot在有关跨域方面的博客,但那主要是针对解决问题,而没有去分析跨域。后来我在看了多篇博客之后,在这里整理总结下我对CORS的认识。
造成跨域的主要原因是由于请求方的1、域名 2、端口与被请求方不一致。而CORS可以提供跨域的资源分享(比如一个网站需要访问另一个网站的资源,这个资源可以是一张图片,或者是一个API接口),它需要前后端共同去实现。
支持CORS的浏览器有
1、Chrome 3+
2、Firefox 3.5+
3、Opera 12+
4、Safari 4+
5、IE 8+
CORS的请求方式分两种:简单请求和非简单请求。
简单请求满足下列两点:
1、HTTP Method为下列三种:HEAD、GET、POST
2、HTTP Headers中主要包括Accept、Accept-Language、Content-Language、Last-Event-ID以及Content-Type(Content-Type只能取1application/x-www-form-urlencoded、2multipart/form-data、3text/plain这三种)。
其他情况都属于非简单请求。
像目前比较常用的JSON-P来进行GET方法的跨域,用的就是简单请求。但是如果用JSON,那肯定就是非简单请求了。
下面我们来看简单请求:
首先用Javascript发送请求时与平时一样,但是Request的内容会发生改变,下图是我引用https://www.html5rocks.com/en/tutorials/cors/中的图片。
红色框框的部分是浏览器自动给我们加上的,Origin中的值主要有协议、域名、端口这几种。注意,CORS请求肯定有Origin这个属性,但是有这个属性并不一定是CORS请求。
当服务器接受到这个请求之后,它会返回给我们一个请求,这个Response请求中会包含下面几个属性:
Access-Control-Allow-Origin属性为服务器允许跨域访问的域名、
Access-Control-Allow-Credentials为是否允许写入Cookies。这个属性大家需要注意,它是一个可选属性,但是如果你要用到Session必须要打开,,所有的Cookie都由你请求的站点来控制,你是无法通过JavaScript来管理的。
Access-Control-Expose-Headers主要携带特殊Response中Header的信息。
下面来看看非简单请求:
当我们要发送PUT、DELETE请求,或者使用Json,那我我们会发送非简单请求,下面看张图。
从这张图中我们可以看出,非简单请求在发送真正的请求前会发送一次Preflight Request,接收一个Preflight Response。(这也是Preflight恶心的地方)。
下面我们来看一个Preflight Request:
这个Preflight Request不会携带Cookie和你要传递的参数,它携带
1、Origin 告诉服务器我的域名是多少
2、Access-Control-Request-Method 我真实请求的方法是什么
3、Access-Control-Request-Headers 真实请求携带的Header中的信息
然后服务器端给我们返回一个Preflight Response
主要到这个Response返回给我们的Methods包含了GET,POST,DELETE,PUT这个4个方法,而不是我们请求的GET,那是因为PreflightResponse可以缓存一段时间,在这段时间内,非简单请求就以这个Response为参考,符合这些条件就不必再发Preflight,而是直接开始真实的请求。
然后浏览器开始发送真实的请求:
上图为真实的请求。大家注意到这个请求携带了Cookie,这是因为我在发出请求时,就设置了.withCredentials=true(如果不知道如何设置,大家可以百度)
然后服务器会给我返回相应的Response,这个Response与简单请求的差不多。
以上就是CORS请求,浏览器与服务器交互的过程,这上面的坑主要是Preflight,如果我们的后台用了安全管理框架(比如Spring Security),并且没有对Preflight这个请求做出相应的处理,那么这个请求会导致权限管控失败(比如无法登录)。因为Preflight不携带Cookie,即不携带JSESSIONID,因此Spring Security拦截器会认为你没有登录。
在用Spring Security作为安全框架的情况下,处理这种问题也是非常简单的,下面给上代码
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/login").permitAll() .requestMatchers(CorsUtils::isPreFlightRequest).permitAll()//就是这一行啦 .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/teacher/**").hasRole("TEACHER") .antMatchers("/student/**").hasRole("STUDENT") .anyRequest().authenticated() .and().formLogin().permitAll() .and().formLogin().successHandler(authenticationSuccessionHandler) .and().formLogin().failureUrl("http://localhost:63342/yjsy-ui/build/login/login.html") .and().csrf().disable(); }requestMatchers(CorsUtils::isPreFlightRequest).permitAll()的作用是将PreflightRequest不做拦截。
- 浅谈CORS(跨域资源分享),并给出Spring Security处理Preflight的方法
- 使用Spring Security中遇到的Preflight请求和跨域的问题
- Springboot通过cors解决跨域问题(解决spring security oath2的/oauth/token跨域问题)
- cors preflight问题
- Spring MVC 实现跨域资源 CORS 请求
- 什么是跨域,Cors协议,spring cors
- CORS 跨域资源访问
- 浅谈Ajax跨域的解决方案——CORS、JSONP
- Spring Boot全局支持CORS(跨源请求)的配置方法
- Spring Boot全局支持CORS(跨源请求)的配置方法
- spring 跨域问题CORS
- 求资源 慕课哪位大神有《Spring Security开发安全的REST服务》求分享
- Tomcat7 CORS(资源跨域) 解决方案一
- 1.跨域资源共享资源CORS
- cors跨域资源共享方法
- CORS实现AJAX跨域的分析以及Spring实现
- Spring MVC配置CORS(解决跨域请求)
- spring could 微服务 跨域问题(CORS )
- C语言里try的用法
- libcurl 库的ftp上传和下载代码
- 简单的二维码扫描
- UGUI字体不清楚——终极探索
- 构建nodejs环境及解决node服务器外网端口无法访问
- 浅谈CORS(跨域资源分享),并给出Spring Security处理Preflight的方法
- ueditor的配置和使用
- 【独家】加入时间特征的船舶轨迹离线压缩算法——快速Douglas-Peucker算法研究
- 乔布斯的设计理念
- 【Java多线程与并发库】5.线程范围内共享变量的概念与作用
- Ubuntu 16.10上找回workspaces
- UITableView常用方法、属性总结
- 使用maven构建项目,项目上有红叉提示错误,但是错误找不到
- Manipulating Files With Tcl