Understanding CORS Issues
CORS can sometimes present challenges to the Applications/Apis published via the Azure AD Application Proxy. There are many options to resolve these issues with ease, and in this blog we share those options as well as provide another look at understanding CORS.
What is CORS?
Cross Origin Resource Sharing (CORS) is a W3C standard that allows a server to relax the same-origin policy. Using CORS, a server can explicitly allow some cross-origin requests while rejecting others.
Browser security prevents a web page from making AJAX requests to another domain. This restriction is called the same-origin policy and prevents a malicious site from reading sensitive data from another site. However, sometimes you might want to let other sites call your web API.
What is Same Origin?
Two URLs have the same origin if they have identical schemes, hosts and ports. (RFC 6454)
These two URLs have the same origin:
- http://contoso.com/foo.html
- http://contoso.com/bar.html
These URLs have different origins than the previous two:
- http://consoto.net – Different domain
- http://contoso.com:9000/foo.html – Different port
- https://contoso.com/foo.html – Different scheme
- http://www.contoso.com/foo.html – Different subdomain
Consider the below example we have a «Webservice«, which hosts a Web API controller, and the other called “WebClient”, which calls Webservice. There is an AJAX request from WebClient to WebService
CORS Challenges with Application Proxy
The App seems to work when hosted on premises but either fails to load or errors out when published via the Azure AD Application Proxy.
Both the applications were published as different applications through Application Proxy, so since the two applications are hosted at different domains, an AJAX request from WebClient to WebService is a cross-origin request and it fails.
Identifying CORS Issue
You can identify CORS issues by using the browser debug tools:
1. Launch the browser and browse to the Web App
2. Hit F12 to bring up the debug console
3. Try and reproduce the transaction and review the console
The console will give an error about the origin if you are seeing a CORS violation.
Note: In the below example the call is made when you hit the “Try It” Button, the expected response is a Test Message, instead you see an error.
Note: In the above example https://corwebclient-allmylab.msappproxy.net is missing from Access-Control-Allow-Origin header
Solution
Below are some possible solutions
Option 1: Custom Domains
Use the Custom Domain feature of the Azure AD Application Proxy, so you can use the same domain name and no changes to applications or headers are required. Thus the origin will continue to stay the same.
Option 2: Publish Parent Directory
Publish the parent directory of both applications. This works particularly well if you only have two applications on the web servers. Instead of publishing each application separately, you could publish the parent directory, that would result in the same origin.
App Published Individually
Instead publish the parent directory
The resulting URLs would be as below, effectively resolving your CORS issues.
https://corswebclient-allmylab.msappproxy.net/CORSWebService
https://corswebclient-allmylab.msappproxy.net/CORSWebClient
Option 3: Update HTTP Headers
Add the HTTP Response Header on the Web Service to match the Origin request. For example, below is how you could set it up for the websites running on the IIS.
This would also not require any change to the Code. You can also verify this in the Fiddler traces.
Post the Header Addition
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/plain; charset=utf-8
Expires: -1
Vary: Accept-Encoding
Server: Microsoft-IIS/8.5 Microsoft-HTTPAPI/2.0
Access-Control-Allow-Origin: https://corswebclient-allmylab.msappproxy.net
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Content-Length: 17
Option 4: App Modification
Modify your application to add support for the CORS by adding the Access-Control-Allow-Origin header with appropriate values. The way to do this will depend on the language in which you wrote the application. This is the least recommended option since it requires more effort.
Best,
Jeevan Bisht
Program Manager – GTP