diff --git a/aspnetcore/fundamentals/servers/aspnet-core-module.md b/aspnetcore/fundamentals/servers/aspnet-core-module.md index f3a1b83b53b6..b3d0cdc3767a 100644 --- a/aspnetcore/fundamentals/servers/aspnet-core-module.md +++ b/aspnetcore/fundamentals/servers/aspnet-core-module.md @@ -1,126 +1,59 @@ --- title: ASP.NET Core Module author: tdykstra -description: Introduces ASP.NET Core Module (ANCM), an IIS module that lets the Kestrel web server use IIS or IIS Express as a reverse proxy server. +description: Learn how the ASP.NET Core Module allows the Kestrel web server to use IIS or IIS Express as a reverse proxy server. manager: wpickett ms.author: tdykstra -ms.custom: H1Hack27Feb2017 -ms.date: 08/03/2017 +ms.custom: mvc +ms.date: 02/23/2018 ms.prod: asp.net-core ms.technology: aspnet ms.topic: article uid: fundamentals/servers/aspnet-core-module --- -# Introduction to ASP.NET Core Module +# ASP.NET Core Module By [Tom Dykstra](https://github.com/tdykstra), [Rick Strahl](https://github.com/RickStrahl), and [Chris Ross](https://github.com/Tratcher) -ASP.NET Core Module (ANCM) lets you run ASP.NET Core applications behind IIS, using IIS for what it's good at (security, manageability, and lots more) and using [Kestrel](kestrel.md) for what it's good at (being really fast), and getting the benefits from both technologies at once. **ANCM works only with Kestrel; it isn't compatible with WebListener (in ASP.NET Core 1.x) or HTTP.sys (in 2.x).** +The ASP.NET Core Module allows ASP.NET Core apps to run behind IIS in a reverse proxy configuration. IIS provides advanced web app security and manageability features. Supported Windows versions: -* Windows 7 and Windows Server 2008 R2 and later +* Windows 7 or later +* Windows Server 2008 R2 or later† -[View or download sample code](https://github.com/aspnet/Docs/tree/master/aspnetcore/fundamentals/servers/aspnet-core-module/sample) ([how to download](xref:tutorials/index#how-to-download-a-sample)) +†Conceptually, the use of the ASP.NET Core Module with IIS described in this document also applies to hosting ASP.NET Core apps on Nano Server IIS. For instructions specific to Nano Server, see the [ASP.NET Core with IIS on Nano Server](xref:tutorials/nano-server) tutorial. -## What ASP.NET Core Module does +The ASP.NET Core Module only works with Kestrel. The module is incompatible with [HTTP.sys](xref:fundamentals/servers/httpsys) (formerly called [WebListener](xref:fundamentals/servers/weblistener)). -ANCM is a native IIS module that hooks into the IIS pipeline and redirects traffic to the backend ASP.NET Core application. Most other modules, such as windows authentication, still get a chance to run. ANCM only takes control when a handler is selected for the request, and handler mapping is defined in the application *web.config* file. +## ASP.NET Core Module description -Because ASP.NET Core applications run in a process separate from the IIS worker process, ANCM also does process management. ANCM starts the process for the ASP.NET Core application when the first request comes in and restarts it when it crashes. This is essentially the same behavior as classic ASP.NET applications that run in-process in IIS and are managed by WAS (Windows Activation Service). +The ASP.NET Core Module is a native IIS module that plugs into the IIS pipeline to redirect web requests to backend ASP.NET Core apps. Many native modules, such as Windows Authentication, remain active. To learn more about IIS modules active with the module, see [Using IIS modules](xref:host-and-deploy/iis/modules). -Here's a diagram that illustrates the relationship between IIS, ANCM, and ASP.NET Core applications. +Because ASP.NET Core apps run in a process separate from the IIS worker process, the module also handles process management. The module starts the process for the ASP.NET Core app when the first request arrives and restarts the app if it crashes. This is essentially the same behavior as seen with ASP.NET 4.x apps that run in-process in IIS that are managed by the [Windows Process Activation Service (WAS)](/iis/manage/provisioning-and-managing-iis/features-of-the-windows-process-activation-service-was). -![ASP.NET Core Module](aspnet-core-module/_static/ancm.png) - -Requests come in from the Web and hit the kernel mode Http.Sys driver which routes them into IIS on the primary port (80) or SSL port (443). ANCM forwards the requests to the ASP.NET Core application on the HTTP port configured for the application, which isn't port 80/443. - -Kestrel listens for traffic coming from ANCM. ANCM specifies the port via environment variable at startup, and the [UseIISIntegration](#call-useiisintegration) method configures the server to listen on `http://localhost:{port}`. There are additional checks to reject requests not from ANCM. (ANCM doesn't support HTTPS forwarding, so requests are forwarded over HTTP even if received by IIS over HTTPS.) - -Kestrel picks up requests from ANCM and pushes them into the ASP.NET Core middleware pipeline, which then handles them and passes them on as `HttpContext` instances to application logic. The application's responses are then passed back to IIS, which pushes them back out to the HTTP client that initiated the requests. - -ANCM has a few other functions as well: - -* Sets environment variables. -* Logs `stdout` output to file storage. -* Forwards Windows authentication tokens. - -## How to use ANCM in ASP.NET Core apps - -This section provides an overview of the process for setting up an IIS server and ASP.NET Core application. For detailed instructions, see [Host on Windows with IIS](xref:host-and-deploy/iis/index). - -### Install ANCM - -The ANCM is installed in IIS on Windows Server and in IIS Express on Windows desktop operating systems. For servers and development machines, the ANCM is included in the [.NET Core Windows Server Hosting bundle](https://aka.ms/dotnetcore-2-windowshosting). If installing Visual Studio, the ANCM is automatically installed in IIS Express (and in IIS, if present on the machine). - -### .NET Core Windows Server Hosting bundle - -The [.NET Core Windows Server Hosting bundle](https://aka.ms/dotnetcore-2-windowshosting) installs the .NET Core Runtime, .NET Core Library, and the ANCM. For more information, see [Install the .NET Core Windows Server Hosting bundle]( -xref:host-and-deploy/iis/index#install-the-net-core-windows-server-hosting-bundle). - -### Install the IISIntegration NuGet package - -# [ASP.NET Core 2.x](#tab/aspnetcore2x) - -The [Microsoft.AspNetCore.Server.IISIntegration](https://www.nuget.org/packages/Microsoft.AspNetCore.Server.IISIntegration/) package is included in the ASP.NET Core metapackages ([Microsoft.AspNetCore](https://www.nuget.org/packages/Microsoft.AspNetCore/) and [Microsoft.AspNetCore.All](xref:fundamentals/metapackage)). If you don't use one of the metapackages, install `Microsoft.AspNetCore.Server.IISIntegration` separately. The `IISIntegration` package is an interoperability pack that reads environment variables broadcast by ANCM to set up your app. The environment variables provide configuration information, such as the port to listen on. - -# [ASP.NET Core 1.x](#tab/aspnetcore1x) - -In your application, install [Microsoft.AspNetCore.Server.IISIntegration](https://www.nuget.org/packages/Microsoft.AspNetCore.Server.IISIntegration/). The `IISIntegration` package is an interoperability pack that reads environment variables broadcast by ANCM to set up your app. The environment variables provide configuration information, such as the port to listen on. - ---- +The following diagram illustrates the relationship between IIS, the ASP.NET Core Module, and ASP.NET Core apps: -### Call UseIISIntegration - -# [ASP.NET Core 2.x](#tab/aspnetcore2x) - -The `UseIISIntegration` extension method on [`WebHostBuilder`](https://docs.microsoft.com/aspnet/core/api/microsoft.aspnetcore.hosting.webhostbuilder) is called automatically when you run with IIS. - -If you aren't using one of the ASP.NET Core metapackages and haven't installed the `Microsoft.AspNetCore.Server.IISIntegration` package, you get a runtime error. If you call `UseIISIntegration` explicitly, you get a compile time error if the package isn't installed. - -# [ASP.NET Core 1.x](#tab/aspnetcore1x) - -In your application's `Main` method, call the `UseIISIntegration` extension method on [`WebHostBuilder`](https://docs.microsoft.com/aspnet/core/api/microsoft.aspnetcore.hosting.webhostbuilder). - -[!code-csharp[](aspnet-core-module/sample/Program.cs?name=snippet_Main&highlight=12)] - ---- - -The `UseIISIntegration` method looks for environment variables that ANCM sets, and it no-ops if they aren't found. This behavior facilitates scenarios like developing and testing on macOS or Linux and deploying to a server that runs IIS. While running on macOS or Linux, Kestrel acts as the web server; but when the app is deployed to the IIS environment, it automatically uses ANCM and IIS. - -### ANCM port binding overrides other port bindings - -# [ASP.NET Core 2.x](#tab/aspnetcore2x) - -ANCM generates a dynamic port to assign to the back-end process. The `UseIISIntegration` method picks up this dynamic port and configures Kestrel to listen on `http://locahost:{dynamicPort}/`. This overrides other URL configurations, such as calls to `UseUrls` or [Kestrel's Listen API](xref:fundamentals/servers/kestrel?tabs=aspnetcore2x#endpoint-configuration). Therefore, you don't need to call `UseUrls` or Kestrel's `Listen` API when you use ANCM. If you do call `UseUrls` or `Listen`, Kestrel listens on the port you specify when you run the app without IIS. - -# [ASP.NET Core 1.x](#tab/aspnetcore1x) - -ANCM generates a dynamic port to assign to the back-end process. The `UseIISIntegration` method picks up this dynamic port and configures Kestrel to listen on `http://locahost:{dynamicPort}/`. This overrides other URL configurations, such as calls to `UseUrls`. Therefore, you don't need to call `UseUrls` when you use ANCM. If you do call `UseUrls`, Kestrel listens on the port you specify when you run the app without IIS. - -In ASP.NET Core 1.0, if you call `UseUrls`, call it **before** you call `UseIISIntegration` so that the ANCM-configured port doesn't get overwritten. This calling order isn't required in ASP.NET Core 1.1, because the ANCM setting overrides `UseUrls`. - ---- - -### Configure ANCM options in Web.config +![ASP.NET Core Module](aspnet-core-module/_static/ancm.png) -Configuration for the ASP.NET Core Module is stored in the *web.config* file that's located in the application's root folder. Settings in this file point to the startup command and arguments that start your ASP.NET Core app. For sample *web.config* code and guidance on configuration options, see [ASP.NET Core Module Configuration Reference](xref:host-and-deploy/aspnet-core-module). +Requests arrive from the web to the kernel-mode HTTP.sys driver. The driver routes the requests to IIS on the website's configured port, usually 80 (HTTP) or 443 (HTTPS). The module forwards the requests to Kestrel on a random port for the app, which isn't port 80/443. -### Run with IIS Express in development +The module specifies the port via an environment variable at startup, and the IIS Integration Middleware configures the server to listen on `http://localhost:{port}`. Additional checks are performed, and requests that don't originate from the module are rejected. The module doesn't support HTTPS forwarding, so requests are forwarded over HTTP even if received by IIS over HTTPS. -IIS Express can be launched by Visual Studio using the default profile defined by the ASP.NET Core templates. +After Kestrel picks up a request from the module, the request is pushed into the ASP.NET Core middleware pipeline. The middleware pipeline handles the request and passes it on as an `HttpContext` instance to the app's logic. The app's response is passed back to IIS, which pushes it back out to the HTTP client that initiated the request. -## Proxy configuration uses HTTP protocol and a pairing token +The ASP.NET Core Module has a few other functions. The module can: -The proxy created between the ANCM and Kestrel uses the HTTP protocol. Using HTTP is a performance optimization where the traffic between the ANCM and Kestrel takes place on a loopback address off of the network interface. There's no risk of eavesdropping the traffic between the ANCM and Kestrel from a location off of the server. +* Set environment variables for the worker process. +* Log `stdout` output to file storage for troubleshooting startup issues. +* Forward Windows authentication tokens. -A pairing token is used to guarantee that the requests received by Kestrel were proxied by IIS and didn't come from some other source. The pairing token is created and set into an environment variable (`ASPNETCORE_TOKEN`) by the ANCM. The pairing token is also set into a header (`MSAspNetCoreToken`) on every proxied request. IIS Middleware checks each request it receives to confirm that the pairing token header value matches the environment variable value. If the token values are mismatched, the request is logged and rejected. The pairing token environment variable and the traffic between the ANCM and Kestrel aren't accessible from a location off of the server. Without knowing the pairing token value, an attacker can't submit requests that bypass the check in the IIS Middleware. +## How to install and use the ASP.NET Core Module -## Next steps +For detailed instructions on how to install and use the ASP.NET Core Module, see [Host on Windows with IIS](xref:host-and-deploy/iis/index). For information on configuring the module, see the [ASP.NET Core Module configuration reference](xref:host-and-deploy/aspnet-core-module). -For more information, see the following resources: +## Additional resources -* [Sample app for this article](https://github.com/aspnet/Docs/tree/master/aspnetcore/fundamentals/servers/aspnet-core-module/sample) -* [ASP.NET Core Module source code](https://github.com/aspnet/AspNetCoreModule) -* [ASP.NET Core Module Configuration Reference](xref:host-and-deploy/aspnet-core-module) * [Host on Windows with IIS](xref:host-and-deploy/iis/index) +* [ASP.NET Core Module configuration reference](xref:host-and-deploy/aspnet-core-module) +* [ASP.NET Core Module GitHub repository (source code)](https://github.com/aspnet/AspNetCoreModule) diff --git a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/AspNetCoreModuleDemo.sln b/aspnetcore/fundamentals/servers/aspnet-core-module/sample/AspNetCoreModuleDemo.sln deleted file mode 100644 index 58f67107552b..000000000000 --- a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/AspNetCoreModuleDemo.sln +++ /dev/null @@ -1,22 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "AspNetCoreModuleDemo", "AspNetCoreModuleDemo.xproj", "{C270F740-C62C-4F88-A2DC-C3F7E9DC61E8}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C270F740-C62C-4F88-A2DC-C3F7E9DC61E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C270F740-C62C-4F88-A2DC-C3F7E9DC61E8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C270F740-C62C-4F88-A2DC-C3F7E9DC61E8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C270F740-C62C-4F88-A2DC-C3F7E9DC61E8}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/AspNetCoreModuleDemo.xproj b/aspnetcore/fundamentals/servers/aspnet-core-module/sample/AspNetCoreModuleDemo.xproj deleted file mode 100644 index f91798b8d540..000000000000 --- a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/AspNetCoreModuleDemo.xproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - c270f740-c62c-4f88-a2dc-c3f7e9dc61e8 - ServersDemo - ..\..\artifacts\obj\$(MSBuildProjectName) - .\bin\ - - - 2.0 - 5634 - - - \ No newline at end of file diff --git a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/Program.cs b/aspnetcore/fundamentals/servers/aspnet-core-module/sample/Program.cs deleted file mode 100644 index 10d30eec5723..000000000000 --- a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/Program.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.IO; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; - -namespace AspNetCoreModuleDemo -{ - /// - /// Executing the "dotnet run" command in the application folder will run this app. - /// You can also run "dotnet publish" and specify the publish directory as the physical path of a site in IIS Manager. - /// - public class Program - { - // The default listening address is http://localhost:5000 if none is specified. - // You can use the --urls command-line flag to change the listening address when - // running without IIS. Example: - // > dotnet run --urls http://localhost:8080 - - // Use the following code to configure URLs in code: - // builder.UseUrls("http://localhost:8080"); - // Put it after UseConfiguration(config) to take precedence over - // command-line configuration. IIS config will take precedence over - // UseUrls. - #region snippet_Main - public static int Main(string[] args) - { - var config = new ConfigurationBuilder() - .AddCommandLine(args) - .Build(); - - var builder = new WebHostBuilder() - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseConfiguration(config) - .UseStartup() - .UseUrls("http://localhost:5001") - .UseIISIntegration() - .UseKestrel(options => - { - if (config["threadCount"] != null) - { - options.ThreadCount = int.Parse(config["threadCount"]); - } - }); - - var host = builder.Build(); - host.Run(); - - return 0; - } - #endregion - } -} diff --git a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/Properties/launchSettings.json b/aspnetcore/fundamentals/servers/aspnet-core-module/sample/Properties/launchSettings.json deleted file mode 100644 index 02f9d97b4a1e..000000000000 --- a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/Properties/launchSettings.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:6314/", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} \ No newline at end of file diff --git a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/Startup.cs b/aspnetcore/fundamentals/servers/aspnet-core-module/sample/Startup.cs deleted file mode 100644 index a4bbf4aa9d12..000000000000 --- a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/Startup.cs +++ /dev/null @@ -1,52 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Hosting.Server.Features; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Extensions; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using System; - -namespace AspNetCoreModuleDemo -{ - public class Startup - { - public Startup(IHostingEnvironment env) - { - Configuration = new ConfigurationBuilder() - .SetBasePath(env.ContentRootPath) - .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) - .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) - .AddEnvironmentVariables() - .Build(); - } - - public IConfigurationRoot Configuration { get; private set; } - - public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) - { - loggerFactory.AddConsole(Configuration.GetSection("Logging")); - - var serverAddressesFeature = app.ServerFeatures.Get(); - - app.UseStaticFiles(); - - app.Run(async (context) => - { - context.Response.ContentType = "text/html"; - await context.Response.WriteAsync("

