{"id":95404,"date":"2019-06-20T15:00:19","date_gmt":"2019-06-20T15:00:19","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/aspnet\/?p=22256"},"modified":"2019-06-20T15:00:19","modified_gmt":"2019-06-20T15:00:19","slug":"forwarded-headers-middleware-updates-in-net-core-3-0-preview-6","status":"publish","type":"post","link":"https:\/\/sickgaming.net\/blog\/2019\/06\/20\/forwarded-headers-middleware-updates-in-net-core-3-0-preview-6\/","title":{"rendered":"Forwarded Headers Middleware Updates in .NET Core 3.0 preview 6"},"content":{"rendered":"<div class=\"row justify-content-center\">\n<div class=\"col-md-4\">\n<div><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/06\/forwarded-headers-middleware-updates-in-net-core-3-0-preview-6.jpg\" width=\"58\" height=\"58\" alt=\"Avatar\" class=\"avatar avatar-58 wp-user-avatar wp-user-avatar-58 photo avatar-default\"><\/div>\n<\/div>\n<\/div>\n<div class=\"entry-meta\">\n<p>June 20th, 2019<\/p>\n<\/p><\/div>\n<p><!-- .entry-meta --> <\/p>\n<p>With the ASP.NET Core 2.1 release, we included <code>UseHsts<\/code> and <code>UseHttpRedirection<\/code> by default. These methods put a site into an infinite loop if deployed to an Azure Linux App Service, Azure Linux virtual machine (VM), or behind any other reverse proxy besides IIS. TLS is terminated by the reverse proxy, and Kestrel isn\u2019t made aware of the correct request scheme.<\/p>\n<p>OAuth and OIDC also fail in this configuration because they generate incorrect redirects. Calls to <code>UseIISIntegration<\/code> add and configure forwarded headers middleware when running behind IIS, but there\u2019s no matching automatic configuration for Linux (Apache or Nginx integration). The fix for this issue is discussed in more detail in the doc article <a href=\"https:\/\/docs.microsoft.com\/en-us\/aspnet\/core\/host-and-deploy\/proxy-load-balancer?view=aspnetcore-2.2#forward-the-scheme-for-linux-and-non-iis-reverse-proxies\">Forward the scheme for Linux and non-IIS reverse proxies<\/a>.<\/p>\n<h2>Configuration-only Wire-up in Preview 6<\/h2>\n<p>With the updates in .NET Core 3 preview 6, you no longer need to call the middleware explicitly, as the host logic has been pre-wired to enable the Forwarded Headers Middleware by default as long as the <code>ASPNETCORE_FORWARDEDHEADERS_ENABLED<\/code> environment variable has been set to <code>true<\/code>. Turning on the Forwarded Headers Middleware is as simple as setting the <code>ASPNETCORE_FORWARDEDHEADERS_ENABLED<\/code> setting in the Azure Portal\u2019s configuration blade for any App Service running on Linux or in a container.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/06\/forwarded-headers-middleware-updates-in-net-core-3-0-preview-6.png\" alt=\"Enabling the Forwarded Headers Middleware via config\"><\/p>\n<p>Once this setting is set to true, the middleware starts working, and features dependent on <code>Request.IsHttps<\/code> resulting to <code>true<\/code> begin to function as expected.<\/p>\n<h2>Resolving the issue with ASP.NET Core 2.x Apps Today<\/h2>\n<p>If you\u2019re currently building an ASP.NET Core 2.x app and want to run it on App Service for Linux now, there\u2019s a workaround that will be future-proof when the updates come out for 3.0.<\/p>\n<p>To forward the scheme from the proxy in non-IIS scenarios, add and configure Forwarded Headers Middleware. In <code>Startup.cs<\/code>, use the following code:<\/p>\n<pre><code class=\"csharp\">\/\/ using Microsoft.AspNetCore.HttpOverrides; public void ConfigureServices(IServiceCollection services)\n{ if (string.Equals( Environment.GetEnvironmentVariable(\"ASPNETCORE_FORWARDEDHEADERS_ENABLED\"), \"true\", StringComparison.OrdinalIgnoreCase)) { services.Configure&lt;forwardedheadersoptions&gt;(options =&gt; { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; \/\/ Only loopback proxies are allowed by default. \/\/ Clear that restriction because forwarders are enabled by explicit \/\/ configuration. options.KnownNetworks.Clear(); options.KnownProxies.Clear(); }); }\n} public void Configure(IApplicationBuilder app, IWebHostEnvironment env)\n{ app.UseForwardedHeaders();\n}\n<\/code><\/pre>\n<p>If you enable your ASP.NET Core 2.x apps with this workaround today, when you\u2019re ready to upgrade to 3.0, you\u2019ll already have the right configuration setting in place.<\/p>\n<h2>Base Image Update<\/h2>\n<p>The base images used by the App Service team to streamline the creation of ASP.NET Core apps will soon be updated so that the <code>ASPNETCORE_FORWARDEDHEADERS_ENABLED<\/code> environment variable will be set to <code>true<\/code>. Once they\u2019re updated, you won\u2019t even need to explicitly set the environment variable; it\u2019ll be enabled by default.<\/p>\n<h2>Try it Out<\/h2>\n<p>If you\u2019re new to building ASP.NET Core apps using containers, the App Service options for Linux and Container-based hosting offer a great place to get started. The docs are loaded with guidance and examples, from how to <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/app-service\/containers\/quickstart-dotnetcore\">Run a .NET Core app in App Service on Linux<\/a> to accessing a <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/app-service\/containers\/tutorial-dotnetcore-sqldb-app\">SQL Server Database from an ASP.NET Core app running in App Service Linux<\/a>.<\/p>\n<div class=\"authorinfoarea\">\n<div><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/06\/forwarded-headers-middleware-updates-in-net-core-3-0-preview-6-1.jpg\" width=\"96\" height=\"96\" alt=\"Avatar\" class=\"avatar avatar-96 wp-user-avatar wp-user-avatar-96 photo avatar-default\"><\/div>\n<div>\n<h5><a class=\"no-underline\" aria-label=\" Brady Gaster\" target=\"_blank\" href=\"https:\/\/devblogs.microsoft.com\/aspnet\/author\/bradygmicrosoft-com\/\" rel=\"noopener noreferrer\"> Brady Gaster<\/a><\/h5>\n<p>Senior Program Manager,&nbsp;ASP.NET Core<\/p>\n<p><strong>Follow <\/strong>&nbsp;&nbsp;&nbsp;<a class=\"no-underline stayinformed\" aria-label=\" Brady Gaster Twitter profile\" target=\"_blank\" href=\"https:\/\/twitter.com\/bradygaster\" rel=\"noopener noreferrer\"><i class=\"fa fa-twitter\"><\/i><\/a><a class=\"no-underline stayinformed\" aria-label=\" Brady Gaster GitHub profile\" target=\"_blank\" href=\"https:\/\/github.com\/bradygaster\" rel=\"noopener noreferrer\"><i class=\"fa fa-github\"><\/i><\/a><a class=\"no-underline stayinformed hvr-pop\" aria-label=\" Brady Gaster RSS Feed\" target=\"_blank\" href=\"https:\/\/devblogs.microsoft.com\/aspnet\/author\/bradygmicrosoft-com\/feed\/\" rel=\"noopener noreferrer\"><\/a><\/p>\n<\/p><\/div>\n<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>June 20th, 2019 With the ASP.NET Core 2.1 release, we included UseHsts and UseHttpRedirection by default. These methods put a site into an infinite loop if deployed to an Azure Linux App Service, Azure Linux virtual machine (VM), or behind any other reverse proxy besides IIS. TLS is terminated by the reverse proxy, and Kestrel [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":95405,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[66,1],"tags":[102],"class_list":["post-95404","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microsoft-webdev","category-uncategorized","tag-uncategorized"],"_links":{"self":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/95404","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/comments?post=95404"}],"version-history":[{"count":0,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/95404\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/media\/95405"}],"wp:attachment":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/media?parent=95404"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/categories?post=95404"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/tags?post=95404"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}