SAML login/transparent proxy to our app, when using reverse proxy/rewrite

We’re trying to move our site from a Heroku-based server that serves both as an API server as well as serving static files onto Netlify + API server.

The last piece of the puzzle that we can’t figure out how to achieve with Netlify as of now is SAML support for our customers. We have a backend hosted on Heroku, which allows for SAML-based authentication. The way we currently do it is the following:

  1. Custom domain per customer. e.g. https://internal.brandotal.com is for ourselves, using our GSuite as the identity provider.
  2. Customer goes to https://internal.brandtotal.com, which redirects them to https://internal.brandtotal.com/auth-saml/brandtotal-google. Since the entire app is hosted in Heroku, including the static-page-serving part, this is the same server, and it catches that - and redirects them to GSuite to login.
  3. GSuite has a redirect URL (ACS Url) defined as BrandTotal (called with POST), which again - is fine, since we just catch that request using the same server as above, which then sets a session for that user, and sends them back a cookie with it + a redirect to the home page (now authenticated).

Using the netlify.toml we defined this:

[[redirects]]
from = "/auth-saml/*"
to = "https://our-app.herokuapp.com/auth-saml/:splat"

[[redirects]]
from = "/api/auth/brandtotal-google"
to = "https://our-app.herokuapp.com/api/auth/brandtotal-google"
status = 200

This works fine almost all the way through, but we get an error after the user logs in (in GSuite - step #1 above) (emphasis in bold is mine):

2020-11-29T16:55:55.909492+00:00 app[web.1]: Error: SAML provider returned Requester error: Invalid request, ACS Url in request https://brandtotal-www-staging.herokuapp.com/api/auth/brandtotal-gsuite doesn’t match configured ACS Url https://internal.brandtotal.com/api/auth/brandtotal-gsuite .
2020-11-29T16:55:55.909504+00:00 app[web.1]: at /app/node_modules/passport-saml/lib/passport-saml/saml.js:662:31

What we think is going on is that the Netlify reverse proxy gets the response back from Google, but then calls our server with the URL we have defined in the to, and not the original host https://internal.brandtotal.com

Here are the response headers for POST https://internal.brandtotal.com/api/auth/brandtotal-google that we see in the browser Dev Tools (which we get a 500 for):

access-control-allow-credentials: true
access-control-expose-headers: Content-Range
age: 0
content-length: 148
content-security-policy: default-src ‘self’
content-type: text/html; charset=utf-8
date: Sun, 29 Nov 2020 16:55:55 GMT
server: Netlify
status: 500
via: 1.1 vegur
x-content-type-options: nosniff
X-DNS-Prefetch-Control: off
x-nf-request-id: 489b5d1f-32c0-4666-b7ab-a6eec404fca1-18842479
x-powered-by: Express

We’d really appreciate some help here, I’m sure we’re not the first company that faces this issue - providing SAML-based auth. to their customers, while being hosted on Netlify…

Also, we really don’t want to have the ACS Url pointing directly at the heroku server, since that means our customers will have to know that too, and right now we have it set up such that they just get their own subdomain (in their eyes). e.g.:
https://netlify.brandtotal.com or https://some-company.brandtotal.com

Was someone able to achieve something similar using Netlify’s reverse proxy/some other solution? It seems like it’s not completely transparent… The closest thing I found on the community forums is this thread from ~6 months ago, but it’s not the very same situation and unfortunately I wasn’t able to derive something useful for our case from this.

Any help here would be much appreciated.
Thanks!

P.S.
We currently have internal.brandtotal.com is CNAME-ed to our netlify app:

> nslookup internal.brandtotal.com
Server: 1.1.1.1
Address: 1.1.1.1#53
Non-authoritative answer:
internal.brandtotal.com canonical name = brandtotal-www-frontend.netlify.app.
Name: brandtotal-www-frontend.netlify.app
Address: 130.193.56.159
Name: brandtotal-www-frontend.netlify.app
Address: 130.193.50.25

Hey @bengry :wave:t2:

Going to try to help you out with this one. I’m not sure what you mean when you’re referencing that since the whole app is hosted in Heroku, certain requests are ‘caught’ as… related?

More to the point though, I’m curious if not using a 200 flag in your first redirect, the one from /auth-saml/* might be causing your issue, since that could cause initial request to Google to show as being from your actual Heroku host… which could cause the issue down stream. The status = 200 on the second redirect should be working fine; I’ve never seen issues with POST’ing to rewrites before.


Jon