IIS と ASP.NET Core を使用したインプロセス ホスティング

インプロセス ホスティング モデルを使用する場合、ASP.NET Core アプリはその IIS ワーカー プロセスと同じプロセスで実行されます。 インプロセス ホスティングは、パフォーマンスの点でアウトプロセス ホスティングよりも優れています。要求がループバック アダプター (発信されたネットワーク トラフィックを同じコンピューターに送り返すネットワーク インターフェイス) を介してプロキシされることがないからです。

次の図は、IIS (ASP.NET Core モジュール) とインプロセスでホストされるアプリとの間のリレーションシップを示しています。

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

インプロセス ホスティングを有効にする

ASP.NET Core 3.0 以降、IIS に展開されるすべてのアプリに対してインプロセス ホスティングが既定では有効になっています。

インプロセス ホスティング用にアプリを明示的に構成するには、プロジェクト ファイル (.csproj) で、<AspNetCoreHostingModel> プロパティの値を InProcess に設定します。

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

全般的なアーキテクチャ

要求の一般的なフローは次のとおりです。

  1. Web からカーネル モードの HTTP.sys ドライバーに要求が届きます。
  2. このドライバーによって、Web サイトの構成ポート (通常は 80 (HTTP) または 443 (HTTPS)) 上で IIS へのネイティブ要求がルーティングされます。
  3. ASP.NET Core モジュールは、ネイティブ要求を受け取り、それを IIS HTTP サーバー (IISHttpServer) に渡します。 IIS HTTP サーバーは IIS 用のインプロセス サーバーの実装であり、要求がネイティブからマネージドに変換されます。

IIS HTTP サーバーによって要求が処理された後は、次のようになります。

  1. 要求は ASP.NET Core ミドルウェア パイプラインに送信されます。
  2. ミドルウェア パイプラインは要求を処理し、HttpContext インスタンスとしてアプリのロジックに渡します。
  3. アプリの応答は、IIS の HTTP サーバーを経由して IIS に戻されます。
  4. IIS は、要求を開始したクライアントに応答を送信します。

CreateDefaultBuilder では、UseIIS メソッドを呼び出し、CoreCLR を起動して IIS ワーカー プロセス (w3wp.exe または iisexpress.exe) 内のアプリをホストすることで、IServer インスタンスを追加します。 パフォーマンス テストは、.NET Core アプリのインプロセス ホスティングでは、アプリのアウトプロセス ホスティングや Kestrel へのプロキシ要求に比べ、スループットの要求が大幅に高くなることを示しています。

単一ファイルの実行可能ファイルとして公開されたアプリは、インプロセス ホスティング モデルで読み込むことができません。

アプリケーションの構成

IIS オプションを構成するには、IISServerOptions 用のサービス構成を Program.cs に含めます。 次の例では 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();
オプション Default 設定
AutomaticAuthentication true true の場合、IIS サーバーが Windows 認証によって認証された HttpContext.User を設定します。 false の場合、サーバーは HttpContext.User の ID を提供するだけで、AuthenticationScheme によって明示的に要求されたときにチャレンジに応答します。 AutomaticAuthentication を機能させるためには、IIS で Windows 認証を有効にする必要があります。 詳細については、Windows 認証に関する記事を参照してください。
AuthenticationDisplayName null ログイン ページでユーザーに表示名が表示されるように設定します。
AllowSynchronousIO false HttpContext.Request および HttpContext.Response に対して同期 I/O が許可されるか。
MaxRequestBodySize 30000000 HttpRequest の最大要求本文サイズを取得または設定します。 IIS 自体に、IISServerOptions に設定された MaxRequestBodySize の前に処理される上限 maxAllowedContentLength があることに注意してください。 MaxRequestBodySize を変更しても、maxAllowedContentLength に影響はありません。 maxAllowedContentLengthを引き上げるには、web.config 内にエントリを追加して maxAllowedContentLength をより高い値に設定します。 詳細については、「Configuration (構成)」を参照してください。

インプロセスおよびアウトプロセス ホスティングの相違点

インプロセスでホストする場合は、次の特性が適用されます。

  • Kestrel サーバーの代わりに、IIS HTTP サーバー (IISHttpServer) が使用されます。 インプロセスの場合は、CreateDefaultBuilder によって UseIIS が呼び出され、次のことが行われます。

    • IISHttpServer を登録します。
    • ASP.NET Core モジュールの背後で実行するときにサーバーがリッスンする、ポートとベース パスを構成します。
    • スタートアップ エラーをキャプチャするホストを構成します。
  • requestTimeout 属性 は、インプロセス ホスティングには適用されません。

  • アプリ プールをアプリ間で共有することはサポートされていません。 アプリごとに 1 つのアプリ プールを使用します。

  • アプリとインストールされているランタイム (x64 または x86) のアーキテクチャ (ビット) は、アプリ プールのアーキテクチャと一致する必要があります。 たとえば、32 ビット (x86) 用に公開されたアプリの場合、IIS アプリケーション プールで 32 ビットが有効になっている必要があります。 詳細については、「IIS サイトを作成する」セクションを参照してください。

  • クライアントの切断が検出されます。 クライアントが切断されると、HttpContext.RequestAborted キャンセル トークンが取り消されます。

  • インプロセス ホスティングの場合、ユーザーを初期化するために内部で AuthenticateAsync が呼び出されることはありません。 そのため、認証のたびに要求を変換するための IClaimsTransformation 実装は既定で有効になっていません。 IClaimsTransformation 実装で要求を返還するとき、AddAuthentication を呼び出し、認証サービスを追加します。

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

タイミング情報を取得する

IHttpSysRequestTimingFeature を使用して詳細なタイミング情報を取得する」を参照してください。

インプロセス ホスティング モデルを使用する場合、ASP.NET Core アプリはその IIS ワーカー プロセスと同じプロセスで実行されます。 インプロセス ホスティングは、パフォーマンスの点でアウトプロセス ホスティングよりも優れています。要求がループバック アダプター (発信されたネットワーク トラフィックを同じコンピューターに送り返すネットワーク インターフェイス) を介してプロキシされることがないからです。

次の図は、IIS (ASP.NET Core モジュール) とインプロセスでホストされるアプリとの間のリレーションシップを示しています。

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

インプロセス ホスティングを有効にする

ASP.NET Core 3.0 以降、IIS に展開されるすべてのアプリに対してインプロセス ホスティングが既定では有効になっています。

インプロセス ホスティング用にアプリを明示的に構成するには、プロジェクト ファイル (.csproj) で、<AspNetCoreHostingModel> プロパティの値を InProcess に設定します。

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

全般的なアーキテクチャ

要求の一般的なフローは次のとおりです。

  1. Web からカーネル モードの HTTP.sys ドライバーに要求が届きます。
  2. このドライバーによって、Web サイトの構成ポート (通常は 80 (HTTP) または 443 (HTTPS)) 上で IIS へのネイティブ要求がルーティングされます。
  3. ASP.NET Core モジュールは、ネイティブ要求を受け取り、それを IIS HTTP サーバー (IISHttpServer) に渡します。 IIS HTTP サーバーは IIS 用のインプロセス サーバーの実装であり、要求がネイティブからマネージドに変換されます。

IIS HTTP サーバーによって要求が処理された後は、次のようになります。

  1. 要求は ASP.NET Core ミドルウェア パイプラインに送信されます。
  2. ミドルウェア パイプラインは要求を処理し、HttpContext インスタンスとしてアプリのロジックに渡します。
  3. アプリの応答は、IIS の HTTP サーバーを経由して IIS に戻されます。
  4. IIS は、要求を開始したクライアントに応答を送信します。

