Dinesh
Dinesh

Reputation: 4559

getting CORS error with SAML 2.0

I am getting a CORS error when trying to authenticate an access using SAML 2.0 and I am at a complete loss.

We have a backend web server which serves 3 different paths /html /js and /services. We have defined a SAML ID provider, imported the IDP metadata and configured a Service on the server side where the service url has been set to /html. This generated some metadata xml which has been registered in the IDP end of the world.

Starting with a fresh browser, the user types in https://host:port/html and a federated login page appears. User logs in, the backend server returns session cookies and remaining requests to /js and /services fly smoothly.

Now when the user closes the browser and reopens it, the HTML, JS/CSS are being served out of the browser cache. The first outbound request from the app to the backend server is to /services/a-service-name and it fails with the following:

XMLHttpRequest cannot load https://fed.xxx.com/fed/idp/samlv20?SAMLRequest=some-charater-string. 
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'https://my-host:port' is therefore not allowed access.

NETWORK ERROR; xhr= 0 error ; settings= GET /services/a-service-name <<<<<<<<<< this print is from my app

What gives? Do I need to create 3 service providers (i.e. /html, /js, /services) on my backend server side? Or, does my application need to trap and interpret SAML requests?

Will appreciate some help as I am very new to SAML.

----EDIT 1

Based on Anders Abel's answer, we added the following to index.html

<script>
  if(window.location.search.length == 0){
    window.location = "index.html?"+Math.random();
  }
</script>

This forces a hit to the designated SP, triggers SAML dialog with the Federation and forces a login unless the user is already logged in. Thanks!

Upvotes: 9

Views: 9993

Answers (1)

Anders Abel
Anders Abel

Reputation: 69280

When you access the site in the reopened browser, there is no established session to the application. The first request that hits the server, as you've found out an ajax request from JavaScript. That request triggers the SAML to login sequence and replies with a redirect to the Idp. This is where the problem shows up - The idp does not set a CORS header that will allow your Javascript to load it.

But before you rush off to try to convince your Idp to set a CORS header, please read on, because that's not how you should fix this.

SAML2 was designed in ancient times before ajax calls were known so it works quite badly together with it. What you want to do is to ensure that the HTML page is loaded from the server every time the user opens the application. That way the HTML load will trigger the SAML2 login flow if needed and everything will work.

The solution is to set a cache header on your html so that it is never cached.

Upvotes: 10

Related Questions