Hosted by Kestrel

"); - // ASPNETCORE_PORT is the port that IIS proxies requests to. - if (Environment.GetEnvironmentVariable("ASPNETCORE_PORT") != null) - { - await context.Response.WriteAsync("Using IIS as reverse proxy."); - } - if (serverAddressesFeature != null) - { - await context.Response.WriteAsync($"

Listening on the following addresses: {string.Join(", ", serverAddressesFeature.Addresses)}

"); - } - - await context.Response.WriteAsync($"

Request URL: {context.Request.GetDisplayUrl()}

"); - }); - } - } -} diff --git a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/appsettings.json b/aspnetcore/fundamentals/servers/aspnet-core-module/sample/appsettings.json deleted file mode 100644 index fa8ce71a97a3..000000000000 --- a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/appsettings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - } -} diff --git a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/project.json b/aspnetcore/fundamentals/servers/aspnet-core-module/sample/project.json deleted file mode 100644 index 204d807a4ae4..000000000000 --- a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/project.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "version": "1.0.0-*", - - "dependencies": { - "Microsoft.AspNetCore.Server.Kestrel": "1.1.0", - "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0", - "Microsoft.Extensions.Logging.Console": "1.1.0", - "Microsoft.Extensions.Configuration.FileExtensions": "1.1.0", - "Microsoft.Extensions.Configuration.CommandLine": "1.1.0", - "Microsoft.Extensions.Configuration.Json": "1.1.0", - "Microsoft.AspNetCore.StaticFiles": "1.1.0" - }, - - "tools": { - "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final" - }, - - "buildOptions": { - "emitEntryPoint": true - }, - - "frameworks": { - "netcoreapp1.0": { - "dependencies": { - "Microsoft.NETCore.App": { - "version": "1.1.0", - "type": "platform" - }, - "System.Console": "4.3.0" - } - }, - "net451": {} - }, - - "publishOptions": { - "include": [ - "wwwroot", - "web.config" - ] - }, - - "scripts": { - "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] - } -} diff --git a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/web.config b/aspnetcore/fundamentals/servers/aspnet-core-module/sample/web.config deleted file mode 100644 index e62e1a101fc8..000000000000 --- a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/web.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/wwwroot/demo.html b/aspnetcore/fundamentals/servers/aspnet-core-module/sample/wwwroot/demo.html deleted file mode 100644 index fd35dfb041b4..000000000000 --- a/aspnetcore/fundamentals/servers/aspnet-core-module/sample/wwwroot/demo.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - AspNetCoreModuleDemo - - -