CreateDefaultBuilder では、UseIIS メソッドを呼び出し、CoreCLR を起動して IIS ワーカー プロセス (w3wp.exe または iisexpress.exe) 内のアプリをホストすることで、IServer インスタンスを追加します。 パフォーマンス テストは、.NET Core アプリのインプロセス ホスティングでは、アプリのアウトプロセス ホスティングや Kestrel へのプロキシ要求に比べ、スループットの要求が大幅に高くなることを示しています。

単一ファイルの実行可能ファイルとして公開されたアプリは、インプロセス ホスティング モデルで読み込むことができません。

アプリケーションの構成

IIS オプションを構成するには、IISServerOptions 用のサービス構成を ConfigureServices に含めます。 次の例では、AutomaticAuthentication が無効になります。

services.Configure<IISServerOptions>(options => 
{
    options.AutomaticAuthentication = false;
});
オプション Default 設定
AutomaticAuthentication true true の場合、IIS サーバーが Windows 認証によって認証された HttpContext.User を設定します。 false の場合、サーバーは HttpContext.User の ID を提供するだけで、AuthenticationScheme によって明示的に要求されたときにチャレンジに応答します。 AutomaticAuthentication を機能させるためには、IIS で Windows 認証を有効にする必要があります。 詳細については、Windows 認証に関する記事を参照してください。
AuthenticationDisplayName null ログイン ページでユーザーに表示名が表示されるように設定します。
AllowSynchronousIO false HttpContext.Request および HttpContext.Response に対して同期 I/O が許可されるか。
MaxRequestBodySize 30000000 HttpRequest の最大要求本文サイズを取得または設定します。 IIS 自体に、IISServerOptions に設定された MaxRequestBodySize の前に処理される上限 maxAllowedContentLength があることに注意してください。 MaxRequestBodySize を変更しても、maxAllowedContentLength に影響はありません。 maxAllowedContentLengthを引き上げるには、web.config 内にエントリを追加して maxAllowedContentLength をより高い値に設定します。 詳細については、「Configuration (構成)」を参照してください。

インプロセスおよびアウトプロセス ホスティングの相違点

インプロセスでホストする場合は、次の特性が適用されます。

  • Kestrel サーバーの代わりに、IIS HTTP サーバー (IISHttpServer) が使用されます。 インプロセスの場合は、CreateDefaultBuilder によって UseIIS が呼び出され、次のことが行われます。

    • IISHttpServer を登録します。
    • ASP.NET Core モジュールの背後で実行するときにサーバーがリッスンする、ポートとベース パスを構成します。
    • スタートアップ エラーをキャプチャするホストを構成します。
  • requestTimeout 属性 は、インプロセス ホスティングには適用されません。

  • アプリ プールをアプリ間で共有することはサポートされていません。 アプリごとに 1 つのアプリ プールを使用します。

  • アプリとインストールされているランタイム (x64 または x86) のアーキテクチャ (ビット) は、アプリ プールのアーキテクチャと一致する必要があります。 たとえば、32 ビット (x86) 用に公開されたアプリの場合、IIS アプリケーション プールで 32 ビットが有効になっている必要があります。 詳細については、「IIS サイトを作成する」セクションを参照してください。

  • クライアントの切断が検出されます。 クライアントが切断されると、HttpContext.RequestAborted キャンセル トークンが取り消されます。

  • インプロセス ホスティングの場合、ユーザーを初期化するために内部で AuthenticateAsync が呼び出されることはありません。 そのため、認証のたびに要求を変換するための IClaimsTransformation 実装は既定で有効になっていません。 IClaimsTransformation 実装で要求を返還するとき、AddAuthentication を呼び出し、認証サービスを追加します。

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransient<IClaimsTransformation, ClaimsTransformer>();
        services.AddAuthentication(IISServerDefaults.AuthenticationScheme);
    }
    
    public void Configure(IApplicationBuilder app)
    {
        app.UseAuthentication();
    }
    
  • Web パッケージ (単一ファイル) の配置はサポートされていません。