【发布时间】:2020-06-02 17:10:38
【问题描述】:
我的设置
我使用多个 Spring Boot 应用程序作为微服务构建了我的项目。还有另一个称为 api-gateway 的 Spring Boot 应用程序,它充当所有其他微服务的反向代理。我为此使用 ZuulProxy。每个微服务都有自己的带有不同端口的 tomcat,api-gateway 会通过这些端口路由流量。微服务通过 http 相互通信。
我正在将微服务和 api-gatway 构建为 docker 容器。这是我的后端设置。
我有一个用 html、angularjs 开发的 web 客户端,它也作为 docker 容器运行。此 Web 应用程序通过 http REST 调用后端 API。这个容器是一个暴露 80 端口的 apache 容器。
因此,当有人点击 http://example.com 时,它会到达 Web 应用容器并加载 UI。此 UI 使用 http://api-example.com/* 进行 REST 调用。因此,在 apache 容器(httpd.conf)中,我添加了这样的 VirtualHosts。
<VirtualHost *:80>
ServerName example.com
DocumentRoot "<path to my UI files>"
</VirtualHost>
<VirtualHost *:80>
ServerName api-example.com
ProxyPass / http://apigateway:8081/
ProxyPassReverse / http://apigateway:8081/
</VirtualHost>
问题
一切都在 http 上按预期工作。但是为此设置启用 SSL 的正确方法是什么。
我尝试了什么
我购买了证书并在 Web 应用程序容器中进行了配置,并且 UI 在浏览器中通过 https 加载正常。因为,我在 UI 中使用 http://api-example.com/* 进行 api 调用,所以浏览器向我抛出错误,说安全应用程序中的非安全调用。因此,我在 UI 代码中将 api url 更改为 https。为此,我在 httpd.conf 中添加了一个 VirtualHost,如下所示
<VirtualHost *:443>
ServerName api-example.com
ProxyPass / http://apigateway:8081/ timeout=600
ProxyPassReverse / http://apigateway:8081/ timeout=600
</VirtualHost>
整个事情都部署在服务器中。而且我可以从我的浏览器通过 https 访问应用程序。 但是,它不适用于其他笔记本电脑。它有时会工作,但在其余时间会失败,在 UI 访问 https://api-example.com/ 时出现 CORS 错误。
浏览器控制台中的完全错误: 在“https://api-example.com/api/auth/login?”访问 XMLHttpRequest来自原点“https://example.com”的 CORS 策略已阻止:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。
顺便说一句,我的 api-gateway 中还有以下代码来遵守 CORS
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedHeader("Access-Control-Allow-Origin");
config.addExposedHeader("X-AuthToken"); //This is must for browser to read X-AuthToken header
config.addExposedHeader("X-filename"); //This is must for browser to read X-filename header
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
这看起来很奇怪,因为我的浏览器中没有出现此错误。我的同事尝试了所有其他浏览器并清除了浏览器缓存。
所以,我怀疑我做这个架构的方式。有人可以告诉我我犯了什么错误或建议一种更好的方法来设置这样的东西。
注意:我现在希望将所有服务和 Web 应用程序放在同一台机器上。
【问题讨论】:
-
你能按照下面的方法进行midify,看看它是否有效?我怀疑 source.registerCorsConfiguration("/*", config);有问题。 config.setAllowCredentials(true); config.addAllowedOrigin(""); config.addAllowedHeader(""); config.addAllowedMethod(""); source.registerCorsConfiguration("", config);
标签: apache spring-boot ssl microservices