Hello from static HTML!

- - \ No newline at end of file diff --git a/aspnetcore/fundamentals/static-files.md b/aspnetcore/fundamentals/static-files.md index 991bf45b3fba..aff7b3dba6b7 100644 --- a/aspnetcore/fundamentals/static-files.md +++ b/aspnetcore/fundamentals/static-files.md @@ -233,7 +233,7 @@ With the preceding code, a request for a file with an unknown content type is re * The URLs for content exposed with `UseDirectoryBrowser` and `UseStaticFiles` are subject to the case sensitivity and character restrictions of the underlying file system. For example, Windows is case insensitive—Mac and Linux aren't. -* ASP.NET Core apps hosted in IIS use the [ASP.NET Core Module (ANCM)](xref:fundamentals/servers/aspnet-core-module) to forward all requests to the app, including static file requests. The IIS static file handler isn't used. It has no chance to handle requests before they're handled by the ANCM. +* ASP.NET Core apps hosted in IIS use the [ASP.NET Core Module](xref:fundamentals/servers/aspnet-core-module) to forward all requests to the app, including static file requests. The IIS static file handler isn't used. It has no chance to handle requests before they're handled by the module. * Complete the following steps in IIS Manager to remove the IIS static file handler at the server or website level: 1. Navigate to the **Modules** feature. @@ -241,7 +241,7 @@ With the preceding code, a request for a file with an unknown content type is re 1. Click **Remove** in the **Actions** sidebar. > [!WARNING] -> If the IIS static file handler is enabled **and** the ANCM is configured incorrectly, static files are served. This happens, for example, if the *web.config* file isn't deployed. +> If the IIS static file handler is enabled **and** the ASP.NET Core Module is configured incorrectly, static files are served. This happens, for example, if the *web.config* file isn't deployed. * Place code files (including *.cs* and *.cshtml*) outside of the app project's web root. A logical separation is therefore created between the app's client-side content and server-based code. This prevents server-side code from being leaked. diff --git a/aspnetcore/host-and-deploy/aspnet-core-module.md b/aspnetcore/host-and-deploy/aspnet-core-module.md index be78beffc5a1..c5ed76f17eaa 100644 --- a/aspnetcore/host-and-deploy/aspnet-core-module.md +++ b/aspnetcore/host-and-deploy/aspnet-core-module.md @@ -124,6 +124,12 @@ The following sample `aspNetCore` element configures `stdout` logging for an app See [Configuration with web.config](#configuration-with-webconfig) for an example of the `aspNetCore` element in the *web.config* file. +## Proxy configuration uses HTTP protocol and a pairing token + +The proxy created between the ASP.NET Core Module and Kestrel uses the HTTP protocol. Using HTTP is a performance optimization, where the traffic between the module and Kestrel takes place on a loopback address off of the network interface. There's no risk of eavesdropping the traffic between the module and Kestrel from a location off of the server. + +A pairing token is used to guarantee that the requests received by Kestrel were proxied by IIS and didn't come from some other source. The pairing token is created and set into an environment variable (`ASPNETCORE_TOKEN`) by the module. The pairing token is also set into a header (`MSAspNetCoreToken`) on every proxied request. IIS Middleware checks each request it receives to confirm that the pairing token header value matches the environment variable value. If the token values are mismatched, the request is logged and rejected. The pairing token environment variable and the traffic between the module and Kestrel aren't accessible from a location off of the server. Without knowing the pairing token value, an attacker can't submit requests that bypass the check in the IIS Middleware. + ## ASP.NET Core Module with an IIS Shared Configuration The ASP.NET Core Module installer runs with the privileges of the **SYSTEM** account. Because the local system account doesn't have modify permission for the share path used by the IIS Shared Configuration, the installer hits an access denied error when attempting to configure the module settings in *applicationHost.config* on the share. When using an IIS Shared Configuration, follow these steps: diff --git a/aspnetcore/host-and-deploy/iis/index.md b/aspnetcore/host-and-deploy/iis/index.md index 192a263ccfa5..3e5e1bd8add0 100644 --- a/aspnetcore/host-and-deploy/iis/index.md +++ b/aspnetcore/host-and-deploy/iis/index.md @@ -40,6 +40,8 @@ public static IWebHost BuildWebHost(string[] args) => ... ``` +The ASP.NET Core Module generates a dynamic port to assign to the back-end process. The `UseIISIntegration` method picks up the dynamic port and configures Kestrel to listen on `http://locahost:{dynamicPort}/`. This overrides other URL configurations, such as calls to `UseUrls` or [Kestrel's Listen API](xref:fundamentals/servers/kestrel#endpoint-configuration). Therefore, calls to `UseUrls` or Kestrel's `Listen` API aren't required when using the module. If `UseUrls` or `Listen` is called, Kestrel listens on the port specified when running the app without IIS. + # [ASP.NET Core 1.x](#tab/aspnetcore1x) Include a dependency on the [Microsoft.AspNetCore.Server.IISIntegration](https://www.nuget.org/packages/Microsoft.AspNetCore.Server.IISIntegration/) package in the app's dependencies. Use IIS Integration middleware by adding the [UseIISIntegration](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilderiisextensions.useiisintegration) extension method to [WebHostBuilder](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilder): @@ -53,6 +55,10 @@ var host = new WebHostBuilder() Both [UseKestrel](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilderkestrelextensions.usekestrel) and [UseIISIntegration](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilderiisextensions.useiisintegration) are required. Code calling `UseIISIntegration` doesn't affect code portability. If the app isn't run behind IIS (for example, the app is run directly on Kestrel), `UseIISIntegration` doesn't operate. +The ASP.NET Core Module generates a dynamic port to assign to the back-end process. The `UseIISIntegration` method picks up the dynamic port and configures Kestrel to listen on `http://locahost:{dynamicPort}/`. This overrides other URL configurations, such as calls to `UseUrls`. Therefore, a call to `UseUrls` isn't required when using the module. If `UseUrls` is called, Kestrel listens on the port specified when running the app without IIS. + +If `UseUrls` is called in an ASP.NET Core 1.0 app, call it **before** calling `UseIISIntegration` so that the module-configured port isn't overwritten. This calling order isn't required with ASP.NET Core 1.1 because the module setting overrides `UseUrls`. + --- For more information on hosting, see [Hosting in ASP.NET Core](xref:fundamentals/hosting). diff --git a/aspnetcore/security/authentication/windowsauth.md b/aspnetcore/security/authentication/windowsauth.md index 6196e629ea84..38248642749d 100644 --- a/aspnetcore/security/authentication/windowsauth.md +++ b/aspnetcore/security/authentication/windowsauth.md @@ -51,7 +51,7 @@ Alternatively, these two properties can be configured in the *launchSettings.jso ## Enable Windows authentication with IIS -IIS uses the [ASP.NET Core Module](xref:fundamentals/servers/aspnet-core-module) (ANCM) to host ASP.NET Core apps. The ANCM flows Windows authentication to IIS by default. Configuration of Windows authentication is done within IIS, not the application project. The following sections show how to use IIS Manager to configure an ASP.NET Core app to use Windows authentication. +IIS uses the [ASP.NET Core Module](xref:fundamentals/servers/aspnet-core-module) to host ASP.NET Core apps. The module flows Windows authentication to IIS by default. Windows authentication is configured in IIS, not the app. The following sections show how to use IIS Manager to configure an ASP.NET Core app to use Windows authentication. ### Create a new IIS site diff --git a/aspnetcore/tutorials/nano-server.md b/aspnetcore/tutorials/nano-server.md index d6ffb23c7dd9..3d57bc5b0c09 100644 --- a/aspnetcore/tutorials/nano-server.md +++ b/aspnetcore/tutorials/nano-server.md @@ -97,9 +97,9 @@ Install-NanoServerPackage -Name Microsoft-NanoServer-IIS-Package To quickly verify if IIS is setup correctly, you can visit the URL `http://192.168.1.10/` and should see a welcome page. When IIS is installed, a website called `Default Web Site` listening on port 80 is created by default. -## Installing the ASP.NET Core Module (ANCM) +## Install the ASP.NET Core Module -The ASP.NET Core Module is an IIS 7.5+ module which is responsible for process management of ASP.NET Core HTTP listeners and to proxy requests to processes that it manages. At the moment, the process to install the ASP.NET Core Module for IIS is manual. You will need to install the [.NET Core Windows Server Hosting bundle](https://download.microsoft.com/download/B/1/D/B1D7D5BF-3920-47AA-94BD-7A6E48822F18/DotNetCore.2.0.0-WindowsHosting.exe) on a regular (not Nano) machine. After installing the bundle on a regular machine, you will need to copy the following files to the file share that we created earlier. +The ASP.NET Core Module is an IIS 7.5+ module which is responsible for process management of ASP.NET Core HTTP listeners and to proxy requests to processes that it manages. At the moment, the process to install the ASP.NET Core Module for IIS is manual. Install the [.NET Core Windows Server Hosting bundle](https://aka.ms/dotnetcore-2-windowshosting) on a regular (not Nano) machine. After installing the bundle on a regular machine, copy the following files to the file share that we created earlier. On a regular (not Nano) server with IIS, run the following copy commands: @@ -119,39 +119,7 @@ Copy-Item -Path C:\PublishedApps\AspNetCoreSampleForNano\aspnetcore_schema.xml - Run the following script in the remote session: -```PowerShell -# Backup existing applicationHost.config -Copy-Item -Path C:\Windows\System32\inetsrv\config\applicationHost.config -Destination C:\Windows\System32\inetsrv\config\applicationHost_BeforeInstallingANCM.config - -Import-Module IISAdministration - -# Initialize variables -$aspNetCoreHandlerFilePath="C:\windows\system32\inetsrv\aspnetcore.dll" -Reset-IISServerManager -confirm:$false -$sm = Get-IISServerManager - -# Add AppSettings section -$sm.GetApplicationHostConfiguration().RootSectionGroup.Sections.Add("appSettings") - -# Set Allow for handlers section -$appHostconfig = $sm.GetApplicationHostConfiguration() -$section = $appHostconfig.GetSection("system.webServer/handlers") -$section.OverrideMode="Allow" - -# Add aspNetCore section to system.webServer -$sectionaspNetCore = $appHostConfig.RootSectionGroup.SectionGroups["system.webServer"].Sections.Add("aspNetCore") -$sectionaspNetCore.OverrideModeDefault = "Allow" -$sm.CommitChanges() - -# Configure globalModule -Reset-IISServerManager -confirm:$false -$globalModules = Get-IISConfigSection "system.webServer/globalModules" | Get-IISConfigCollection -New-IISConfigCollectionElement $globalModules -ConfigAttribute @{"name"="AspNetCoreModule";"image"=$aspNetCoreHandlerFilePath} - -# Configure module -$modules = Get-IISConfigSection "system.webServer/modules" | Get-IISConfigCollection -New-IISConfigCollectionElement $modules -ConfigAttribute @{"name"="AspNetCoreModule"} -``` +[!code-powershell[](nano-server/enable-aspnetcoremodule.ps1)] > [!NOTE] > Delete the files *aspnetcore.dll* and *aspnetcore_schema.xml* from the share after the above step. diff --git a/aspnetcore/tutorials/nano-server/enable-ancm.ps1 b/aspnetcore/tutorials/nano-server/enable-aspnetcoremodule.ps1 similarity index 87% rename from aspnetcore/tutorials/nano-server/enable-ancm.ps1 rename to aspnetcore/tutorials/nano-server/enable-aspnetcoremodule.ps1 index 6aaa07a8d1e0..3710e9886689 100644 --- a/aspnetcore/tutorials/nano-server/enable-ancm.ps1 +++ b/aspnetcore/tutorials/nano-server/enable-aspnetcoremodule.ps1 @@ -1,5 +1,5 @@ # Backup existing applicationHost.config -copy C:\Windows\System32\inetsrv\config\applicationHost.config C:\Windows\System32\inetsrv\config\applicationHost_BeforeInstallingANCM.config +copy C:\Windows\System32\inetsrv\config\applicationHost.config C:\Windows\System32\inetsrv\config\applicationHost_BeforeInstallingAspNetCoreModule.config Import-Module IISAdministration @@ -29,7 +29,3 @@ New-IISConfigCollectionElement $globalModules -ConfigAttribute @{"name"="AspNetC # Configure module $modules = Get-IISConfigSection "system.webServer/modules" | Get-IISConfigCollection New-IISConfigCollectionElement $modules -ConfigAttribute @{"name"="AspNetCoreModule"} - -# Backup existing applicationHost.config -copy C:\Windows\System32\inetsrv\config\applicationHost.config C:\Windows\System32\inetsrv\config\applicationHost_AfterInstallingANCM.config -