skip to Main Content

I have two services in Kubernetes which are exposed through nginx controller. Service a wants to invoke content on domain b but at the same time both services need to be authenticated through Google using the oauth-proxy service.

So I have managed to enable CORS and a can invoke b without any issues. But the problem is when I include the authentication as well, I am constantly getting:

Access to manifest at 'https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force&client_id=<obscured>.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fa.example.com%2Foauth2%2Fcallback&response_type=code&scope=profile+email&state=<obscured>manifest.json' (redirected from 'https://a.example.com/manifest.json') from origin 'https://a.example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Here are the ingresses:

Service a

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    kubernetes.io/tls-acme: "true"
    nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
    nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri"
    nginx.ingress.kubernetes.io/whitelist-source-range: 0.0.0.0/0
  name: a
spec:
  rules:
  - host: a.example.com
    http:
      paths:
      - backend:
          service:
            name: a-svc
            port:
              number: 8080
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - a.example.com
    secretName: a-tls

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/whitelist-source-range: 0.0.0.0/0
  labels:
    k8s-app: oauth2-proxy
  name: a-oauth
spec:
  rules:
  - host: a.example.com
    http:
      paths:
      - backend:
          service:
            name: oauth2-proxy
            port:
              number: 4180
        path: /oauth2
        pathType: Prefix
  tls:
  - hosts:
      - a.example.com
    secretName: a-oauth-tls

Service b

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    kubernetes.io/tls-acme: "true"
    nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
    nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri"
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/whitelist-source-range: 0.0.0.0/0
  name: b
spec:
  rules:
  - host: b.example.com
    http:
      paths:
      - backend:
          service:
            name: b-svc
            port:
              number: 8080
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - b.example.com
    secretName: b-tls

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
    nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri"
    nginx.ingress.kubernetes.io/whitelist-source-range: 0.0.0.0/0
  labels:
    k8s-app: oauth2-proxy
  name: b-oauth
spec:
  rules:
  - host: b.example.com
    http:
      paths:
      - backend:
          service:
            name: oauth2-proxy
            port:
              number: 4180
        path: /oauth2
        pathType: Prefix
  tls:
  - hosts:
      - b.example.com
    secretName: b-oauth-tls

Obviously, there is only one difference between these two and that is the cors annotations nginx.ingress.kubernetes.io/enable-cors: "true" in the service b ingresses.

I am not sure of what is causing the issue but I am guessing that the authentication done against Google in service a is not being passed to the CORS request so that the service b can also be authenticate with the same token/credentials.

What am I doing wrong and how can I resolve this?

2

Answers


  1. Chosen as BEST ANSWER

    So, it turns out that the whole Kubernetes and Nginx config was correct, so the solution was implementing the usage of the saved cookie on client side when invoking a CORS request to the second service.

    Essentially, this was already answered here: Set cookies for cross origin requests

    Excerpt from the answer:

    Front-end (client): Set the XMLHttpRequest.withCredentials flag to true, this can be achieved in different ways depending on the request-response library used:

    • jQuery 1.5.1 xhrFields: {withCredentials: true}
    • ES6 fetch() credentials: 'include'
    • axios: withCredentials: true

  2. Based on the documentation, it looks like you lack of annotations for using HTTP.

    Try to add fragment like this in service configuration file:

    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/configuration-snippet: |
       more_set_headers "Access-Control-Allow-Origin: $http_origin";
    

    But it can be a problem with CORS. In such case you should add the following line:

    --cors-allowed-origins=["http://*"]
    

    to /etc/default/kube-apiserver or /etc/kubernetes/manifests/kube-apiserver.yaml file (depending on the location your kube-apiserver configuration file).

    After that restart kube-apiserver.

    See also this similar question.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search