web.config settings not respected in .net core 3.1 Azure multi-instance scaled app service? - azure-web-app-service

I'm trying to add/remove certain http headers from responses coming back from a 'pure' web api application (i.e. no MVC) published to Azure.
I added the following web.config to the project in VS2019:
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="X-Content-Type-Options" value="nosniff"/>
<add name="X-Frame-Options" value="SAMEORIGIN"/>
<remove name="X-Powered-By"/>
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
This works fine in my dev environment with IISExpress. It also works fine when the app is published to Azure for app services that are not configured for multi-instance scaling. However, when the app service is configured for multi-instance scaling (three instances in my case) then responses from the app contain 'X-Powered-By' and no 'X-Content-Type-Options' or 'X-Frame-Options'.
Publishing creates the following web.config in Out folder on my dev machine:
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="X-Content-Type-Options" value="nosniff" />
<add name="X-Frame-Options" value="SAMEORIGIN" />
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath=".\<apname>.exe" stdoutLogEnabled="false" stdoutLogFile="\\?\%home%\LogFiles\stdout" hostingModel="inprocess" />
</system.webServer>
</configuration>
I also verified that the above web.config is present in the root of the app service in Azure.
Is there anything else that needs to be done in app service configuration in Azure for this to work with multi-instance scaling?

After testing, you do not need to make any changes. In the code or web.config, your solution is currently possible, provided that it is deployed in a windows-based webapp. If it is deployed under linux, then the web.config file is not effective. The web.config file is only applicable to iis. Under linux, the configuration file that needs to be used should be .htaccess.
Put web.config under the wwwroot path, which is the root directory of the project.
Based on windows azure webapp, the post-deployment effect should be consistent with the local iis effect. After testing, after I deploy, you can see the screenshots, and the effect in your web.config has been achieved.
Note:
Some headers cannot be deleted, but they can be overwritten. They need to be coded in the program. You are not involved in this question yet.
<httpProtocol>
<customHeaders>
<add name="X-Content-Type-Options" value="nosniff" />
<add name="X-Frame-Options" value="SAMEORIGIN" />
<-- replace server vaule -->
<add name="Server" value="N/A" />
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
Test Steps:
Method 1 with web.config
Create a sample project like below.
Deploy to azure, please see my files on scm site.
Method 2 without web.config (workaround, also works in linux)
Add below code in Startup.cs, it also works for me .
app.Use(async (context, next) =>
{
context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
context.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
context.Response.Headers.Remove("X-Powered-By");
await next.Invoke();
});

Related

Hosting a net6.0 web api in Azure App Service

I have created a demo Web Api in net6 using the Visual Studio 2022 template for that. The Web Api runs fine on my machine but when trying to host it in an Azure App Service it fails with the following error:
After some research I managed to have it working on Azure by changing the module "AspNetCoreModuleV2" to "AspNetCoreModule" in the web.config.
Here it is the web.config that gets deployed to Azure and it doesn't work:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\Web6Test.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
</system.webServer>
</location>
</configuration>
Is it possible to host the web api in Azure using the "AspNetCoreModuleV2" module?
There can be multiple reasons causing HTTP 500.30 error: ASP .Net core app failed to start like App Initialization, App Configuration and Key vault permission issues.
Thanks to 130nk3r5, I figured out how to find the root cause of the error:
Go to Azure Portal
Select App Services
Search and click on your App service
Go to development tools and open console.
Run the application through this console and then the real error that is causing the application not to load will be displayed.
You can refer to this SO thread for multiple solutions.
Hosting the web api can also be achieved by using AspNetCoreModuleV2 in the web.config.
I have reproduced the same by creating a .Net 6.0 Core web API project in Visual Studio.
Web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\XXXXXX.dll" stdoutLogEnabled="false" stdoutLogFile="\\?\%home%\LogFiles\stdout" hostingModel="inprocess" />
</system.webServer>
</location>
</configuration>
<!--ProjectGuid: 09e5e23c-101e-41d1-bd27-60c6f5c08db0-->
Output when running the project locally:
Deployed the application to Azure App Service:
Output after hosting the application in Azure App Service:
Result:

ASP.NET Core 2.2 Site Warmup

