IIS
36 TopicsHow to Properly Configure IIS Reverse Proxy for ASP.NET Core Applications Secured with Entra ID
If you’ve ever worked on an ASP.NET Core application protected with Entra ID, you might have encountered an issue where the backend server URL appears as the redirect URI instead of the IIS Reverse Proxy URL. This is because ASP.NET Core applications use the backend server’s hostname to generate the redirect URI. While this behavior is the default, it can be problematic. While you can work around this by manually setting the redirect URI to the ARR/IIS Reverse Proxy endpoint in your code as follows: builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")); builder.Services.Configure<OpenIdConnectOptions>(options => { options.Events.OnRedirectToIdentityProvider = context => { context.ProtocolMessage.RedirectUri = "https://arr.local.lab"; return Task.FromResult(0); }; }); It isn’t the most elegant solution, especially in environments where configuration changes might often be required. Instead, using Forwarded Headers offers a cleaner, more scalable approach. In this post, I’ll walk you through how to resolve this issue using Forwarded Headers. ASP.NET Core provides a ForwardedHeaders Middleware , which reads headers such as X-Forwarded-Host and X-Forwarded-Proto. These headers replace values in HttpContext such as HttpContext.Request.Host and HttpContext.Request.Scheme. By passing these headers appropriately from IIS Reverse Proxy, we can resolve the redirect URI issue. But IIS reverse proxy or server farms doesn't send X-Forwarded-Host & X-Forwarded-Proto headers by default. You’ll need to configure IIS to include these headers using the URL Rewrite feature. To do so, follow these steps: Set Server Variables Open the URL Rewrite module in the IIS Manager Console and Select View Server Variables. Add following Server Variables: HTTP_X_Forwarded_Host HTTP_X_Forwarded_Proto Edit Inbound Rules Once Server Variables are added, select the concerned reverse proxy inbound rule and select Edit under Inbound rules in Actions Pane. Add the Server Variables to the inbound rule: Map HTTP_X_Forwarded_Host to {HTTP_HOST} Map HTTP_X_Forwarded_Proto to https Once IIS is configured to pass forwarded headers, the application needs to process them. Add ForwardedHeaders Middleware in your ASP.NET Core application and configure ForwardedHeadersOptions as follows: using Microsoft.AspNetCore.HttpOverrides; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")); builder.Services.AddAuthorization(options => { // By default, all incoming requests will be authorized according to the default policy. options.FallbackPolicy = options.DefaultPolicy; }); builder.Services.AddRazorPages() .AddMicrosoftIdentityUI(); builder.Services.Configure<ForwardedHeadersOptions>(options => { options.KnownProxies.Add(IPAddress.Parse("10.160.7.4")); // Reverse Proxy IP address options.ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost; }); var app = builder. Build(); app.UseForwardedHeaders(); // ForwardedHeaders Middleware // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapStaticAssets(); app.MapRazorPages() .WithStaticAssets(); app.MapControllers(); app.Run(); Note: Order of the Middleware is important. Ensure ForwardedHeaders Middleware is called before any other middleware in the pipeline. Make sure to add the IP address of your ARR/IIS Reverse Proxy to the KnownProxies list. Alternatively, you can use KnownNetwork to set IP range. With these configurations, X-Forwarded-Host and X-Forwarded-Proto headers sent from IIS Reverse Proxy will replace the Host and Scheme in HttpContext. This ensures that the redirect URI correctly points to the IIS Reverse Proxy endpoint, resolving the issue seamlessly. Further Reading: Refer to these resources for more information: Configure ASP.NET Core to work with proxy servers and load balancers | Microsoft Learn Setting HTTP request headers and IIS server variables | Microsoft Learn IIS Server Variables | Microsoft Learn Hope this guide helps!179Views2likes0CommentsConfiguring CORS in IIS with the IIS CORS Module: A Step-by-Step Guide
The Cross-Origin Resource Sharing (CORS) is a security feature implemented by web browsers that enables control of which resources are accessible based on the origin of requests. This way, web servers are given the authority to define which domains are allowed to access resources, ensuring only trusted sources will interact with your server. In this modern era of applications, where most web apps fetch data from multiple origins, CORS is very important to manage and secure these interactions.7.8KViews5likes1CommentIIS URL Rewrite Rule Not Working: Resolving 'HTTP Error 404.4 - Not Found' Issues.
Issue Most of you have encountered situations where you have used IIS URL Rewrite to redirect traffic from one site to another. But in some cases, rewrite rules fail to work as expected and returns 'HTTP Error 404.4 - Not Found'. The 404.4 status code means no handler configured. Which means the file name extension of the requested URL doesn't have a handler that is configured to process the request on the Web server. For example you have two sites hosted in IIS. Site1 bind with port 81 and Site2 bind with port 82. The requirement is to rewrite all the request coming to Site1 (port:81) should rewrite to Site2 (port:82). The below rule is configured - <system.webServer> <rewrite> <rules> <rule name="RewriteToPort81" stopProcessing="true"> <match url="^.*$" /> <action type="Rewrite" url="http://localhost:82/{R:0}" appendQueryString="true" /> </rule> </rules> </rewrite> </system.webServer> Solution First you need to check if the correct module is installed in IIS. To check this go to IIS Manager and open the Modules. Within the Modules check if the correct URL Rewrite module is installed. You can get the latest IIS URL Rewrite module from this link URL Rewrite : The Official Microsoft IIS Site If the correct module is installed as highlighted above, the next thing you check the Failed Request Tracing logs for the request. And verify if the correct rule is invoked and it updates the URL to new one. Here in this case you can see "RewriteToPort82" rule is invoked and it changed the request URL to http://loalhost:82/. Also verify if the HttpStatus="404" and HttpSubStatus="4". To remediate the issue, go to IIS Manager, open Application Request Routing Cache module and open Server Proxy Settings form the right-hand Actions pane. Within the Server Proxy Settings you will find an option to enable proxy. Check the Enable proxy checkbox and click apply form the right-hand Actions pane as pointed in the below picture. After this you need to restart IIS. This should resolve the URL rewrite issue. To know more about URL rewrite in IIS you can follow this article - Using the URL Rewrite Module | Microsoft Learn5.3KViews4likes3CommentsHow to fix HTTP Error 500.37 - ASP.NET Core app failed to start within the startup time limit error
ASP.NET Core applications hosted in IIS are designed to provide robust performance. However, sometimes, issues arise that prevent apps from starting properly within the expected time. One common problem is the HTTP Error 500.37, which indicates that the application failed to start within the startup time limit. This article will walk you through what causes this error and how to resolve it.4.7KViews3likes3CommentsHow to fix Failed to Load API Definition error in SwaggerUI when hosting an ASP.NET Core API in IIS
When hosting an ASP.NET Core API, it’s not uncommon to encounter the "Failed to load API definition" error in SwaggerUI. This article will explore the reasons behind this error and provide steps to resolve it.13KViews5likes4CommentsHTTP Error 500.30 - ASP.NET Core App Failed to Start: Root Cause and Solutions
When deploying an ASP.NET Core application, encountering the "HTTP Error 500.30 - ASP.NET Core app failed to start" is the most common error. This error typically indicates an issue within the application startup process, often triggered by misconfigurations, dependencies or environment mismatches.17KViews4likes0CommentsCPU Management in IIS Application Pools: A Deep Dive into Advanced Settings for Optimal Performance
Application pools provide an isolation between different web application in Internet Information Services (IIS) by allowing you to manage the resources, recycling, and performance per application. Control of CPU usage is going to be one of the most critical factors in the performance and management of an application pool. IIS includes a dedicated section under ApplicationPool -> Advance Settings for the management of CPU. it provides varied settings that enable you to optimize the utilization of the CPU so that a particular server resource does not become dominated by one application. This article will dive into the CPU settings for an ApplicationPool, explaining each option and its configuration.2KViews4likes0CommentsHow to Configure and Collect Schannel and CAPI2 Logs
CAPI2 log is a diagnostic log in Windows that tracks cryptographic operations. It track events related to certificate validation, key exchange. It also record how Windows and applications use cryptographic algorithms for securing data. This is crucial for diagnosing issues with SSL/TLS, digital signatures, and other encryption-related processes. CAPI2 logs are particularly useful for diagnose security-related problems in Windows systems. When troubleshooting issues related to cryptographic operations in Windows, it may be necessary to enable and collect logs for both Schannel and CAPI2. This article will help you to configure and collect these logs for diagnostic purposes.3.6KViews4likes0CommentsUnderstanding HTTP Status Code 304 Not Modified Response and Output Caching Feature in IIS
Caching plays a crucial role in optimizing web performance. When Output Caching is enabled in IIS for specific file extensions or URLs, it delivers 304 Not Modified status code. This status code is essential for managing caching, as it indicates whether a resource has been modified since the last time it was requested.2.3KViews4likes0Comments