For Infor CRM / Saleslogix SData is the key technology on the server side that enables us to build rich client side applications. Single-page applications are all the rage now and with sdata they can communicate with the Saleslogix database without the need to build a custom web service. However there is a key security limitation which is that your client app can only communicate with a service hosted on the same server, in some cases this may not be convenient. CORS (Cross-origin resource sharing) is a mechanism that lets us call the sdata service from a page that runs on another server (note that this applies only to client code that runs in the browser – if you run your code from a server-side app such as the C# code of an ASP.NET page, you need not worry about any of this!)
In theory this is pretty simple – you just configure a header on the server to let browsers know it is OK to post cross-domain requests to it. However there are a few complications, some of them are due to sdata, some of them to confusing information, so I thought I would summarize the requirements here. Note that I have not tested any of this with Windows authentication and I don’t even know if it is possible to do cross-domain requests with Windows credentials.
- Change “verb” under handlers in web.config to “GET,POST,PUT,DELETE”. With CORS request the browser will do a “pre-flight” request using the “OPTIONS” verb and no credentials to “test the waters” – i.e. determine what the server is configured to let it send. We need sdata to not handle the “OPTIONS” verb which will be lacking credentials, otherwise it will return a 401 error and the browser will give up on the rest of the request!
- Under the global server settings in IIS (not the site’s), go under the custom headers and add the following:
- Access-Control-Allow-Headers: Authorization, Content-Type, X-Authorization, X-Requested-With, X-Authorization-Mode (the first one is the standard authorization header, the rest is custom headers that are used by the sdata javascript client library. If you are using custom javascript code and not the client library you might be able to stick to “Authorization” there)
- Access-Control-Allow-Methods: GET,POST,PUT,OPTIONS
- Access-Control-Allow-Origin: * (you can also set it to a specific domain instead of * if you want to limit requests to pages served from that domain but since the authentication credentials need to be known to the code making the requests it does not really give you any additional security)
You do NOT need to set Access-Control-Allow-Credentials. That one is only used for session-based authentication (i.e. cookies)
- Likewise you do NOT need to set “withCredentials” on the HTTP request – that is again only used for cookie-based authentication
If all works well you should see the 2 requests sent by your code: the OPTIONS request which will return an empty body and a “200” status, and the actual Sdata request which will return the data. If it does not work watch the console as the browser will try to print helpful error message to point out why it was not able to send a request.