This repository has been archived by the owner. It is now read-only.

HttpPlatformHandler has been replaced by ASP.NET Core Module #105

Closed
Tratcher opened this Issue Mar 25, 2016 · 105 comments

Comments

Projects
None yet
@Tratcher
Member

Tratcher commented Mar 25, 2016

Background

In beta8 and rc1 ASP.NET Core Applications hosted in IIS employed a native IIS module, HttpPlatformHandler v1.2, to forward requests to the ASP.NET Core Kestrel Server.

What's Changing?

Going forward we're moving to the ASP.NET Core Module, a new native IIS module, to forward requests to Kestrel.

Why?

We have added Asp.Net specific features, where HttpPlatformHandler was a generic reverse forwarder.

What's new?

AspNetCoreModule v0.8 is based on a fork of HttpPlatformHandler 1.2. Most viable is the rename of the module and associated config entries to avoid conflicts with the existing module. We've also fixed several bugs and added the following features:

Download the new ASP.NET Core Module v0.8

What won't work yet?

There is no tooling support in Visual Studio yet (as of 3/25). In the meantime you'll need to use dotnet publish from the command line and run the application with full IIS. dotnet-publish-iis is also in the process of being updated so some manual web.config manipulation may be necessary.

The module will be deployed to Azure Web Sites in the coming weeks.

Changes to your app

New package dependency

There is a new package Microsoft.AspNetCore.Server.IISIntegration that contains the extension methods to work with ASP.NET Core Module. This replaces Microsoft.AspNetCore.IISPlatformHandler.

Changes to Startup.cs

public class Startup
{
    public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
    {
          ...
          // Remove call to app.UseIISPlatformHandler(); This is handled by UseIIS in Main.
          // Remove call to app.UseForwardedHeaders(); This is handled by UseIIS in Main.
          ...
    }

    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseDefaultConfiguration(args)
            .UseServer("Microsoft.AspNetCore.Server.Kestrel")
            // Replaces call to UseIISPlatformHandlerUrl()
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

        host.Run();
    }
}

Register the new AspNetCoreModule in your web.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath="..\MySite.exe" arguments="" stdoutLogEnabled="false" stdoutLogFile="..\logs\stdout" />
  </system.webServer>
</configuration>
@poke

This comment has been minimized.

poke commented Mar 26, 2016

Will the older HttpPlatformHandler still be supported for later releases of ASP.NET Core? I know that it was already difficult for some people to get their hosters support the HttpPlatformHandler. I was actually hoping for the functionality to eventually merge into IIS itself so an additional module that you need to install wasn’t necessary. This fork now suggests the inverse, that the functionality will always be something separate, and from now on even very specific to ASP.NET Core and Kestrel.

@NickCraver

This comment has been minimized.

NickCraver commented Mar 26, 2016

+1 on the change, I think this allows for much better separation of concerns and ASP.Net improvements down the road.

Might I make a suggestion only tangential to this actual change? It feels very odd to be using a string in .UseServer() when we're having to reference the namespace already, doesn't it?

It seems like there should be another overload to .UseServer(), or a convenience .UseKestrelServer() or similar in play. Any time we have thousands of devs type or copy/pasting the same string, it feels like we can do better. Am I off base here, or should I open an issue?

@robertmuehsig

This comment has been minimized.

robertmuehsig commented Mar 26, 2016

By having a seperate module it feels like ASP.NET Core is somewhat special. I liked the general idea of just having one module and it doesn't matter whats behind it.
Those added features doesn't sound very asp.net specific.
Was the general HttpHandler a performance bottleneck?

@skystedt

This comment has been minimized.

skystedt commented Mar 26, 2016

Will ASP.NET Core Module be made open source?

@ArieJones

This comment has been minimized.

ArieJones commented Mar 26, 2016

Can we get some further details on what manual web.config manipulation may be needed beyond what was addressed above?

@Tratcher

This comment has been minimized.

Member

Tratcher commented Mar 26, 2016

@poke HttpPlatformHandler will not be directly supported past the RC1 release. i.e. RC2 switches over and we'll remove the old code as soon as we get AspNetCoreModule deployed to Azure Web Sites.

That said, it wouldn't be hard for someone to maintain the HttpPlatformHandler support as a community project, there's not that much too it. The biggest gap would be VS integration.

@Tratcher

This comment has been minimized.

Member

Tratcher commented Mar 26, 2016

@robertmuehsig no we haven't added a lot yet, we wanted to get the initial transition out of the way first. Performance is one area we're already experimenting with.

@Tratcher

This comment has been minimized.

Member

Tratcher commented Mar 26, 2016

@skystedt We want it to be open source. Not sure how long the paperwork will take...

@davidfowl

This comment has been minimized.

Member

davidfowl commented Mar 26, 2016

It's going to be OSS 😄

@Eilon

This comment has been minimized.

Member

Eilon commented Mar 26, 2016

Yes, we have plans to make it OSS - hopefully won't be too long before that happens.

@oryol

This comment has been minimized.

oryol commented Mar 28, 2016

Idea of removing any hard linking between new ASP .Net and IIS was cool. Currently it looks like we can't use generic HPH and we need "workaround" module for ASP .Net specific things. So we introduce linking between ASP .Net and IIS again. May be we can do it in some generic way so nothing in IIS will be ASP .Net specific and nothing in ASP .Net web app will be IIS specific?

@Eilon

This comment has been minimized.

Member

Eilon commented Mar 28, 2016

@oryol completely divorcing ASP.NET Core from IIS wasn't a goal. The goal was to ensure that ASP.NET Core is not strictly tied to IIS, which it certainly isn't. Ultimately every web server has some "contract" for loading other systems (e.g. ASP.NET, Node, PHP, etc.). In order to get the best performance from a system, it's often valuable to have a server-specific integration point, and that's what AspNetCodeModule is.

@oryol

This comment has been minimized.

oryol commented Mar 28, 2016

I thought that we will get something like (already classic) backend / frontend server separation. Where all ASP .Net stuff will be only in the Kestrel and we will be able to use any web server as "frontend" server (IIS, nginx or any other) without any downsides. But currently it looks like IIS still will be "main" server for ASP .Net and other configurations.. well.. they will be supported but they will not be "first class" configurations for ASP .Net.

@Eilon

This comment has been minimized.

Member

Eilon commented Mar 28, 2016

@oryol there is still that separation, and Kestrel is generally always used, whether it's a standalone server, running behind nginx, or running under AspNetCoreModule on IIS. It is not the case that IIS is the "main" server, but it's certainly the recommended server when running on Windows. I am not aware of anything that was officially stated by Microsoft that would lead anyone to believe that IIS is the only "first class" configuration for ASP.NET.

@aL3891

This comment has been minimized.

aL3891 commented Mar 28, 2016

I have a feeling i know the answer but there isn't anything specific to kestrel in the AspNetCoreModule is there? it will work the same with any server based on the Asp.net hosting model?

Also can you share (or point to issues) about the plans for the module down the road? What kind of features you're looking to add or what kind of perf improvement you're looking to make? i Agree with others here that the current features seems like they would make sense in the standard HPH, but i guess there are other plans down the road?

@grahamehorner

This comment has been minimized.

grahamehorner commented May 17, 2016

@guardrex

This comment has been minimized.

Contributor

guardrex commented May 17, 2016

@muratg @benaadams Unfortunately, manual AFAIK ... install locally ... move module and schema file to the server ... (yuck). Whether it becomes a Nano package or not, the bundle installer isn't going to work for me ...

Any news on the module becoming OSS? I was told that it was making its way through the gauntlet of approvals needed. My plan was to compile and deploy my own module, as I don't want .NET Core assemblies pre-installed on my servers or anything run portable (i.e., no shared framework ... no env vars on servers to opt-out of telemetry ... + ❤️ app isolation). Any news on how module OSS is coming along?

@shirhatti

This comment has been minimized.

Member

shirhatti commented May 17, 2016

@benaadams we are working on an .appx installer for Nano that has not yet landed. For the time being, you'll need to install ANCM on a full server, copy the DLL and schema for the module and edit the applicationHost.config to include this module. Let me try and write this up by today afternoon

@guardrex

This comment has been minimized.

Contributor

guardrex commented May 17, 2016

@benaadams Also in the blog post ... http://blog.guardrex.com/#install-the-aspnetcoremodule ... one dev said it works. I haven't found the time to confirm, b/c I need to get the IIS packages bit fixed in the post: AFAICT one still needs to use an unattend.xml file to install IIS packages. I hope to get back to it shortly; however, the ANCM bits of the post I think are correct.

@muratg

This comment has been minimized.

Member

muratg commented May 17, 2016

@benaadams Currently you'll need to manually copy the files over for Nano installation. AFAIK, you'll need to copy the dll to C:\windows\system32\inetsrv and the schema to C:\windows\system32\inetsrv\config\schema

cc @pan-wang & @victorhurdugaci

@muratg

This comment has been minimized.

Member

muratg commented May 17, 2016

@guardrex re OSS ANCM... unfortunately no firm date yet, but the goal is to open it up.

@nil4

This comment has been minimized.

nil4 commented May 17, 2016

@muratg please consider publishing the ASP.NET Core Module installer separately. Here's my scenario: I am working on a new application, targeting net461, but trying to keep it compatible with netcoreapp1.0. However, I will not be able to deploy .NET Core pre-release bits to production.

Today the IIS module is bundled with the .NET Core server hosting package, although the previous version (0.8) was available for download separately. This is unfortunate, and as a workaround, I had to find the module installer from my Package Cache folder. Is there a good reason why the installer cannot be published separately?

@Tratcher

This comment has been minimized.

Member

Tratcher commented May 17, 2016

@nil4 We're investigating ways to make the installer more flexible for environments like yours.

@EricSch

This comment has been minimized.

EricSch commented May 24, 2016

What is the scenario to support Windows Authentication on IIS with RC2?
Do I have to use Kestrel or WebListener? How to setup? Didn't find anything actual in the doc.
Thanks for any help

@davidfowl

This comment has been minimized.

Member

davidfowl commented May 24, 2016

What is the scenario to support Windows Authentication on IIS with RC2?

2 options:

  • Use IIS Express/IIS and turn on Windows Authentication.
  • Use WebListener configuring NTLM/Kerberos (whatever you need).

Do I have to use Kestrel or WebListener? How to setup? Didn't find anything actual in the doc.

public static void Main(string[] args)
{
    var host = new WebHostBuilder()
        .UseWebListener(options =>
        {
            options.Listener.AuthenticationManager.AuthenticationSchemes = AuthenticationSchemes.NTLM;
        })
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseIISIntegration()
        .UseStartup<Startup>()
        .Build();

    host.Run();
}
@EricSch

This comment has been minimized.

EricSch commented May 24, 2016

@davidfowl Thank you for answering.

public class Program
    {
        public static void Main(string[] args)
        {
            var config = new ConfigurationBuilder()
             .AddCommandLine(args)
             .AddEnvironmentVariables(prefix: "ASPNETCORE_")
             .AddJsonFile("hosting.json", optional: true)
             .Build();

            var builder = new WebHostBuilder();

            if (string.Equals(config.GetValue<string>("server"), "WebListener", System.StringComparison.OrdinalIgnoreCase))
            {
                builder.UseWebListener(options =>
                {
                    options.Listener.AuthenticationManager.AuthenticationSchemes = AuthenticationSchemes.NTLM;
                });
            }
            else
            {
                builder.UseKestrel();
            }

            builder
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>();

            var host = builder.Build();
            host.Run();
        }
    }

`

I have the following setups (Server 2012 R2 / IIS):

  • Kestrel
  • Windows Authentication enabled
  • forwardWindowsAuthToken="true"
    --> Identity is set, but only for the first client connected, for all other clients, they have the same identity like the first one

or:

  • WebListener (configured by using arguments=".\MyApp.dll server=WebListener" in web.config)
  • Windows Authentication enabled
  • forwardWindowsAuthToken="true"
    --> I get "Bad Gateway"

So I'm not sure what is going wrong.

@davidfowl

This comment has been minimized.

Member

davidfowl commented May 24, 2016

Pick the one you want to use. I'm not sure why you're using both servers. If you're running on IIS, use IIS.

@EricSch

This comment has been minimized.

EricSch commented May 24, 2016

On the server is get:
Failed to start process with commandline 'dotnet .\My.dll server=WebListener', Error Code = '0x8007065f'.

So why does the same command work in a command line? Are in a hosted environment not multiple arguments allowed?

@davidfowl I was using both servers, because I had problems debugging with WebListener in Visual Studio. Will try changing it to WebListener per default.

@EricSch

This comment has been minimized.

EricSch commented May 24, 2016

With WebListener i have the following error:
Failed to start process with commandline 'dotnet .\My.dll', Error Code = '0x8007065f'.

Same error code. What does it mean?

@davidfowl

This comment has been minimized.

Member

davidfowl commented May 24, 2016

WebListener doesn't work with IIS. If you're using IIS then use Kestrel.

@EricSch

This comment has been minimized.

EricSch commented May 24, 2016

Great, then how to use Windows Authentification? Kestrel doesn't work.

@davidfowl

This comment has been minimized.

Member

davidfowl commented May 24, 2016

Let's go back to this:

  • Kestrel
  • Windows Authentication enabled
  • forwardWindowsAuthToken="true" --> Identity is set, but only for the first client connected, for all other - clients, they have the same identity like the first one

So the problem you're seeing is the identity is incorrect? But Windows Auth is working, right?

@EricSch

This comment has been minimized.

EricSch commented May 24, 2016

Yes, Windows Auth is working.

Problem:
I'm connecting initially with User A to the server. Identity is set for User A. Now I'm connecting with User B from a different machine to the server. Identity is still User A.

@davidfowl

This comment has been minimized.

Member

davidfowl commented May 24, 2016

@EricSch can you file a new bug with that information?

@EricSch

This comment has been minimized.

EricSch commented May 26, 2016

@davidfowl After setting up a sample project without having the issue, I reviewed our project and found a logical error caused by injection in our code. Thanks for your time.

@PleasantD

This comment has been minimized.

PleasantD commented Jun 15, 2016

How does IIS interact with the core app with regards to monitoring and restart?
Does setting the apppool to always running and using the applicationInitialization module still work?
Is there anyway to get notified about apppool/site restarts and shutdowns (and maybe delay them while processing is still happening)?

@guardrex

This comment has been minimized.

Contributor

guardrex commented Jun 15, 2016

@karldodd

This comment has been minimized.

karldodd commented Jul 7, 2016

Sorry to be a bit off-the-topic but related:

What is the Nginx equivalent for .UseIISIntegration()? Will there be a UseNginxIntegration()? I failed to find useful information in https://docs.asp.net/en/1.0.0/publishing/linuxproduction.html

@grahamehorner

This comment has been minimized.

grahamehorner commented Jul 7, 2016

@karldodd I'm trying to understand your thoughts around this UseNginxIntegration() ? and I'm unsure what your after with regards this ?

Nginx is/has been recommended as reserve proxy by members of the aspnetcore team for production environments; AFAIW kestrel/aspnet is not hosted/integrated in the same way as it is with IIS; Nginx forwarding requests & provides load balancing etc. and thus .net code doesn't need any knowledge about Nginx.

hope that helps; and this is my understanding; so if I'm wrong please someone correct me.

@karldodd

This comment has been minimized.

karldodd commented Jul 8, 2016

@grahamehorner We already set up Nginx+Kestrel and it is working for the most part, but httpContext.Connection.RemoteIpAddress is not working. So I am looking for something like UseNginxIntegration() which fills in these fileds from http headers like X-Forwarded-For .

@Tratcher

This comment has been minimized.

Member

Tratcher commented Jul 8, 2016

Would UseNginxIntegration do anything more than UseForwardedHeaders?

@muratg

This comment has been minimized.

Member

muratg commented May 12, 2017

We are closing this issue because no further action is planned for this issue. If you still have any issues or questions, please log a new issue with any additional details that you have.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.