最近在开发项目的时候遇到了一个坑,折腾了两天,但是最后试了很多办法还是没有解决,哈哈。
项目最近需要上https ,所以同事在网关支持了https ,后来发现后台微服务通过OpenFeign 调用的接口出现了问题。
1. 第一个问题是 feign 远程调用了网关的接口是https ,但是本服务是没有支持https 的.
提示Error: Hostname/IP doesn't match certificate's altnames等,临时的解决办法是设置了opfenfein 临时绕过ssl 的验证,但是这种办法谨慎使用!!,会存在安全问题。正确的办法是本服务支持ssl 并信任网关服务的ssl 证书,这个方法浅试了一下,貌似没有成功,所以使用了临时办法。忽略ssl 验证代码如下:
@Configuration
public class Ignore {
@Bean
public Client feignClient() {
return new Client.Default(getSSLSocketFactory(), new NoopHostnameVerifier());
}
private SSLSocketFactory getSSLSocketFactory() {
try {
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
return sslContext.getSocketFactory();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
2.第二个问题 网关新增了Origin 的请求头,本服务源代码使用了httpUtil 的工具进行请求,这个工具发起的请求适合于没有添加请求头的情况,所以使用了httprequest
HttpRequest.get(url).header("Origin", openFeignProperties.getOrigin()).execute().body()
3.修改成功之后,发现请求到网关的时候获取不到Origin 的值,但是自己额外添加的test 的请求头可以在网关获取到,以为是http 工具问题所以换了fluenthc 工具,但是使用fluent 工具出现了上面第1点的问题,所以还是放弃了,依然使用hutool 工具。
4.后来怀疑过是不是网关的过滤器有优先级 Origin 请求头被覆盖的可能(以前遇到过),排除了一下网关的链路没有存在这种情况。
5.在本服务提交请求 的时候 重新设置了 Origin,Accpect,Host 等,在网关这边发现了Accpect 的请求头是设置成功了,但是Origin 和Host 设置不成功,终于找到了问题的突破口。
网上百度了一下,说是JVM系统限制了一些特殊的请求头不允许被修改,刚好Origin 和Host 都在其中。根据百度的给出的解决方法试了几种,但是依然没有解决问题,真是服了!!!。
第一种解决方法,在本服务启动类 添加
System.setProperty("sun.net.http.allowRestrictedHeaders", "true")
没有生效,呜呜!
第二种,在本服务jvm 启动参数上加,但是也没用呢!!!
-Dsun.net.http.allowRestrictedHeaders=true
第三种说是可以在pom 文件中 加上配置,貌似也没有生效
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<systemPropertyVariables>
<sun.net.http.allowRestrictedHeaders>true</sun.net.http.allowRestrictedHeaders>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
尝试了很多种方法都是没有生效,放弃了!!!,以上记录仅供参考