1

我们应用程序的后端 (API) 建立在 Grails 5.1.1 之上,并且已经在 DiginalOcean 上运行了好几年。我们现在正在尝试将基础架构迁移到 Kubernetes(也在 DO 上)。对于入口控制器,我们使用了 Ambassador Edge Stack(出于各种原因)。

现在,整个集群都已启动并运行,只是我们遇到了 CORS 问题。

注意:通过常规的 LoadBalancer(甚至是相同的图像),完全相同的代码库在 DO 上运行没有问题。

当我们将 API 切换到 Kubernetes 集群时,我们会收到缺少 CORS 标头的错误。

在细节之前,有一点历史......

起初,OPTIONS请求被拒绝,因为显然 spring-security 拒绝了这些请求。出于某种原因,我们只有在切换到 Kubernetes 时才会遇到这个问题。

我们通过添加另一个过滤器来解决这个问题(拦截器不适用于这种情况,因为它们在安全过滤器之后执行)......

铜过滤器

class CorsFilter extends OncePerRequestFilter {

    private allowedOrigins = ["http://localhost:4200",
                              "https://localhost:4200",
                              "https://app.priz.guru"]

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain chain)
            throws ServletException, IOException {

        String origin = req.getHeader('Origin')
        if (allowedOrigins.contains(origin)) {
            resp.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
            resp.addHeader("Access-Control-Max-Age", "3600")
//            resp.addHeader("Access-Control-Allow-Credentials", "true")
            resp.addHeader("Access-Control-Allow-Origin", origin)
            resp.addHeader("Access-Control-Expose-Headers", "*")
        }

        if (req.getMethod() == "OPTIONS") {
            resp.status = 200
        } else {
            chain.doFilter(req, resp)
        }
    }
}

添加到resource.groovy

optionsCorsFilter(CorsFilter)

并注册BootStrap.groovy

SpringSecurityUtils.clientRegisterFilter(
                "optionsCorsFilter",
                SecurityFilterPosition.FIRST.order - 1
        )

之后,OPTIONS请求开始按预期工作。顺便说一句,内置的 cors 过滤器仍然处于启用状态。我们可以在这一点上从技术上删除它。

一旦解决了这个问题,我们现在将面临下一个挑战。实际的 API 调用不返回 CORS 标头。


更多细节

就目前的环境而言。 带有托管 LoadBalancer 的 DO 上的 Docker 液滴。

OPTIONS要求: 在此处输入图像描述

相同的GET要求: 在此处输入图像描述

如您所见,CORS 标头都适用于两者。一切都很幸福。

在 Kubernetes 上与大使 字面意思是相同的 docker 镜像。

大使地图:

---
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
  name: priz-api
  namespace: ambassador
spec:
  prefix: /
  host: api.priz.guru
  service: priz-api.backend
  cors:
    origins:
      - https://app.priz.guru
    methods: GET, POST, PUT, PATCH, OPTIONS, DELETE
    headers: "*"
#    credentials: true
    exposed_headers: "*"
    max_age: "86400"

注意:即使我完全删除cors配置,我仍然面临同样的问题。

OPTIONS要求: 在此处输入图像描述

匹配 GET 请求: 在此处输入图像描述

4

0 回答 0