I've migrated a .NET Framework 4.6 WebApi to .NETCore 2.2 and am having trouble getting the IIS ApplicationInitialization module to call my endpoints on a startup/slot swap/scale out.
I added a Web.Config like:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\FR911.Api.Core.dll" stdoutLogEnabled="false" stdoutLogFile="\\?\%home%\LogFiles\stdout" hostingModel="inprocess" />
<applicationInitialization doAppInitAfterRestart="true">
<add initializationPage="api/Warmup>
<add initializationPage="/" />
</applicationInitialization>
</system.webServer>
</location>
</configuration>
But if I keep the default hosting model of "inprocess" my warmup never gets called. If I change to "outofprocess" hosting, my warmup does get called before the swap is completed.
I think the issue below is likely related:
https://github.com/aspnet/AspNetCore/issues/8057
I'm not looking to just manually ping or otherwise hit my endpoint because I want the existing feature in the module that IIS is Azure won't actually swap the endpoints until the warmup requests have finished (thus initing EFCore etc.)
Has anyone had any luck getting this to work with the inprocess hosting model?

HTTP Error 502.5 running ASP.NET Core 2.0 app from IIS

I'm getting an HTTP 502.5 error when trying to run my ASP.NET core 2.0 web app from IIS.
I've installed the .NET Core Windows Server Hosting Bundle and checked all my IIS settings as per this document https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/index?tabs=aspnetcore2x
The web.config looks like this.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\OscarWeb.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" />
</system.webServer>
</configuration>
The Windows event log produces the following errors.
It is IIS v6.2 running on Windows Server 2012 R2. The web application was built using ASP.NET Core 2.0.
When I run dotnet from the commandline as follows there are no errors:
dotnet oscarweb.dll
The first thing you have to do in this scenario is to create the logs folder if it is missing and check the stdout logs generated.
It can be several different things but from personal experience the most common issue i had was IIS not having enough permissions to run it. In IIS you can configure the Identity used in Advanced Settings. If it is using ApplicationPoolIdentity then change it to LocalSystem and see if it works. The logs in the stdtout file however will give you the answer.
The solution to this problem (in my case at least) was to reboot the web server. After installing the .NET Core Windows Server Hosting Bundle you need to reboot the server for them to be registered correctly.
Thanks to Chris Pratt (first comment underneath my question) for suggesting the answer :)
Not sure if your webconfig is complete. I believe aspnetcore tag needs to have the ASPNETCORE_ENVIRONMENT environment variable set as well.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\OscarWeb.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" >
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="YourRuntimeEnv" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</configuration>

Asp.Net Core tag in web.config causes failure

I have a .NET Core application which works on one machine but not on another.
The problem is that the application fails to load, because the IIS does not recognize the following
<aspNetCore processPath="dotnet" arguments=".\MyApp.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
The result is that when I click on the IIS authentication configuration, I get an error. If I remove the aspNetCore tag I can view the authentication settings, but then the application doesn't actually start.
Before you start giving advice about not using web.config for .NET Core, remember that it works on my other machine. Also, I need to use Windows Security and ASP.NET Impersonation.
Both machines are running Windows 10 Pro, and I have checked the following
IIS features installed: identical
WAS and W3SVC: both started and running under Local System
Application Pool: both have .Net 4.0 CLR, classic mode
Folder and file security: identical
Binary compare of the application and all dlls: identical
I don't normally work with IIS and .NET, so I'm quite puzzled that my application breaks on one of two seemingly identical installations. I have run out of things to check. Any help or pointers would be greatly appreciated.
Here is the complete web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<authentication mode="Windows" />
<authorization>
<deny users="?" />
</authorization>
<identity impersonate="true" />
</system.web>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\MyApp.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
</system.webServer>
</configuration>
<!--ProjectGuid: a447f5e7-6aee-4d26-bef4-c7111a88c409-->
I was also facing the same issue and it was because the machine
was missing the NET Core Windows Server Hosting bundle. If this is not installed then IIS cannot recognize the aspNetCore section in web.config
You can install the bundle from below location.
NET Core Windows Server Hosting bundle

Upload large file (>4MB) with asp.net 5.0 app hosted on windows azure

I want to upload a large file ( >4mb ) to my asp.net 5.0 app, everything works great on my computer using this config :
<configuration>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2147483648" maxQueryString="2000">
</requestLimits>
</requestFiltering>
</security>
<handlers>
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
</handlers>
<httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" forwardWindowsAuthToken="false" startupTimeLimit="3600" />
</system.webServer>
<system.web>
<httpRuntime maxRequestLength="102400000" />
</system.web>
</configuration>
But on azure ( Web Role ) it only works for files under 4MB.
I think that IIS is fine, it's Kestrel or the webListner which doesn't want to process the request ( I get "The specified CGI application encountered an error and the server terminated the process." ), I don't know if it possible to configure it too.
Sounds like another limit being hit. The system.web section is ineffective on ASP.NET 5 applications
From this article (vNext maxRequestLength):
There are no predefined configurations in ASP.NET 5.0 :
All configuration is done in code
There is no System.Web in ASP.NET 5.0.
You can still use web.config for IIS settings only
Support for MaxRequestLength is coming

Resources