Enable cross-origin requests in UmbracoApiController and Azure

What you will learn

In this article I’ll show how you can resolve umbraco cms api CORS policy problems.

After going through this tutorial - hopefully you will be able to use umbraco api from another domain.

The problem

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. This tutorial shows how to enable CORS in your Web API application.

In my case, my local angular app was throwing following error while consuming data from umbraco api controller:

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

What to do now?

Install Microsoft AspNet Cors library using nuget

  • Open Visual Studio
  • Go to Tools\Nuget Package Manager
  • Choose Package Manager Console
  • Install the package as follows: Install-Package Microsoft.AspNet.WebApi.Cors

Decorate controller or 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");
    }
}

Modify 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>

Enable CORS for HttpConfiguration

To do so in Umbraco CMS v8+ you can use composing technique :

  • Create WebApiConfig file
  • Create WebApiCorsComponent
  • Create WebApiCorsComposer 
  • Execute WebApiConfig.Register during component initialization

Full code may look as follows:

public class WebApiCorsComposer : ComponentComposer<WebApiCorsComponent>
{

}

public class WebApiCorsComponent : IComponent
{
    public void Initialize()
    {
        WebApiConfig.Register(GlobalConfiguration.Configuration);
    }

    public void Terminate()
    {
    }
}

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.EnableCors();
    }
}

Enable CORS globally (recommended)

it may happen, that you have to EnableCors for Global configuration:

public class WebApiCorsComposer : ComponentComposer<WebApiCorsComponent>
{

}

public class WebApiCorsComponent : IComponent
{
    public void Initialize()
    {
        GlobalConfiguration.Configuration.EnableCors();
    }

    public void Terminate()
    {
    }
}

Enabling CORS for Azure WebApp

If you're using Azure Web App, you may need to specify the origins that should be allowed to make cross-origin calls.

  • Open azure portal
  • Go to App services
  • Find the app service
  • Go to CORS section
  • Add origin, in my case "http://localhost:4200"
  • Save new settings

Azure Umbraco CMS Web app enabling CORS

References:

https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api