飞行前OPTIONS返回403,CORS

问题描述

我们将Kubernetes与Istio结合使用,并已配置了虚拟服务:

  http:
  - match:
    - uri:
        prefix: /api
    rewrite:
      uri: /api
    route:
    - destination:
        host: svc-api
        port:
          number: 80
        subset: stable
      weight: 0
    - destination:
        host: svc-api
        port:
          number: 80
        subset: vnext
      weight: 100
    corsPolicy: &apiCorsPolicy
      allowOrigins:
      - exact: '*'
      allowMethods:
      - GET
      - POST
      - OPTIONS
      allowCredentials: true
      allowHeaders:
      - "*"
  - match:
    - uri:
        prefix: /
    rewrite:
      uri: /
    route:
    - destination:
        host: svc-api
        port:
          number: 80
        subset: stable
      weight: 0
    - destination:
        host: svc-api
        port:
          number: 80
        subset: vnext
      weight: 100
    corsPolicy: *apiCorsPolicy

在浏览器向https://[host]/api/*发送OPTIONS请求时,向浏览器发出对'from origin [request] has been blocked by CORS policy'的请求。

在k8中描述服务会显示正确的配置。

根据v 1.6.4,使用allowOriginsexact而非allowOrigin的结构是正确的。

在这里想念什么?

解决方法

这里没有什么值得一提的。


最近在较旧的istio版本中,cors和jwt结合在一起出现问题,请查看以下链接:


还有一个github issue,在这个comment社区成员中有同样的问题,也许值得为此开一个新的github问题?


另外,istio dev @howardjohn还有一个答案

大家好。使用curl测试CORS可能会产生误导。没有在服务器端强制执行CORS。例如,它不会返回4xx错误。而是返回标头,浏览器使用这些标头拒绝/接受。 https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/cors.html?highlight=cors对此进行了很好的演示,并且https://www.sohamkamani.com/blog/2016/12/21/web-security-cors/#:~:text=CORS%20isn't%20actually%20enforced,header%20in%20all%20its%20responses。是一个很好的解释。

因此Istio的工作只是返回这些标头。我添加了一个测试来证明这一工作:#26231


正如我在评论中提到的,值得一看的是另一个社区成员配置here,因为他有一个可行的示例,但POST出现403问题。


在您的虚拟服务中我需要改变的几件事

仅使用corsPolicy而不是corsPolicy: &apiCorsPolicy

corsPolicy:

您还可以使用正则表达式代替正则表达式,它可以解决通配符的问题。

allowOrigins:
- regex: '*'

关于//api路径,我认为这里前缀就足够了,您无需重写。