CORS with 3scale

2.1k views Asked by At

We’re trying to setup a 3scale platform over OpenShift to manage API access between a REST service and a JavaScript web application. Authentication shall be managed with the user-key placed in a HTTP header. The two applications are reachable on different URLs:

JS web application:     http://siteA.example.com
REST API application:   http://siteB.example.com

so we are using CORS to implement cross-origin resources on the webapp. This is introducing several OPTIONS pre-flight requests sent by the browser without the user-key header, thus receiving an HTTP 403 error from 3scale.

Is there a way to avoid this behaviour?

4

There are 4 answers

1
Shawn C. On

If you can't handle it at the application level then you can do a nginx if statement to handle it.

location / {
    if ($request_method = OPTIONS ) {
        add_header Access-Control-Allow-Origin "http://example.com";
        add_header Access-Control-Allow-Methods "GET, OPTIONS";
        add_header Access-Control-Allow-Headers "Authorization";
        add_header Access-Control-Allow-Credentials "true";
        ...
        add_header Content-Length 0;
        add_header Content-Type text/plain;
        return 200;
    }
    ...
}

Via http://blog.rogeriopvl.com/archives/nginx-and-the-http-options-method/

0
Melikoth On

I had the same issue in 3scale when using the AWS AMI and was able to solve it by adding the app_key and app_id to the allowed headers for an options request.

In testing the request worked in postman but would not work via Chrome. In my case when a browser issued the preflight options check it resulted in rejection because the app_key and app_id header are not allowed by the CORS defaults.

Adding support for those headers can be achieved by adding an entry for them to the end of the 'Access-Control-Allow-Headers' header. I made this configuration a separate file named cors.conf:

#### CORS ####
  if ($request_method = 'OPTIONS') {
    add_header 'Access-Control-Allow-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-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,app_id,app_key';
    add_header 'Access-Control-Max-Age' 1728000;
    add_header 'Content-Type' 'text/plain charset=UTF-8';
    add_header 'Content-Length' 0;
    return 204;
  }
#### CORS END ####

The cors.conf was then included under any "location /" block in nginx.conf:

...
location / {
include /opt/openresty/nginx/conf/cors.conf;
  set $provider_key null;
  set $cached_key null;
...

Once this change was made my browser was able to successfully make requests.

The CORS on Nginx document was used as a baseline and I noted that only the OPTIONS section needed to be modified to get the desired results.

0
Prashant On

When the environment variable APICAST_PATH_ROUTING is set to true, and APIcast is exposing multiple Services, if the CORS Policy is not enabled for all the Services, the preflight OPTIONS request will receive a 403 (Forbidden) response.

Set the CORS policy on all the services/apis within your 3scale.

More info from RedHat: https://issues.jboss.org/browse/THREESCALE-3063

1
Luca Mattia Ferrari On

3scale gateway now supports out-of-the-box CORS policy definition. More information here: https://access.redhat.com/documentation/en-us/red_hat_3scale_api_management/2.8/html/administering_the_api_gateway/apicast_policies#cors