

zuul+security跨域Cors问题解决
source link: https://segmentfault.com/a/1190000021285275
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

zuul+security跨域Cors问题解决
简介
场景
在服务后台都会出现跨域cors问题,不过一般spring解决起来比较方便,在框架+框架的基础上,问题就显得特别明显了,各种冲突,不了解源码的运行原理,解决起来也是有心无力。
这里介绍的是zuul配置了跨域,在前端调用仍然会出现跨域的问题。
一般没有权限的接口加上cors配置就会通过跨域的问题。不过在服务间调用具有权限的功能,莫名的报跨域问题。
post特殊请求
在解决问题时发现 post
请求也有点特殊,这里也需要处理一下。
post请求分为简单请求和复杂请求。
在 CORS
中,可以使用 OPTIONS
方法发起一个预检请求,以检测实际请求是否可以被服务器所接受。预检请求报文中的 Access-Control-Request-Method
首部字段告知服务器实际请求所使用的 HTTP
方法; Access-Control-Request-Headers
首部字段告知服务器实际请求所携带的自定义首部字段。服务器基于从预检请求获得的信息来判断,是否接受接下来的实际请求。
以及 OPTIONS
未携带任何权限相关的内容,会被认证拦截,我们也得放开 OPTIONS
类型请求
功能使用
Cross 解决
之前设置很简单,习惯操作把之前的代码复制了过来,第一次操作是创建了一个 CorsFilter
bean,但是简单的请求确实通过了,不过权限接口过不了,于是按照一些资料配置了下面的代码 注入了 FilterRegistrationBean
bean 还设置了 order 加载顺序。
解决后无果 仍然和之前的效果一致。
/** * 跨域配置 C - Cross O - Origin R - Resource S - Sharing * * @author purgeyao * @since 1.0 */ @Configuration //@Order(Ordered.HIGHEST_PRECEDENCE) public class CorsConfig { @Bean public FilterRegistrationBean filterRegistrationBean() { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); final CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.setAllowedOrigins(Arrays.asList("*")); config.setAllowedHeaders(Arrays.asList("*")); config.setAllowedMethods(Arrays.asList("*")); config.setMaxAge(300L); source.registerCorsConfiguration("/**", config); CorsFilter corsFilter = new CorsFilter(source); FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(corsFilter); filterRegistrationBean.setOrder(0); return filterRegistrationBean; } }
在一些资料+源码的帮助下,尝试了下面代码:
这次实现了 CorsFilter
类 加载了 @Order
顺序为 (Ordered.HIGHEST_PRECEDENCE)
最优先。
/** * 解决 zuul+oauth2 跨域配置 C - Cross O - Origin R - Resource S - Sharing * * @author purgeyao * @since 1.0 */ @Component @Order(Ordered.HIGHEST_PRECEDENCE) public class AjaxCorsFilter extends CorsFilter { public AjaxCorsFilter() { super(configurationSource()); } private static UrlBasedCorsConfigurationSource configurationSource() { CorsConfiguration corsConfig = new CorsConfiguration(); // List<String> allowedHeaders = Arrays.asList("x-auth-token", "content-type", "X-Requested-With", "XMLHttpRequest"); List<String> exposedHeaders = Arrays .asList("x-auth-token", "content-type", "X-Requested-With", "XMLHttpRequest"); // List<String> allowedMethods = Arrays.asList("POST", "GET", "DELETE", "PUT", "OPTIONS"); List<String> allowedHeaders = Arrays.asList("*"); List<String> allowedMethods = Arrays.asList("*"); List<String> allowedOrigins = Arrays.asList("*"); corsConfig.setAllowedHeaders(allowedHeaders); corsConfig.setAllowedMethods(allowedMethods); corsConfig.setAllowedOrigins(allowedOrigins); corsConfig.setExposedHeaders(exposedHeaders); corsConfig.setMaxAge(36000L); corsConfig.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", corsConfig); return source; } }
哈哈哈,解决了,但是有没有感觉到莫名其妙啊,经过了解
发现其实只是一个加载顺序的问题,我们上面注入的 FilterRegistrationBean
也可以使用的,只是在设置order的时候有点问题 需要设置比 security
优先级高,改为 Ordered.HIGHEST_PRECEDENCE
发现成功可以通过跨域了。
/** * 跨域配置 C - Cross O - Origin R - Resource S - Sharing * * @author purgeyao * @since 1.0 */ @Configuration //@Order(Ordered.HIGHEST_PRECEDENCE) public class CorsConfig { @Bean public FilterRegistrationBean filterRegistrationBean() { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); final CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.setAllowedOrigins(Arrays.asList("*")); config.setAllowedHeaders(Arrays.asList("*")); config.setAllowedMethods(Arrays.asList("*")); config.setMaxAge(300L); source.registerCorsConfiguration("/**", config); CorsFilter corsFilter = new CorsFilter(source); FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(corsFilter); // 设置为 Ordered.HIGHEST_PRECEDENCE filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE); return filterRegistrationBean; } }
解决解决。。。
OPTIONS请求解决
有关 [OPTIONS(NDN
web docs)]( https://developer.mozilla.org... 介绍。
在发送 post 请求 会发现在真正发送之前会有一个 OPTIONS
请求。
因 OPTIONS
为携带任何有状态的认证信息,被权限拦截下来异常,就没有之后的真正请求了。
我们只需要吧 OPTIONS
请求放开 返回200状态即可。
有很多办法做到,可以在zuul网关放过,也可以通过 security
添加 忽略拦截列表。
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { ... @Override protected void configure(HttpSecurity http) throws Exception { ... // 添加忽略拦截OPTIONS 类型的请求 http.authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll(); ... } }
万事大吉。
总结
简单的bug解决起来简单点,不过遇到交集的bug,有心无力的感觉,莫名其妙的问题,需要耐心观察源码运行原理。
Recommend
-
82
跨域资源共享(Cross-Origin Resource Sharing)是一种机制,它使用额外的 HTTP 头部告诉浏览器可以让一个web应用进行跨域资源请求。 请求类型 简单请求 若一个请求同时满足下述所有条件,则该请求可视为“简单请求”(注:灰色字体内容
-
41
Springboot CORS跨域访问 什么是跨域 浏览器的同源策略限制: 它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针...
-
17
我们通常提到跨域问题的时候,相信大家首先会想到的是 CORS (跨源资源共享),其实 CORS 只是众多跨域访问场...
-
9
Django 通过设置 CORS 解决跨域问题 一、Ajax 跨域请求Ajax 请求一个目标地址为非本域(协议、主机、端口任意一个不同)的 web 资源。 前端http://192.168.10.50:8080 后端
-
11
源代码探案系列之 .NET Core 跨域中间件 CORS2021-03-1632 25 min.本文是 #源代码探案系列# 第三篇,今天这篇博客,我们来一起解读下 ASP.NET Core 中的
-
5
11 April 2020 / 开发笔记 Nginx 配置允许跨域访问 CORS 原文地址: https://en...
-
9
什么是跨域资源共享呢? 我们知道一个域是由scheme、domain和port三部分来组成的,这三个部分可以唯一标记一个域,或者一个服务器请求的地址。跨域资源共享的意思就是服务器允许其他的域来访问它自己域的资源。CORS是一个基于HTTP-header检测的机制,本文...
-
5
解决CORS跨域资源共享问题 2022年9月13日 · 1 day ago ...
-
10
Golang iris 解决CORS跨域问题 韬大帅 · 2019-12-16 11:32:45 · 4738 次点击 · 预计阅读时间不到 1 分钟 · 大约8小时之前 开始浏览 ...
-
9
解决ajax post提交 跨域 cors问题 2023年 8月 一 二 三 ...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK