解决跨域请求,NG返回403(403并不一定是NG问题)

 更新时间:2023年12月26日 09:30:28   作者:zero  
这篇文章主要介绍了解决跨域请求,NG返回403(403并不一定是NG问题),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

先说问题怎么解决的

1.ng返回403的情况也就那么几种,百度一下都能找到,但是ng返回403不一定是ng的问题。

2.最终发现是在网关跨域配置中,没有加上请求方的域名。

3.想探索的可以看看文章

背景

和合作方对接,我们这边的app开发完放在合作方的服务器上,再通过NG,请求我这边的后台。

NG配置跨域等信息后(这个很容易找,百度随便都能找到),发现测试环境一切正常,但是到了生产,NG一直返回403。

请求都没通过,网关zuul没有日志。双方开始排查NG,百度了无数次。

最后都配置与测试环境一直,但是生产一直不通。

返回403,加上zuul没日志,一直定位在NG跨域的问题上。

解决

最后发现是zuul项目的问题,SpringBoot跨域问题。

尝试排查是否zuul的问题,对比了测试环境和生产的。

测试环境zuul的跨域配置CorsConfiguration类属性allowedOrigins赋值了个*,生产是针对地址进行配置的。

其实就是SpringBoot的跨域配置,源码CorsConfiguration的allowedOrigins属性没有加上第三方的域名地址。

导致直接被拒绝了。加上合作方地址,问题解决。

源码解析

在配置跨域问题时,我们需要对CorsConfiguration属性赋值

//对CorsConfiguration属性赋值
private CorsConfiguration corsConfig(Map.Entry<String, JawsCorsConfig> entry) {
    CorsConfiguration corsConfiguration = new CorsConfiguration();
    corsConfiguration.setAllowedOrigins(Splitter.on(",").splitToList(entry.getValue().getAllowedOrigins()));
    corsConfiguration.setAllowedHeaders(Splitter.on(",").splitToList(entry.getValue().getAllowedHeaders()));
    corsConfiguration.setAllowedMethods(Splitter.on(",").splitToList(entry.getValue().getAllowedMethods()));
    corsConfiguration.setAllowCredentials(entry.getValue().getAllowCredentials());
    corsConfiguration.setMaxAge(entry.getValue().getMaxAge());
    return corsConfiguration;
}

@Bean
    public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    for (Map.Entry<String, JawsCorsConfig> entry : jawsZuulProperites.getCors().entrySet()) {
        source.registerCorsConfiguration(entry.getValue().getUrls(), corsConfig(entry));
    }
    return new CorsFilter(source);
}

源码中 org.springframework.web.cors.DefaultCorsProcessor#handleInternal 方法

protected boolean handleInternal(ServerHttpRequest request, ServerHttpResponse response,
			CorsConfiguration config, boolean preFlightRequest) throws IOException {

		String requestOrigin = request.getHeaders().getOrigin();
		String allowOrigin = checkOrigin(config, requestOrigin);

		HttpMethod requestMethod = getMethodToUse(request, preFlightRequest);
		List<HttpMethod> allowMethods = checkMethods(config, requestMethod);

		List<String> requestHeaders = getHeadersToUse(request, preFlightRequest);
		List<String> allowHeaders = checkHeaders(config, requestHeaders);

		if (allowOrigin == null || allowMethods == null || (preFlightRequest && allowHeaders == null)) {
			rejectRequest(response);
			return false;
		}

		HttpHeaders responseHeaders = response.getHeaders();
		responseHeaders.setAccessControlAllowOrigin(allowOrigin);
		responseHeaders.add(HttpHeaders.VARY, HttpHeaders.ORIGIN);

		if (preFlightRequest) {
			responseHeaders.setAccessControlAllowMethods(allowMethods);
		}

		if (preFlightRequest && !allowHeaders.isEmpty()) {
			responseHeaders.setAccessControlAllowHeaders(allowHeaders);
		}

		if (!CollectionUtils.isEmpty(config.getExposedHeaders())) {
			responseHeaders.setAccessControlExposeHeaders(config.getExposedHeaders());
		}

		if (Boolean.TRUE.equals(config.getAllowCredentials())) {
			responseHeaders.setAccessControlAllowCredentials(true);
		}

		if (preFlightRequest && config.getMaxAge() != null) {
			responseHeaders.setAccessControlMaxAge(config.getMaxAge());
		}

		response.flush();
		return true;
	}
	

