Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add configurable CORS support to SSO Proxy #251

Open
adityarkj opened this issue Aug 30, 2019 · 6 comments
Open

Add configurable CORS support to SSO Proxy #251

adityarkj opened this issue Aug 30, 2019 · 6 comments

Comments

@adityarkj
Copy link

Is your feature request related to a problem? Please describe.
We have a frontend service, behind SSO, running on frontend.sso.example.com that makes XHR calls to a backend service at backend.sso.example.com.

While accessing frontend.sso.example.com as an authorised user from Chrome, the session cookie from frontend.sso.example.com isn't being forwarded to backend.sso.example.com because the XHR responses from the SSO proxy have the wildcard (*) Access-Control-Allow-Origin header, which is blocked according to CORS - since the two services are on different origins.

CORs requires the Access-Control-Allow-Origin header on the XHR response to match the origin domain to forward cookies across different origins.

Describe the solution you'd like
An option to configure CORS for the proxy through environment variables on the Proxy would be great. Or alternatively, a way to configure CORS individually on services through the upstream config file.

Describe alternatives you've considered
I attempted to play around with some of the configuration options currently available, both through the proxy configuration file and through the upstream configuration file, but wasn't able to bypass the issue we faced. In the end, I cloned the project and manually added a CORS library, which we then hosted on our private container registry to use with our services.

Additional context
My issues have been on Chrome and I haven't tested on other browsers

@spencergilbert
Copy link

I believe I'm also running into this, @adityarkj would it be possible to host that image publicly?

@adityarkj
Copy link
Author

@spencergilbert That would be possible, yes. However, I'd need to touch up the code a little bit before hosting it somewhere, which I might not get time to do for a few weeks at least.

@erewok
Copy link

erewok commented Oct 7, 2019

I think I have the same issue. Earlier I tried to do path-based routing and when that didn't work, I went in this direction. How do others solve this problem of having an authentication-protected frontend sending requests to an authentication-protected backend at a different origin? Seems like it would be a common scenario.

I tried to set SESSION_COOKIE_DOMAIN in sso-auth and COOKIE_DOMAIN in the sso-proxy to a domain that would cover both services, but I couldn't get cookies to be submitted to the backend.

@sporkmonger
Copy link
Contributor

Yeah, I'm trying to get this to work for Grafana and Prometheus, with similar issues.

@MrSaints
Copy link

MrSaints commented Nov 22, 2019

I came across this issue too because of the exact same scenario. But for the record...

because the XHR responses from the SSO proxy have the wildcard (*) Access-Control-Allow-Origin header

The SSO proxy does not actually set the CORS headers. It is your upstream application that is setting it, and you need to ensure that there is a specific Access-Control-Allow-Origin defined (e.g. the host for the frontend). Access-Control-Allow-Credentials must also be set for this backend-frontend scenario to work.

Finally, set the SKIP_AUTH_PREFLIGHT environment variable to true for the SSO proxy deployment. Otherwise, OPTIONS requests to the API will be "redirected" to the SSO proxy, and the preflight will fail because redirects are not allowed. If you do enable this, ensure that the upstream hosts do not expose anything sensitive when provided with an OPTIONS request.

With the aforementioned in mind, it is very much possible to have both a backend, and frontend proxied through SSO with the frontend being able to talk to the backend.

That said, it would be nice to be able to intercept preflight requests / handle CORS at the proxy level. But, perhaps it may bloat the SSO proxy with features that should probably be handled by more complex API gateways like Kong.

@rlabrecque
Copy link

rlabrecque commented Nov 25, 2020

This was a mess for me to figure out;

What I ended up doing which works for us because we control both sides of this is:

  1. Defined out upstreams as such (using the helm chart)
upstreams:
  - service: frontend
    default:
      from: 'frontend.redacted.tld'
      to: 'http://frontend.prod.svc.cluster.local'
  - service: backend
    default:
      from: 'backend.redacted.tld'
      to: 'http://backend.prod.svc.cluster.local'
      options:
        header_overrides:
          Access-Control-Allow-Origin: 'https://frontend.redacted.tld'
          Access-Control-Allow-Credentials: 'true'

proxy:
  extraEnv:
    - name: STATSD_HOST
      value: localhost
    - name: STATSD_PORT
      value: '11111'
    - name: COOKIE_SECURE
      value: 'false' # TODO: This feels like it shouldn't be required. https://github.com/minddocdev/buzzfeed-sso/issues/1
    - name: PROVIDER_URL_INTERNAL
      value: 'http://buzzfeed-sso-auth.prod.svc.cluster.local'
    - name: SKIP_AUTH_PREFLIGHT
      value: 'true' # https://github.com/buzzfeed/sso/issues/251
    - name: COOKIE_DOMAIN
      value: 'redacted.tld'

auth:
  domain: 'sso-auth.redacted.tld'
  extraEnv:
    - name: STATSD_HOST
      value: localhost
    - name: STATSD_PORT
      value: '11111'
    - name: COOKIE_SECURE
      value: 'false'
    - name: SESSION_COOKIE_DOMAIN
      value: 'redacted.tld'
  1. Removed ALL CORS stuff from our backend (realistically was just a couple lines).

  2. Changed our frontend (TypeScript based with Axios to) to set the "withCredentials" attribute:

	return axios
		.request({
			method: "GET",
			url: URL,
			withCredentials: true,
		})
		.then(response => {
			console.log(`< ${response.status} GET ${URL}`);
                        // ...
                });

This is the only thing that I could get working smoothly and consistently. Biggest problem I ran into on the buzzfeed-sso side was the sso-auth.redacted.tld getting blocked because of CORS... I think if I could set the response headers from that to include Access-Control-Allow-Origin: https://frontend.redacted.tld I would not have had to edit the frontend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants