Hospedaje en proceso con IIS y ASP.NET Core

El hospedaje en proceso ejecuta una aplicación de ASP.NET Core en el mismo proceso que su proceso de trabajo de IIS. El hospedaje en proceso proporciona un rendimiento mejorado con respecto al hospedaje fuera de proceso porque las solicitudes no se realizan mediante proxy en el adaptador de bucle invertido, una interfaz de red que devuelve el tráfico saliente a la misma máquina.

En el siguiente diagrama se muestra la relación entre IIS, el módulo ASP.NET Core y una aplicación hospedada en proceso:

ASP.NET Core Module in the in-process hosting scenario

Habilitación del hospedaje en proceso

A partir de ASP.NET Core 3.0, el hospedaje en proceso se ha habilitado de forma predeterminada en todas las aplicaciones implementadas en IIS.

Para configurar explícitamente una aplicación para un hospedaje fuera de proceso, establezca el valor de la propiedad <AspNetCoreHostingModel> en InProcess en el archivo del proyecto (.csproj):

<PropertyGroup>
  <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>

Arquitectura general

El flujo general de una solicitud es el siguiente:

  1. Una solicitud llega de Internet al controlador HTTP.sys en modo kernel.
  2. El controlador enruta la solicitud nativa a IIS en el puerto configurado del sitio web, que suele ser el puerto 80 (HTTP) o 443 (HTTPS).
  3. El módulo ASP.NET Core recibe la solicitud nativa y la pasa a IIS HTTP Server (IISHttpServer). El servidor HTTP de IIS es una implementación de servidor en proceso para IIS que convierte una solicitud nativa en administrada.

Una vez que el servidor HTTP de IIS procesa la solicitud:

  1. La solicitud se envía a la canalización de middleware de ASP.NET Core.
  2. La canalización de middleware controla la solicitud y la pasa como una instancia de HttpContext a la lógica de la aplicación.
  3. La respuesta de la aplicación se pasa a IIS a través del servidor HTTP de IIS.
  4. IIS envía la respuesta al cliente que inició la solicitud.

CreateDefaultBuilder agrega una instancia IServer mediante una llamada al método UseIIS para iniciar CoreCLR y hospedar la aplicación dentro del proceso de trabajo de IIS (w3wp.exe o iisexpress.exe). Las pruebas de rendimiento indican que el hospedaje de una aplicación .NET Core en proceso proporciona un rendimiento de solicitud considerablemente mayor en comparación con el hospedaje de solicitudes de aplicaciones fuera de proceso y de proxy para Kestrel.

Las aplicaciones publicadas como un único archivo ejecutable no se pueden cargar por el modelo de hospedaje en proceso.

Configuración de aplicación

Para configurar las opciones de IIS, incluya una configuración de servicio para IISServerOptions en Program.cs. En el ejemplo siguiente se deshabilita AutomaticAuthentication:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Server.IIS;
using Microsoft.EntityFrameworkCore;
using RPauth.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();

builder.Services.Configure<IISServerOptions>(options =>
{
    options.AutomaticAuthentication = false;
});

builder.Services.AddTransient<IClaimsTransformation, MyClaimsTransformation>();
builder.Services.AddAuthentication(IISServerDefaults.AuthenticationScheme);

builder.Services.AddRazorPages();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();

app.Run();
Opción Default Parámetro
AutomaticAuthentication true Si es true, el servidor IIS establece el HttpContext.User autenticado mediante la autenticación de Windows. Si es false, el servidor solo proporciona una identidad para HttpContext.User y responde a los desafíos cuando se le solicita explícitamente mediante el AuthenticationScheme. Autenticación de Windows debe estar habilitado en IIS para que AutomaticAuthentication funcione. Para obtener más información, vea Autenticación de Windows.
AuthenticationDisplayName null Establece el nombre para mostrar que se muestra a los usuarios en las páginas de inicio de sesión.
AllowSynchronousIO false Si se permiten la E/S sincrónica para HttpContext.Request y HttpContext.Response.
MaxRequestBodySize 30000000 Obtiene o establece el tamaño máximo del cuerpo de solicitud para HttpRequest. Tenga en cuenta que el propio IIS tiene el límite de maxAllowedContentLength, que se procesará antes que el valor de MaxRequestBodySize establecido en IISServerOptions. El cambio de MaxRequestBodySize no afectará a maxAllowedContentLength. Para aumentar maxAllowedContentLength, agregue una entrada al archivo web.config para establecer maxAllowedContentLength en un valor superior. Para más información, consulte Configuración.

Diferencias entre el hospedaje en proceso y fuera de proceso

Al hospedar en proceso, se aplican las siguientes características:

  • Se usa el servidor HTTP de IIS (IISHttpServer) en lugar del servidor Kestrel. Dentro del proceso, CreateDefaultBuilder llama a UseIIS para:

    • Registrar el IISHttpServer.
    • Configurar el puerto y la ruta de acceso base donde debe escuchar el servidor al ejecutarse detrás del módulo de ASP.NET Core.
    • Configurar el host para capturar errores de inicio.
  • El atributo requestTimeout se aplica al hospedaje en proceso.

  • No se admite el uso compartido de un grupo de aplicaciones entre aplicaciones. Se usa un grupo de aplicaciones por aplicación.

  • La arquitectura (valor de bits) de la aplicación y el runtime instalado (x64 o x86) deben coincidir con la arquitectura del grupo de aplicaciones. Por ejemplo, las aplicaciones publicadas para 32 bits (x86) deben tener habilitados 32 bits para los grupos de aplicaciones de IIS. Para más información, consulte la sección Creación del sitio de IIS.

  • Se detectan las desconexiones del cliente. El token de cancelación de HttpContext.RequestAborted se cancela cuando el cliente se desconecta.

  • Cuando se hospeda en el proceso, no se llama a AuthenticateAsync de forma interna para inicializar un usuario. Por tanto, se usa una implementación de IClaimsTransformation para transformar las notificaciones después de que cada autenticación no se active de forma predeterminada. Al transformar notificaciones con una implementación de IClaimsTransformation, llame a AddAuthentication para agregar servicios de autenticación:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Server.IIS;
using Microsoft.EntityFrameworkCore;
using RPauth.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();

builder.Services.Configure<IISServerOptions>(options =>
{
    options.AutomaticAuthentication = false;
});

builder.Services.AddTransient<IClaimsTransformation, MyClaimsTransformation>();
builder.Services.AddAuthentication(IISServerDefaults.AuthenticationScheme);

builder.Services.AddRazorPages();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();

app.Run();

Obtención de información de control del tiempo

Consulte Implementación del servidor web HTTP.sys en ASP.NET Core.

El hospedaje en proceso ejecuta una aplicación de ASP.NET Core en el mismo proceso que su proceso de trabajo de IIS. El hospedaje en proceso proporciona un rendimiento mejorado con respecto al hospedaje fuera de proceso porque las solicitudes no se realizan mediante proxy en el adaptador de bucle invertido, una interfaz de red que devuelve el tráfico saliente a la misma máquina.

En el siguiente diagrama se muestra la relación entre IIS, el módulo ASP.NET Core y una aplicación hospedada en proceso:

ASP.NET Core Module in the in-process hosting scenario

Habilitación del hospedaje en proceso

A partir de ASP.NET Core 3.0, el hospedaje en proceso se ha habilitado de forma predeterminada en todas las aplicaciones implementadas en IIS.

Para configurar explícitamente una aplicación para un hospedaje fuera de proceso, establezca el valor de la propiedad <AspNetCoreHostingModel> en InProcess en el archivo del proyecto (.csproj):

<PropertyGroup>
  <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>

Arquitectura general

El flujo general de una solicitud es el siguiente:

  1. Una solicitud llega de Internet al controlador HTTP.sys en modo kernel.
  2. El controlador enruta la solicitud nativa a IIS en el puerto configurado del sitio web, que suele ser el puerto 80 (HTTP) o 443 (HTTPS).
  3. El módulo ASP.NET Core recibe la solicitud nativa y la pasa a IIS HTTP Server (IISHttpServer). El servidor HTTP de IIS es una implementación de servidor en proceso para IIS que convierte una solicitud nativa en administrada.

Una vez que el servidor HTTP de IIS procesa la solicitud:

  1. La solicitud se envía a la canalización de middleware de ASP.NET Core.
  2. La canalización de middleware controla la solicitud y la pasa como una instancia de HttpContext a la lógica de la aplicación.
  3. La respuesta de la aplicación se pasa a IIS a través del servidor HTTP de IIS.
  4. IIS envía la respuesta al cliente que inició la solicitud.

CreateDefaultBuilder agrega una instancia IServer mediante una llamada al método UseIIS para iniciar CoreCLR y hospedar la aplicación dentro del proceso de trabajo de IIS (w3wp.exe o iisexpress.exe). Las pruebas de rendimiento indican que el hospedaje de una aplicación .NET Core en proceso proporciona un rendimiento de solicitud considerablemente mayor en comparación con el hospedaje de solicitudes de aplicaciones fuera de proceso y de proxy para Kestrel.

Las aplicaciones publicadas como un único archivo ejecutable no se pueden cargar por el modelo de hospedaje en proceso.

Configuración de aplicación

Para configurar las opciones de IIS, incluya una configuración de servicio para IISServerOptions en ConfigureServices. Con el ejemplo siguiente se deshabilita AutomaticAuthentication:

services.Configure<IISServerOptions>(options => 
{
    options.AutomaticAuthentication = false;
});
Opción Default Parámetro
AutomaticAuthentication true Si es true, el servidor IIS establece el HttpContext.User autenticado mediante la autenticación de Windows. Si es false, el servidor solo proporciona una identidad para HttpContext.User y responde a los desafíos cuando se le solicita explícitamente mediante el AuthenticationScheme. Autenticación de Windows debe estar habilitado en IIS para que AutomaticAuthentication funcione. Para obtener más información, vea Autenticación de Windows.
AuthenticationDisplayName null Establece el nombre para mostrar que se muestra a los usuarios en las páginas de inicio de sesión.
AllowSynchronousIO false Si se permiten la E/S sincrónica para HttpContext.Request y HttpContext.Response.
MaxRequestBodySize 30000000 Obtiene o establece el tamaño máximo del cuerpo de solicitud para HttpRequest. Tenga en cuenta que el propio IIS tiene el límite de maxAllowedContentLength, que se procesará antes que el valor de MaxRequestBodySize establecido en IISServerOptions. El cambio de MaxRequestBodySize no afectará a maxAllowedContentLength. Para aumentar maxAllowedContentLength, agregue una entrada al archivo web.config para establecer maxAllowedContentLength en un valor superior. Para más información, consulte Configuración.

Diferencias entre el hospedaje en proceso y fuera de proceso

Al hospedar en proceso, se aplican las siguientes características:

  • Se usa el servidor HTTP de IIS (IISHttpServer) en lugar del servidor Kestrel. Dentro del proceso, CreateDefaultBuilder llama a UseIIS para:

    • Registrar el IISHttpServer.
    • Configurar el puerto y la ruta de acceso base donde debe escuchar el servidor al ejecutarse detrás del módulo de ASP.NET Core.
    • Configurar el host para capturar errores de inicio.
  • El atributo requestTimeout se aplica al hospedaje en proceso.

  • No se admite el uso compartido de un grupo de aplicaciones entre aplicaciones. Se usa un grupo de aplicaciones por aplicación.

  • La arquitectura (valor de bits) de la aplicación y el runtime instalado (x64 o x86) deben coincidir con la arquitectura del grupo de aplicaciones. Por ejemplo, las aplicaciones publicadas para 32 bits (x86) deben tener habilitados 32 bits para los grupos de aplicaciones de IIS. Para más información, consulte la sección Creación del sitio de IIS.

  • Se detectan las desconexiones del cliente. El token de cancelación de HttpContext.RequestAborted se cancela cuando el cliente se desconecta.

  • Cuando se hospeda en el proceso, no se llama a AuthenticateAsync de forma interna para inicializar un usuario. Por tanto, se usa una implementación de IClaimsTransformation para transformar las notificaciones después de que cada autenticación no se active de forma predeterminada. Al transformar notificaciones con una implementación de IClaimsTransformation, llame a AddAuthentication para agregar servicios de autenticación:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransient<IClaimsTransformation, ClaimsTransformer>();
        services.AddAuthentication(IISServerDefaults.AuthenticationScheme);
    }
    
    public void Configure(IApplicationBuilder app)
    {
        app.UseAuthentication();
    }
    
  • No se admiten implementaciones de paquetes web (archivo único).