DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Delivering Your Code to the Cloud With JFrog Artifactory and GitHub Actions
  • Migrating Spring Java Applications to Azure App Service (Part 1: DataSources and Credentials)
  • Achieving Micro-frontend Architecture Using Angular Elements
  • How to Build Slack App for Audit Requests

Trending

  • Agentic AI for Automated Application Security and Vulnerability Management
  • How Trustworthy Is Big Data?
  • Doris: Unifying SQL Dialects for a Seamless Data Query Ecosystem
  • Stateless vs Stateful Stream Processing With Kafka Streams and Apache Flink
  1. DZone
  2. Software Design and Architecture
  3. Cloud Architecture
  4. Using Azure Front Door for Eliminating Preflight Calls (CORS)

Using Azure Front Door for Eliminating Preflight Calls (CORS)

You can use an Azure Front Door to route to both the UI domain and the API to eliminate the (OPTIONS) request; calls from the browser will be directed to the same-origin as the UI.

By 
Pratik Bhattacharya user avatar
Pratik Bhattacharya
·
Mar. 18, 21 · Analysis
Likes (3)
Comment
Save
Tweet
Share
10.0K Views

Join the DZone community and get the full member experience.

Join For Free

What is CORS

Cross-Origin Resource Sharing (CORS) is a security mechanism built-in most modern browsers to restrict accessing resources from a server hosted on a different domain. Using CORS techniques, servers can limit the sharing of data to only trusted domains. Assume you have a frontend website hosted on https://www.contoso.com. Some JavaScript code from your website is trying to access an API hosted on https://www.foobar.com. This is an example of Cross-Origin Resource Sharing because the requesting domain and the resource domain are different. https://www.foorbar.com might have some sensitive information that it can share with only specific trusted domains, then https://www.foobar.com can specify a CORS policy where it can block requests from other domains than the trusted sites. If the request originates from the same domain, then CORS doesn't come into play.

CORS Example

How CORS Works

When JavaScript from the frontend initiates an AJAX call, the browser will need to check if Server has enabled CORS. In such a situation instead of sending the actual request, the browser will make a 'preflight' request to the server to determine if the server has enabled resource sharing with the current domain. The browser makes a preflight call by sending an HTTP request with the OPTIONS method to the origin containing the resource. The HTTP options call will also send the current origin, non-standard headers, and the original HTTP call method.

Based on this information, the server can take a decision. Suppose the server can accept the given call. In that case, it will send a response code of 204 along with headers specifying the origins from which requests are allowed, allowed HTTP methods, allowed custom headers, and cache duration.

If the Server sends a response of 204, allowed origins contain the current origin, and the headers and methods that the client wants to send are present in the server response, then the browser enables the actual request to go through. For any other cases, the browser will block the request.

CORS Working

Client Headers

  • Access-Control-Request-Method: HTTP method of the actual HTTP request.

  • Access-Control-Request-Headers: Headers that will be sent as part of the actual HTTP request.

Server Headers

  • Access-Control-Allow-Origins: Origins that are allowed to access resources from the server. '*' can be placed to indicate that all origins are allowed.

  • Access-Control-Allow-Methods: HTTP methods which are allowed by the server.

  • Access-Control-Allow-Headers: Headers that the client can send to the server while accessing Servers.

  • Access-Control-Max-Age: Seconds for which the client can cache this response. For a similar request from the client, the browser need not send another preflight request to the server for the given duration.

When Does the Browser Initiate Preflight?

