Enabling cross-origin requests in Umbraco API and Azure
Table of contents
What you will learn
In this article, I’ll show how you can resolve Umbraco CMS API CORS policy problems, so you could easily consume Umbraco API from another domain.
By the end of this short tutorial, you will know what steps you need to take to:
CORS policy issues overview
Recently I was struggling with the local angular app while retrieving the data from the Umbraco API endpoint. The app was throwing the following error:
Access to XMLHttpRequest at 'http://testapi.piotrbach.com/umbraco/API/showcase/getdummydata' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status
You may have encountered this problem as well because this is a very common error that means the CORS mechanism was not properly configured.
Why this is happening?
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. 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. CORS is safer and more flexible than earlier techniques such as JSONP.
by MS docsWhat to do now?
Installing Microsoft AspNet Cors library using nuget package manager
Enablling CORS globally
To enable CORS globally in Umbraco CMS v8+ you can use composing technique:
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
internal class WebApiCorsComposer : IComposer
{
public void Compose(Composition composition)
{
composition.Components().Insert<WebApiCorsComponent>();
}
public class WebApiCorsComponent : IComponent
{
public void Initialize()
{
GlobalConfiguration.Configuration.EnableCors();
}
public void Terminate()
{
}
}
}
Decorating controller/action with EnableCors attribute
Before that - include System.Web.Http.Cors namespace
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class ShowcaseApiController : UmbracoApiController
{
[HttpGet]
public IHttpActionResult GetDummyData()
{
return Json("ok");
}
}
Configuring HTTP methods and headers in Web.config
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
<remove name="Server" />
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, PATCH, DELETE, HEAD" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Accept, Authorization, Content-Type" />
</customHeaders>
</httpProtocol>
You may skip setting headers and methods in web.config end specify them directly in Component with the following code:
var cors = new EnableCorsAttribute(origins: "*",
headers: "Origin, X-Requested-With, Accept, Authorization, Content-Type",
methods: "GET, POST, PUT, DELETE, OPTIONS");
GlobalConfiguration.Configuration.EnableCors(cors);
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
internal class WebApiCorsComposer : IComposer
{
public void Compose(Composition composition)
{
composition.Components().Insert<WebApiCorsComponent>();
}
public class WebApiCorsComponent : IComponent
{
public void Initialize()
{
var cors = new EnableCorsAttribute(origins: "*",
headers: "Origin, X-Requested-With, Accept, Authorization, Content-Type",
methods: "GET, POST, PUT, DELETE, OPTIONS");
GlobalConfiguration.Configuration.EnableCors(cors);
}
public void Terminate()
{
}
}
}
Enabling CORS for Azure WebApp
If you're using the Azure Web App Service - additionally, you may need to specify the exact origins that should be allowed to make cross-origin calls.
Due to Azure security settings, the connected domains accessing the Azure app should be specified. I noticed that many guys forget this step and once the web API is deployed & ready - it's still not working.
To configure the Azure app properly you need to take the following steps:
References: