Note: This is the first article on the topic of integrating Static Web Apps with resources bound to a virtual network. See the second article for more context: Access network isolated APIs and databases from Azure Static Web Apps - Microsoft Community Hub
Azure Static Web Apps allows you to easily host your web apps globally, with built-in support for APIs, staging environments and more. With the introduction of the API integration feature for Azure Static Web Apps, we’ve heard many developers indicate that they want to link network isolated backends to their Azure Static Web Apps resources to benefit from this feature’s key benefits: integrated security and seamless routing.
However, since Static Web Apps hosts web apps in a distributed manner, Static Web Apps resources can’t be deployed directly into virtual networks directly (only integrated via private endpoint). Therefore, they can’t integrate directly with network isolated backends.
Instead, integrating network isolated resource with a Static Web Apps resource can be achieved by leveraging API Management and its virtual network integration capabilities. This article details how to do this.
How backend integration works (and why it’s so important)
Azure Static Web Apps’ backend integration works by reverse proxying calls made to `/api` to the linked Azure resources (whether it be a Web App, a Container App, a Function App or an API Management instance). When it proxies these calls, it also injects the HTTP headers necessary for authentication and authorization, such as the `x-ms-client-principal`.
By doing this, the Azure Static Web Apps backend integration feature enables the aforementioned benefits of seamless routing and integrated security. By serving your API from the `/api` endpoint, no additional CORS configurations are needed for your backend. Additionally, by injecting the required headers, you can access your user credentials if you are using Azure Static Web Apps’ authentication and authorization.
Azure Static Web Apps’ backend integration also comes with the added benefit of securing access to your API by configuring your backend to only accept traffic coming from your Static Web Apps resource.
All in all, backend integration is an important and interesting feature which allows you to build full stack applications (while leveraging the global distribution of Azure Static Web Apps). As such, it is understandable to want to use this feature with network isolated backends.
Alternatives to backend integration for virtual network-bound resources
Given the benefits of backend integration for Azure Static Web Apps, it is understandable that those with existing network isolated backends wish to make use of this feature. Here are a few alternatives to help you consider your choices when using Azure Static Web Apps with network isolated backends. For this use case, we demonstrate how to integrate your Static Web Apps resource with an API deployed onto a Web App within an App Service Environment in your virtual network.
Option #1: Make direct API calls from your Azure Static Web Apps website to your virtual network-bound API
- With this method, your API is made publicly accessible via a load balancer (such as Application Gateway). Your static web app makes direct HTTP calls to your API, which may be hosted on a separate domain.
- With this method, you get neither benefits: you will have to configure CORS on your server (since your static web app and your API are hosted from different domains). Moreover, you will not be able to use the integrated authentication and authorization of Static Web Apps. However, you are able to access your API which may be all that you need.
- Summary:
- APIs served from /api route: No
- Access to user credentials for Static Web Apps authentication: No
Option #2: Serve your Azure Static Web Apps website from your virtual network. Configure your load balancer to route calls to your static assets to your Static Web Apps resource and route calls to your `/api/*` routes to your API
- With this method, both your Static Web Apps resource and your API are made publicly accessible via a load balancer (such as Application Gateway). Your static web app makes HTTP calls to the relative `/api/*` path (on the same domain).
- With this method, your API and Static Web App are hosted from the same domain, which does not require additional CORS configuration. However, since HTTP requests to the `/api/*` route are directly routed to your API, they are not injected with the headers needed to leverage Azure Static Web Apps’ authentication and authorization.
- Summary:
- APIs served from /api route: Yes
- Access to user credentials for Static Web Apps authentication: No
Option #3: Use API Management as an API gateway between your Static Web Apps resource and your network isolated backends
- With this method, your API Management instance is integrated into your virtual network using the external mode. This gives external access to your private resources, which allows Azure Static Web Apps’ distributed hosts to proxy API calls to your APIM instance, which proxies calls to your backend resource.
- With this method, you can link your API Management instance as a backend to your Azure Static Web Apps resource.
- With this method, your API and Static Web App are integrated via API Management. They are hosted from the same domain, providing seamless routing without additional CORS rules. Moreover, API calls to the /api route are received by Azure Static Web Apps hosts and are injected with the correct headers before being proxied to your API Management resource and then to your backend API. This enables your app to leverage Static Web Apps’ native authentication and authorization, as you can access the user credentials as documented.
- Summary:
- APIs served from /api route: Yes
- Access to user credentials for Static Web Apps authentication: Yes
As you can see from the above architecture options, only the API Management network integration option achieves both the integrated security and seamless routing benefits. While the other options can be suitable for your architecture, they do not enable all benefits of backend integration and come with limitations as explained above. Note that only API Management's developer and premium tiers offer external virtual network integration.
Therefore, API Management is the best option for those wanting to integrate virtual network-bound backends with Azure Static Web Apps since it gives you full feature parity. Below, we detail how to implement this architecture.
How to integrate network isolated backends with Azure Static Web Apps by leveraging API Management
Let’s take another look at the architecture diagram detailed in option 3 above. As we can see, the use of API Management integrated into the virtual network using the external mode allows Static Web Apps’ distributed hosts to access the API endpoints, since this mode gives external access to network isolated backends.
This guide will detail how to configure your Azure Static Web Apps and your API Management instance to achieve integration with network isolated backends. For this demo, I decided to build this architecture using an Azure Function App and a private endpoint instead of the Web App within the App Service Environment for simplicity, though this would apply to all available isolated backends.
Prerequisites:
- A virtual network and a subnet with a network security group attached
- A Function App with a Private Endpoint or other resource isolated within the virtual network
- An available Standard SKU public IPv4 address
- See all details pertaining to API Management prerequisites
Steps:
- Create and configure your API Management to be integrated with your virtual network through the external mode as documented in the Microsoft docs. Your API Management instance needs to be in the same region as your virtual network.
- Add your API to your API Management instance as documented in the same Microsoft docs. Since Azure Static Web Apps prepends all API requests with the `/api` route, you must ensure that your API settings for that API within API Management must have API URL suffix of `api`.
- From your Azure Static Web Apps resource, go to the APIs blade. Link a new API Management backend to your production environment and select the API Management instance you just created.
Upon linking your API Management as a Static Web Apps backend, Static Web Apps will configure your API Management to only accept requests coming from your Static Web Apps resource by configuring the subscriptions and products of your API Management instance.
With this architecture, you’ll notice that your APIs are now being served by Azure Static Web Apps’ `/api` route. Moreover, you can notice that your APIs are now receiving requests with the authentication headers injected, allowing you to use Azure Static Web Apps’ authentication feature.
To test it out, follow these steps:
- Edit your Function App or API to return the ‘x-ms-client-principal’ at a specific route. This header is injected for logged in users and contains the user credentials.
- Go to your Azure Static Web Apps domain, and ensure you are logged in as a user. You can do this by navigating to `your-static-apps-domain.azurestaticapps.net/.auth/login/github` (or any of the other authentication providers).
- Once you are logged in to your Static Web Apps, make a fetch request to `/api/HttpTrigger1` (the route you configured above in step 1). Verify that the response is returning the payload including the `x-ms-client-principal` that you extracted from the request headers in your API code. This indicates that you have access to the `x-ms-client-principal` header within your network isolated backend.
Conclusion
In conclusion, by leveraging API Management and its network integration capabilities, we can integrate a network isolated backend with an Azure Static Web Apps resource. API Management serves as a proxy that allows external access to your private backend APIs. This allows both benefits enabled by Azure Static Web Apps backend integration feature: the ability to serve your API from the `/api` endpoint (no need to configure custom CORS rules in your API) and the injection of authentication headers to API requests allowing you to use Azure Static Web Apps’ authentication feature.
In conjunction with the ability to integrate Static Web Apps with virtual networks through the use of private endpoints, this article demonstrates that Azure Static Web Apps can be well integrated into existing architectures that make use of network isolation for security purposes.
Get started with Azure Static Web Apps today
- Learn more about configuring your Azure Static Web Apps to integrate with your network isolated architectures through the use of private endpoints.
- Share feedback in the Azure Static Web Apps GitHub repo.
- Follow and tag our Twitter account for Azure Static Web Apps.
Read more about architectures to integrate Static Web Apps with network isolated backends here: Access network isolated APIs and databases from Azure Static Web Apps - Microsoft Community Hub