进入checkOrigin(config, requestOrigin);校验请求来源

	public static final String ALL = "*";
	/**
	 * Check the origin of the request against the configured allowed origins.
	 * @param requestOrigin the origin to check
	 * @return the origin to use for the response, or {@code null} which
	 * means the request origin is not allowed
	 */
	public String checkOrigin(String requestOrigin) {
		if (!StringUtils.hasText(requestOrigin)) {
			return null;
		}
		if (ObjectUtils.isEmpty(this.allowedOrigins)) {
			return null;
		}

		if (this.allowedOrigins.contains(ALL)) {
			if (this.allowCredentials != Boolean.TRUE) {
				return ALL;
			}
			else {
				return requestOrigin;
			}
		}
//遍历我们赋值的allowedOrigins,判断请求来源是否包含,包含则返回
		for (String allowedOrigin : this.allowedOrigins) {
			if (requestOrigin.equalsIgnoreCase(allowedOrigin)) {
				return requestOrigin;
			}
		}
return null;
}
		

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 学习Java之File文件操作方法

    学习Java之File文件操作方法

    这篇文章我们主要学习如何实现IO流的具体操作,但很多时候,IO流都会操作一个文件,所以我们需要先学习在Java中如何操作文件,包括文件及文件夹的创建、遍历、删除等,有了文件操作的基础,我们才能更好地操作IO流,文中有详细的代码示例,需要的朋友可以参考下
    2023-09-09
  • java遍历http请求request的所有参数实现方法

    java遍历http请求request的所有参数实现方法

    下面小编就为大家带来一篇java遍历http请求request的所有参数实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • Java开发Oracle数据库连接JDBC Thin Driver 的三种方法

    Java开发Oracle数据库连接JDBC Thin Driver 的三种方法

    这篇文章主要介绍了Java开发Oracle数据库连接JDBC Thin Driver 的三种方法,需要的朋友可以参考下
    2015-12-12
  • 浅谈Java序列化和hessian序列化的差异

    浅谈Java序列化和hessian序列化的差异

    这篇文章主要通过对二者简单的实现方式的对比,介绍了Java序列化和hessian序列化的差异,具有一定参考价值,需要的朋友可以了解下。
    2017-09-09
  • SpringCloud OpenFeign Post请求400错误解决方案

    SpringCloud OpenFeign Post请求400错误解决方案

    这篇文章主要介绍了SpringCloud OpenFeign Post请求400错误解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • SpringBoot之那些注入不了的Spring占位符(${}表达式)问题

    SpringBoot之那些注入不了的Spring占位符(${}表达式)问题

    这篇文章主要介绍了SpringBoot之那些注入不了的Spring占位符(${}表达式)问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • 子类继承父类时构造函数相关问题解析

    子类继承父类时构造函数相关问题解析

    这篇文章主要介绍了子类继承父类时构造函数相关问题解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • 学习Java之二叉树的编码实现过程详解

    学习Java之二叉树的编码实现过程详解

    本文将通过代码来进行二叉树的编码实现,文中的代码示例介绍的非常详细,对我们学习Java二叉树有一定的帮助,感兴趣的同学跟着小编一起来看看吧
    2023-08-08
  • 浅谈线程的几种可用状态

    浅谈线程的几种可用状态

    下面小编就为大家带来一篇浅谈线程的几种可用状态。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • 详解JAVA使用Comparator接口实现自定义排序

    详解JAVA使用Comparator接口实现自定义排序

    这篇文章主要介绍了JAVA使用Comparator接口实现自定义排序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03

最新评论