Solved

How to configure CORS for the /api/profile path?

  • 23 April 2022
  • 13 replies
  • 1052 views

Hello,

We have configured CORS by using the following Ingress options:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
meta.helm.sh/release-name: gooddata-cn
meta.helm.sh/release-namespace: gooddata-cn
nginx.ingress.kubernetes.io/cors-allow-headers: X-GDC-JS-SDK-COMP, X-GDC-JS-SDK-COMP-PROPS,
X-GDC-JS-PACKAGE, X-GDC-JS-PACKAGE-VERSION, x-requested-with, X-GDC-VALIDATE-RELATIONS,
DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since,
Cache-Control, Content-Type, Authorization
nginx.ingress.kubernetes.io/cors-allow-origin: example.com
nginx.ingress.kubernetes.io/enable-cors: "true"
creationTimestamp: "2022-03-28T12:58:20Z"
generation: 4
labels:
app.kubernetes.io/component: dex
app.kubernetes.io/instance: gooddata-cn
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: gooddata-cn
app.kubernetes.io/version: 1.7.1
helm.sh/chart: gooddata-cn-1.7.1
name: gooddata-cn-dex
namespace: gooddata-cn
resourceVersion: "83817680"
uid: e0546e76-2c33-49a0-a2c4-e8a17a609605

 

However, when doing GET or OPTIONS requests at https://example.com/api/profile the Access-Control-Allow-Origin header is always set to “*”.

Are we doing something wrong?

icon

Best answer by Ulku Kijasev 25 April 2022, 09:18

View original

13 replies

Hi,

CORS headers were originally set up with the same value of Access-Control-Allow-Origin for all organizations using nginx ingress annotations in Helm chart values  (in ingress.annotations key).
Since GoodData CN version 1.7.0, the configuration can be done the following way:

  1. if custom UI apps are running on the same domain as Organization, no extra setup is needed.
  2. If custom UI apps run on the other domain and this app is somehow used for multiple organizations, customers still can use the old method using ingress.annotations  that will be automatically applied for every existing and every newly created organization automatically.
  3. If custom UI apps run on the other domain and this domain needs to be different for every organization (like app-prod.example.com for organization prod.example.com, and app-test.example.com for test.example.com), the given UI app domain (e.g. https://app-test.example.com) needs to be set to allowedOrigins attribute of the respective organization as described in the linked doc article

The configuration you have made seems to be fine if you have multiple organizations and you want to have one UI application (running on another domain) same for all organizations.

In your application you see Access-Control-Allow-Origin header is always set to “*” for you requests? Are your requests to gooddata organization successful or do they fail with CORS errors?

Hi,

I’ve successfully set up CORS, but now experiencing the following issue:

Sign in screen at https://localhost:8443/login does nothing. When trying to log in it sends a GET request to /api/profile and displays the “Unknown error” message under the password field.

Hi,

Have you set up the organization as described in here. Did you prepare the organization.yaml and setup the administrator account in it? And after creating the organization then you can setup the authentication for configuring other users, which are composed of steps Creating bootstrap token, Setting up an OIDC identity provider and mapping users to organization as in doc. Please let us know if you have followed the steps for creating organization and administrator account.

Hi,

I’ve set up the administrator account, created an organization, a bootstrap token, a workspace, mapped a user to the  organization. I’m using built-in OIDC Dex provider.

Hi,

Could you please give us more details about what happened. Did you manage to successfully log-in and it failed on communication during the GET /api/profile. Or even the login wasn’t successful for some reason? Could you please send us a screenshot from the browser where the error occurred, as well as the failing API request and the response (at least the status code and not sensitive response headers). If you can provide us also logs it would be good.

Thank you,

Basically that is what I get when pressing the “Sign In” button:

 

 

Hi,

In order to help workaround authentication errors, some colleagues used here workaround by starting the frontend app like this: REACT_APP_DEV_TIGER_API_TOKEN=YWR… yarn start. Could you please try this and let us know if it solves your problem. Maybe it could help.

Thank you,

Hi Ulku,

I tried different combinations of the variables in .env file:

SKIP_PREFLIGHT_CHECK=true
REACT_APP_DEV_TIGER_API_TOKEN=YWR...
#TIGER_API_TOKEN=YWR...
REACT_APP_SET_HOSTNAME=true
#NODE_ENV=production

 

Nothing helps at the moment.

We see that you’re getting error response 403 to GET request to /api/profile. This means you still have problem in authorisation part. You most probably have invalid CORS configuration, so your API requests are rejected because they don’t allow localhost origin. The fix could be adding https://localhost:8443 to allowedHosts in the organization configuration, or you can add https://localhost:8443  to nginx.ingress.kubernetes.io/cors-allow-origin as explained above you can choose where to add depending on your needs. But it seems that https://localhost:8443 was not added as allowed origin in your CORS configuration.

What response code should it return in case of successful configuration? Because I assumed it returned 403 because a user was not logged in yet.

It should return you response 200 OK

Userlevel 2

It seems there’s unexpected interference between cors setup on ingress level and cors setup on organization level, so it really doesn’t work as expected. We will fix in in one of future releases, but till then there is the following workaround:

  1. Add the following annotations to helm chart values and redeploy gooddata-cn:
ingress:
annotations:
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-headers: "X-GDC-JS-SDK-COMP, X-GDC-JS-SDK-COMP-PROPS, X-GDC-JS-PACKAGE, X-GDC-JS-PACKAGE-VERSION, X-GDC-VALIDATE-RELATIONS, DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Authorization"
nginx.ingress.kubernetes.io/cors-allow-origin: "https://localhost:8443, https://another.domain.com"

The “cors-allow-origin” annotation should contain comma-separated list of all domains where the CORS should be enabled for all organizations you have. Note, that you can’t control which domain should be enabled for which organization.

  1. Set allowedOrigins to url for every Organization where you want CORS to be allowed. Following the example above, let’s say you want to set allowedOrigins="https://localhost:8433" for Organization “devel.example.com” and allowedOrigins="https://another.domain.com" for Organization “production.example.com” 

This configuration is secure enough but has a small limitation - running pre-flight check (OPTIONS) from Origin localhost:8443 against production.example.com backend will return status 204, but the real call (GET. POST, ...) will fail with 403 as expected, because localhost:8443 is not allowed host on backend.

 

Userlevel 2

Hello, a brief update:

CORS setup works fine as far as you do NOT add any cors-related annotations to your ingress annotations (simply remove `nginx.ingress.kubernetes.io/enable-cors`,  `nginx.ingress.kubernetes.io/cors-allow-headers` and `nginx.ingress.kubernetes.io/cors-allow-origin` from your customized values file and update your deployment. Removing these annotations is necessary to keep responses unmodified because now the CORS is completely managed by backend services.

Then, set `allowedOrigins` to list of allowed origin URLs; don’t forget to include schema and also port if it differs from default value for given schema (80 for http and 443 for https).

These two settings should be sufficient to make the CORS working.

 

Please us know if it helped.

Reply