Locking App Service to Azure Front Door via Middleware
Locking App Service to Azure Front Door via Middleware
• Azure, App Service, Front Door, Security, Middleware, .NET
• 2 min read
When hosting public internet applications, like a website, or a BFF (back-end for front-end), not only there are infrastructure considerations to secure the application against attacks, but also application security considerations.
In this post, I am sharing an application lock to only accept requests from a gateway/proxy/load balancer, a service that you control, in this instance Azure Front Door. This is an application security strategy, part of a larger security strategy to control and filter incoming requests.
The challenge
Consider an App Service, created using ASP.NET Core, allowing requests from Azure Front Door only.
The solution
An ASP.NET Core Middleware in .NET 8.0 can be used for such lock. Basically what you can do is filter requests based on the request header X-Azure-FDID that Azure Front Door1 provides in all of its requests:
/// <summary>/// Front Door Request Header Middleware/// </summary>publicclassFrontDoorRequestHeaderMiddleware{privatereadonlyRequestDelegate_next;/// <summary>/// Initializes a new instance of the <see cref="FrontDoorRequestHeaderMiddleware" /> class./// </summary>publicFrontDoorRequestHeaderMiddleware(RequestDelegatenext){_next=next;}/// <summary>/// Middleware Invoke Async/// </summary>publicasyncTaskInvokeAsync(HttpContextcontext){if(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")!="Development")// not for local development{varappSettings=context.RequestServices.GetRequiredService<IConfiguration>();varapiKey=appSettings.GetValue<string>("FrontDoorId");// this should be on appsettingsvarisHeaderAvailable=context.Request.Headers.TryGetValue("X-Azure-FDID",outStringValuesheaderValue);varisFrontDoorIdValid=apiKey.Equals(headerValue);if(!isHeaderAvailable||!isFrontDoorIdValid){context.Response.StatusCode=StatusCodes.Status403Forbidden;return;}}await_next.Invoke(context);}}/// <summary>/// FrontDoor request header extension/// </summary>publicstaticclassFrontDoorRequestHeaderExtensions{/// <summary>/// Use FrontDoor extension/// </summary>publicstaticIApplicationBuilderUseFrontDoorRequestHeader(thisIApplicationBuilderbuilder){returnbuilder.UseMiddleware<FrontDoorRequestHeaderMiddleware>();}}
Then from Program.cs you can add this middleware to the App, like this:
What I like about this approach is that all requests go through the middleware, and it simply does short-circuit2 the request pipeline in case the request is forbidden, not passing it to the next delegate, avoiding unnecessary work.
Join the conversation! Share your thoughts and connect with other readers.