If the request is to the same origin (even if it's complicated), the browser doesn't initiate a preflight OPTIONS request. For cross-site requests, the browser forgoes CORS if the request is 'simple.' For an HTTP request to be 'simple,' the request must guarantee the following conditions:

  1. The HTTP Method is simple. Browsers consider GET, HEAD, and POST to be simple.

  2. Only standard headers are present in the HTTP Request. Headers set automatically by the user agent are considered to be simple. To see a list of standard headers, click here.

  3. The Content-Type header value is simple. The allowed values for Content-Type are: application/x-www-form-urlencoded, multipart/form-data and text/plain.

For any deviation from the above 3 points, the browser will make the preflight OPTIONS for any cross-site request.

Performance Penalty

From a security perspective, CORS is essential. However, there is a noticeable performance penalty. Due to the initial OPTIONS call, the actual request is stalled by the browser until the server can respond to the preflight request. Based on the time, the browser takes to respond to the preflight request; the app will have to wait for data to load from the server. Although the Server doesn't have to perform a lot of processing, various factors like SSL handshaking, regional latency, network jitters, server-side load, client-side load, etc. all contribute to the performance penalty. In some cases, OPTIONS requests can take up to 1-2s based on the factors mentioned above.

In an enterprise scenario where multiple teams have their apps deployed in different services keeping a common domain may not be feasible. All these services and APIs belonging to the same enterprise are trusted, but since they do not have the same Domain, the browser will initiate a preflight request for these requests.

We can leverage Azure Front Door as an ingress controller to eliminate the OPTIONS request.

Azure Front Door

It's a Level 7 Load balancer that uses anycast protocol with split TCP and Microsoft's Global Network. It's global and highly scalable.

You can configure any internet-facing service (can be hosted outside Microsoft Azure) as a backend to an Azure Front Door. You can also configure routing rules to route incoming client requests to the most suitable backend (based on availability and speed).

To learn more about Azure Front Door click here.

Configuring Azure Front Door for CORS Elimination

Each front door can have one or multiple frontends/domains. A front door can have multiple internet-facing backends configured. You can now access all these backends via one of the front door domains. A common domain can now access multiple internet-facing services, each hosted on various services having different domains. Extending the same idea, we can also host the frontend application to the same Front door and access it via the same domain. The problem with this approach would be, how will Azure Front Door know which backend to direct an incoming request. This is where routing rules in Azure Front Door come into the picture; we can configure routing rules based on the incoming request URL and other parameters to redirect them to the required backend.

Azure Front Door Routing

In the above examples, two services, www.profiles.azurewebsites.net and www.pos.com, have been configured as backends to the front door with domain: www.ep.com. The routing rule has been configured to redirect request with URL /sales/* to www.pos.com and requests with URL /api/user/* to www.profiles.azurewebsites.net.

If we configure the frontend UI web app as another backend, you can access all the APIs and the UI via the same domain. When a request goes from the UI to any configured APIs, the browser will request the same domain. Hence the browser won't initiate the CORS preflight, allowing you to save precious millisecond to make your website more responsive.

Example 2

In this example, the frontend application is hosted on www.app.azurewebsites.net and is configured as another backend to the common Azure Front Door. 

So both the APIs and the frontend web app can reach via the same Domain (www.ep.com)

If the web app needs to get the sales report instead of calling www.pos.com/sales/2021/report, it will call www.ep.com/sales/2021/report. When www.ep.com (Azure Front Door) receives the request, it will follow its routing rules and redirect the request to www.pos.com, giving the required data to the web app. Since the HTTP request originated from www.ep.com to www.ep.com, the browser will consider this to be a same-origin call; the browser won't make the preflight request.

Routing Configuration Conventions

Developers should follow some conventions to achieve this kind of setting.

  1. Each backend should be identifiable by a unique routing rule. 

  2. Follow proper HTTP guidelines and naming conventions while deciding routes and resources. Although it's not mandatory, using proper REST API guidelines to name the APIs can make this configuration work a lot easier. As per appropriate standards, each API should have an appropriate name of the resource in its route. So if a server is returning user profiles, then its route should be api/users/{user_name}. This will ensure that each API backend has a unique name, making it convenient to configure the routing rules. Following Microsoft's REST API Guidelines should be a good start.

  3. When a user visits ep.com, Azure Front Door should redirect the request to the Web App backend. Keep the Web App route as *. If none of the routing rules matches then Azure Front Door will redirect to the Web App.

  4. If URLs are not enough to distinguish the backends, then complicated routing rules can be created using Rule Engines of Azure Front Door.

From the Field

We used this technique in an Enterprise application and after a week of experimentation we observed the below result:

Results Graph: Cross Domain vs. Common Domain

It provides a clear indication that eliminating cross-domain preflight OPTIONS calls can reduce the API latency.

azure Requests app Web Service

Published at DZone with permission of Pratik Bhattacharya. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Delivering Your Code to the Cloud With JFrog Artifactory and GitHub Actions
  • Migrating Spring Java Applications to Azure App Service (Part 1: DataSources and Credentials)
  • Achieving Micro-frontend Architecture Using Angular Elements
  • How to Build Slack App for Audit Requests

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!