_In a world_ of a single API used by multiple SPAs .... 馃審
It would be really helpful to be able to specify a list of origins/domains/subdomains in the nginx.ingress.kubernetes.io/cors-allow-origin annotation. Especially for subdomains serving media: media1.site.com, media2.site.com, media3.site.com
Intriguingly, this case was put forward in the initial feature request, but looks like it got reduced to an MVP of a single domain? But since the initial merge the thread has continued with many code blocks of how-to config snippet hacks to enable the support of multiple domain handling. This of course gets very messy - especially when having to apply to each microservice's ingress definition.
Initial Feature Request: https://github.com/kubernetes/ingress-nginx/issues/1171
/kind feature
As it currently stands, if you attempt to specify a comma-separated list of allowed origins in the nginx.ingress.kubernetes.io/cors-allow-origin annotation, it won't validate and will therefore fall back to the default of *.
This may give the false impression that the list is actually being obeyed, since all listed origins will work... but so will all other origins, since it's ending up as Access-Control-Allow-Origin: *.
Having this feature would be great, we are also struggling to do it. As a workaround, we are using configuration snippet with custom nginx config which is working but still an ugly solution.
Here's my ugly configuration snippet to work around:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: foo
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($http_origin ~* "^https?://((?:www\.exactmatch\.com)|(?:.*\.regexmatch\.com))$") {
set $cors "true";
}
if ($request_method = 'OPTIONS') {
set $cors "${cors}options";
}
if ($cors = "true") {
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, DELETE, PATCH, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
}
if ($cors = "trueoptions") {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, DELETE, PATCH, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
Here's my ugly configuration snippet to work around:
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: foo annotations: kubernetes.io/ingress.class: "nginx" cert-manager.io/cluster-issuer: "letsencrypt-prod" nginx.ingress.kubernetes.io/configuration-snippet: | if ($http_origin ~* "^https?://((?:www\.exactmatch\.com)|(?:.*\.regexmatch\.com))$") { set $cors "true"; } if ($request_method = 'OPTIONS') { set $cors "${cors}options"; } if ($cors = "true") { add_header 'Access-Control-Allow-Origin' "$http_origin" always; add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, DELETE, PATCH, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always; } if ($cors = "trueoptions") { add_header 'Access-Control-Allow-Origin' "$http_origin"; add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, DELETE, PATCH, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain charset=UTF-8'; add_header 'Content-Length' 0; return 204; }What is the expected behavior in this case if the $http_origin is not on whitelist ?
No headers added, which means no CORS policy so all CORS requests blocked by the browser.
Hi all
Here's my configuration snippet to don't work, where is the problem?
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/enable-access-log: "true"
nginx.ingress.kubernetes.io/enable-rewrite-log: "true"
nginx.ingress.kubernetes.io/proxy-body-size: 100m
ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($http_origin ~* "^https?://((?:ui|uia)\.stand01\.example\.com)$") {
set $cors "true";
}
if ($cors = "true") {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, DELETE, PATCH, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
name: ui-https-cors-ing
spec:
tls:
- hosts:
- ui.stand01.example.com
secretName: stand01-06-example-com-crt-fullchain
rules:
- host: ui.stand01.example.com
http:
paths:
- backend:
serviceName: ui-svc
servicePort: 8080
path: /
This would be really good!
Currently blocked and having to look into writing a snippet 馃憥
Support for wildcard subdomains would be really nice:
nginx.ingress.kubernetes.io/cors-allow-origin: "https://*.domain.com"
because "https://app1.domain.com", "https://app2.domain.com", "https://app3.domain.com" all needing to call "https://api.domain.com" is a common need.
Hello Guys,
I am facing Multiple "Access control allow origin" issue while I am using the below mentioned configuration snippet in k8s annotations: -
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($http_origin ~* ((https?:\/\/(.+.)*(domain1|domain2).(?:net|com)$)) {
set $cors "true";
}
# Determine the HTTP request method used
if ($request_method = 'OPTIONS') {
set $cors "${cors}options";
}
if ($request_method = 'GET') {
set $cors "${cors}get";
}
if ($request_method = 'POST') {
set $cors "${cors}post";
}
if ($cors = "true") {
# Catch all incase there's a request method we're not dealing with properly
add_header 'Access-Control-Allow-Origin' "$http_origin";
}
if ($cors = "trueget") {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($cors = "trueoptions") {
add_header 'Access-Control-Allow-Origin' "$http_origin";
#
# Om nom nom cookies
#
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($cors = "truepost") {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
Please find the attached error: -

Please suggest where am I doing wrong.
Most helpful comment
This would be really good!
Currently blocked and having to look into writing a snippet 馃憥
Support for wildcard subdomains would be really nice:
because "https://app1.domain.com", "https://app2.domain.com", "https://app3.domain.com" all needing to call "https://api.domain.com" is a common need.