How to enable your API with flexible support for CORS with no code changes

CORS in simple terms

It is very common these days to see client-side browser applications that load their pages and JavaScript files from one server, but make API calls to a different server. This is called Cross-Origin Resource Sharing or CORS.

Figure 1. Cross-Origins calls by web application’s JavaScript

By default, browsers will fail to process Cross-Origin API responses. This is the standard security feature built-in in all modern browsers. It restricts browser applications to access resources that have the origin different from the origin of the application itself. In order for API responses to be processed successfully by the browser applications, the API has to respond with its consent to be called Cross-Origin by these applications. Implementation of this consent requires API to support CORS protocol.

CORS protocol provides two processing models, Simple Request and Preflight Request. Browser itself selects which model to use based on HTTP request properties such as HTTP method (GET, POST, etc.) and HTTP headers. API has no control over the CORS processing model selected by the browser, but the API has to respond according to the selected processing model. Simple Request model requires API to provide its response with CORS-specific HTTP headers that indicate Cross-Origin consent. Preflight Request model is a bit more complex. When browser selects this model it sends a special “preflight” HTTP request with HTTP method OPTIONS before sending the actual request. If API server does not provide proper consent in its response, then the browser will not even attempt to send the actual request.

Figure 2. CORS processing models

CORS Challenges

Implementation of the CORS protocol (full implementation or even partial) by the APIs can be a challenging task, especially if you do not have full control over API implementation or its hosting environment. For example, a BizTalk server application can expose its endpoints (Receive Locations) as REST API endpoints. Configuration of these endpoints with full support for CORS is difficult, intrusive and always limited to some simple CORS use cases.

Figure 3. Cross-Origins calls to BizTalk REST API endpoints

For example, this blog article by Nick Hauenstein provides solution for adding CORS support for BizTalk services. The solution requires two quite drastic changes:

  1. Change IIS server configuration (that hosts BizTalk service) to always respond with CORS HTTP headers that are configured with static values.
  2. Develop and deploy with BizTalk service a custom Pipeline component that can deal with CORS preflight HTTP OPTIONS messages. 

Even though this solution will work in many (but not all) cases, it still suffers few deficiencies. Specifically:

  1. You have to change IIS server configuration for each IIS Application that hosts BizTalk services that require CORS.
  2. IIS server changes are static configurations. If CORS configuration has to be changed (for example, the list of web applications allowed to call BizTalk is changed) then IIS server configuration has to be changed again.
  3. Changes in IIS server configuration affect the whole IIS application not just a BizTalk service hosted in it, which might have undesirable side effects.
  4. Custom BizTalk Pipeline component requires development, testing, deployment and configuration with each Biztalk service that requires support for CORS.

Even if you have full control over API implementation and its hosting environment, adding support for CORS will still require code changes and/or configuration changes of each API that needs CORS.

Solution

The best solution to address these challenges regardless of the nature of APIs and their hosting environments is to use an API Gateway. An API Gateway sits in-front of the actual backend APIs and provides virtual APIs (or facade APIs) for any number of the backend APIs. For example, an API Gateway can independently forward messages to BizTalk REST endpoints and regular REST APIs as shown on Figure 3 below.

Figure 3. API Gateway for the backend APIs

Backend APIs do not have to support CORS because they are not called directly. The API Gateway is the one that takes full responsibility to implement CORS protocol on behalf of the backend APIs. Most importantly, the API Gateway can provide complete, flexible and remotely configured capability to add, remove or change CORS configuration for any virtual API. Effectively this results in the flexible support for CORS by any individual backend API with no changes to the API itself.

Nevatech Sentinet product offers API Management software solution that includes an API Gateway called Sentinet Node which among other capabilities provides full support for CORS protocol.

Any REST API (including BizTalk Server services) can be virtualized through a Sentinet Node and configured with support for CORS. Sentinet Administrative Console allows to remotely configure every CORS property in just a few seconds.

Figure 4. Sentinet Administrative Console with CORS configuration

Tags: