Hébergement in-process avec IIS et ASP.NET Core

L’hébergement in-process exécute une application ASP.NET Core dans le même processus que son processus de travail IIS. L’hébergement in-process offre de meilleures performances que l’hébergement out-of-process parce que les requêtes n’ont pas de proxy sur l’adaptateur de bouclage, interface réseau qui retourne du trafic réseau sortant à la même machine.

Le schéma suivant montre la relation entre IIS, le module ASP.NET Core et une application hébergée dans un processus :

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

Activer l’hébergement in-process

Depuis ASP.NET Core 3.0, l’hébergement in-process est activé par défaut pour toutes les applications déployées sur IIS.

Pour configurer explicitement une application pour l’hébergement in-process, définissez la valeur de la propriété <AspNetCoreHostingModel> sur InProcess dans le fichier projet (.csproj) :

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

Architecture générale

Le flux général d’une requête est le suivant :

  1. Une requête arrive du web au pilote HTTP.sys en mode noyau.
  2. Le pilote achemine la requête native vers IIS sur le port configuré du site web, généralement 80 (HTTP) ou 443 (HTTPS).
  3. Le module ASP.NET Core reçoit la requête native et la passe au serveur HTTP IIS (IISHttpServer). Le serveur HTTP IIS est une implémentation du serveur in-process pour IIS qui convertit la requête native en requête managée.

Une fois la requête traitée par le serveur HTTP IIS :

  1. La requête est envoyée au pipeline de middleware (intergiciel) ASP.NET Core.
  2. Le pipeline de middlewares traite la requête et la passe en tant qu’instance de HttpContext à la logique de l’application.
  3. La réponse de l’application est retransmise à IIS via le serveur HTTP IIS.
  4. IIS envoie la réponse au client qui a initié la demande.

CreateDefaultBuilder ajoute une instance de IServer en appelant la méthode UseIIS pour démarrer le CoreCLR et héberger l’application dans le processus de travail IIS (w3wp.exe ou iisexpress.exe). Les tests de performances indiquent que l’hébergement d’une application .NET Core in-process offre un débit de requêtes nettement plus élevé que l’hébergement de l’application hors processus et la proxysation des requêtes vers Kestrel.

Les applications publiées comme un fichier exécutable unique ne peuvent pas être chargées par le modèle d’hébergement in-process.

Configuration de l’application

Pour configurer les options IIS, incluez une configuration de service pour IISServerOptions dans Program.cs. L’exemple suivant désactive 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();
Option Default Paramètre
AutomaticAuthentication true Si true, IIS Server définit le HttpContext.User authentifié par Authentification Windows. Si false, le serveur fournit uniquement une identité pour HttpContext.User et répond aux questions explicitement posées par AuthenticationScheme. L’authentification Windows doit être activée dans IIS pour que AutomaticAuthentication fonctionne. Pour plus d'informations, consultez Authentification Windows.
AuthenticationDisplayName null Définit le nom d’affichage montré aux utilisateurs sur les pages de connexion.
AllowSynchronousIO false Indique si les E/S synchrones sont autorisées pour HttpContext.Request et HttpContext.Response.
MaxRequestBodySize 30000000 Récupère ou définit la taille maximale du corps de la demande de HttpRequest. Il est à noter que IIS a comme limite maxAllowedContentLength, qui doit être traité avant MaxRequestBodySize défini dans IISServerOptions. Les modifications de MaxRequestBodySize n’ont pas d’incidence sur maxAllowedContentLength. Pour augmenter maxAllowedContentLength, ajoutez une entrée dans web.config afin d’affecter à maxAllowedContentLength une valeur plus élevée. Pour plus d’informations, voir Configuration.

Différences entre l’hébergement in-process et out-of-process

Les caractéristiques suivantes s’appliquent lors de l’hébergement in-process :

  • Le serveur IIS HTTP (IISHttpServer) est utilisé à la place du serveur Kestrel. Pour in-process, CreateDefaultBuilder appelle UseIIS pour :

    • Enregistrer IISHttpServer.
    • Configurer le port et le chemin de base sur lesquels le serveur doit écouter lors de l’exécution derrière le module ASP.NET Core.
    • Configurer l’hôte pour capturer des erreurs de démarrage.
  • L’attribut requestTimeout ne s’applique pas à l’hébergement in-process.

  • Le partage d’un pool d’applications entre les applications n’est pas pris en charge. Utilisez un pool d’applications par application.

  • L’architecture (nombre de bits) de l’application et le runtime installé (x64 ou x86) doivent correspondre à l’architecture du pool d’applications. Par exemple, les applications publiées pour les architectures 32 bits (x86) doivent avoir l’architecture 32 bits activée pour leurs pools d’applications IIS. Pour plus d’informations, consultez la section Créer le site IIS.

  • Les déconnexions du client sont détectées. Le jeton d’annulation HttpContext.RequestAborted est annulé lors de la déconnexion du client.

  • Dans le cas d’un hébergement in-process, AuthenticateAsync n’est pas appelé en interne pour initialiser un utilisateur. Par conséquent, une implémentation de IClaimsTransformation utilisée pour transformer les revendications après chaque authentification n’est pas activée par défaut. Si vous transformez les revendications avec une implémentation de IClaimsTransformation, appelez AddAuthentication pour ajouter des services d’authentification :

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();

L’hébergement in-process exécute une application ASP.NET Core dans le même processus que son processus de travail IIS. L’hébergement in-process offre de meilleures performances que l’hébergement out-of-process parce que les requêtes n’ont pas de proxy sur l’adaptateur de bouclage, interface réseau qui retourne du trafic réseau sortant à la même machine.

Le schéma suivant montre la relation entre IIS, le module ASP.NET Core et une application hébergée dans un processus :

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

Activer l’hébergement in-process

Depuis ASP.NET Core 3.0, l’hébergement in-process est activé par défaut pour toutes les applications déployées sur IIS.

Pour configurer explicitement une application pour l’hébergement in-process, définissez la valeur de la propriété <AspNetCoreHostingModel> sur InProcess dans le fichier projet (.csproj) :

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

Architecture générale

Le flux général d’une requête est le suivant :

  1. Une requête arrive du web au pilote HTTP.sys en mode noyau.
  2. Le pilote achemine la requête native vers IIS sur le port configuré du site web, généralement 80 (HTTP) ou 443 (HTTPS).
  3. Le module ASP.NET Core reçoit la requête native et la passe au serveur HTTP IIS (IISHttpServer). Le serveur HTTP IIS est une implémentation du serveur in-process pour IIS qui convertit la requête native en requête managée.

Une fois la requête traitée par le serveur HTTP IIS :

  1. La requête est envoyée au pipeline de middleware (intergiciel) ASP.NET Core.
  2. Le pipeline de middlewares traite la requête et la passe en tant qu’instance de HttpContext à la logique de l’application.
  3. La réponse de l’application est retransmise à IIS via le serveur HTTP IIS.
  4. IIS envoie la réponse au client qui a initié la demande.

CreateDefaultBuilder ajoute une instance de IServer en appelant la méthode UseIIS pour démarrer le CoreCLR et héberger l’application dans le processus de travail IIS (w3wp.exe ou iisexpress.exe). Les tests de performances indiquent que l’hébergement d’une application .NET Core in-process offre un débit de requêtes nettement plus élevé que l’hébergement de l’application hors processus et la proxysation des requêtes vers Kestrel.

Les applications publiées comme un fichier exécutable unique ne peuvent pas être chargées par le modèle d’hébergement in-process.

Configuration de l’application

Pour configurer les options IIS, incluez une configuration de service pour IISServerOptions dans ConfigureServices. L’exemple suivant désactive AutomaticAuthentication :

services.Configure<IISServerOptions>(options => 
{
    options.AutomaticAuthentication = false;
});
Option Default Paramètre
AutomaticAuthentication true Si true, IIS Server définit le HttpContext.User authentifié par Authentification Windows. Si false, le serveur fournit uniquement une identité pour HttpContext.User et répond aux questions explicitement posées par AuthenticationScheme. L’authentification Windows doit être activée dans IIS pour que AutomaticAuthentication fonctionne. Pour plus d'informations, consultez Authentification Windows.
AuthenticationDisplayName null Définit le nom d’affichage montré aux utilisateurs sur les pages de connexion.
AllowSynchronousIO false Indique si les E/S synchrones sont autorisées pour HttpContext.Request et HttpContext.Response.
MaxRequestBodySize 30000000 Récupère ou définit la taille maximale du corps de la demande de HttpRequest. Il est à noter que IIS a comme limite maxAllowedContentLength, qui doit être traité avant MaxRequestBodySize défini dans IISServerOptions. Les modifications de MaxRequestBodySize n’ont pas d’incidence sur maxAllowedContentLength. Pour augmenter maxAllowedContentLength, ajoutez une entrée dans web.config afin d’affecter à maxAllowedContentLength une valeur plus élevée. Pour plus d’informations, voir Configuration.

Différences entre l’hébergement in-process et out-of-process

Les caractéristiques suivantes s’appliquent lors de l’hébergement in-process :

  • Le serveur IIS HTTP (IISHttpServer) est utilisé à la place du serveur Kestrel. Pour in-process, CreateDefaultBuilder appelle UseIIS pour :

    • Enregistrer IISHttpServer.
    • Configurer le port et le chemin de base sur lesquels le serveur doit écouter lors de l’exécution derrière le module ASP.NET Core.
    • Configurer l’hôte pour capturer des erreurs de démarrage.
  • L’attribut requestTimeout ne s’applique pas à l’hébergement in-process.

  • Le partage d’un pool d’applications entre les applications n’est pas pris en charge. Utilisez un pool d’applications par application.

  • L’architecture (nombre de bits) de l’application et le runtime installé (x64 ou x86) doivent correspondre à l’architecture du pool d’applications. Par exemple, les applications publiées pour les architectures 32 bits (x86) doivent avoir l’architecture 32 bits activée pour leurs pools d’applications IIS. Pour plus d’informations, consultez la section Créer le site IIS.

  • Les déconnexions du client sont détectées. Le jeton d’annulation HttpContext.RequestAborted est annulé lors de la déconnexion du client.

  • Dans le cas d’un hébergement in-process, AuthenticateAsync n’est pas appelé en interne pour initialiser un utilisateur. Par conséquent, une implémentation de IClaimsTransformation utilisée pour transformer les revendications après chaque authentification n’est pas activée par défaut. Si vous transformez les revendications avec une implémentation de IClaimsTransformation, appelez AddAuthentication pour ajouter des services d’authentification :

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransient<IClaimsTransformation, ClaimsTransformer>();
        services.AddAuthentication(IISServerDefaults.AuthenticationScheme);
    }
    
    public void Configure(IApplicationBuilder app)
    {
        app.UseAuthentication();
    }
    
  • Les déploiements de package web (fichier unique) ne sont pas pris en charge.