ASP.NET Core での展開の要求

David Acker

要求展開ミドルウェア:

  • API エンドポイントが圧縮されたコンテンツを使用して要求を受け入れるようにします。
  • Content-Encoding HTTP ヘッダーを使用して、圧縮されたコンテンツを含む要求を自動的に識別し、展開します。
  • 圧縮された要求を処理するコードを記述する必要がなくなります。

要求の Content-Encoding ヘッダー値が使用可能な展開プロバイダーの 1 つと一致すると、ミドルウェアは次のようになります。

  • 一致するプロバイダーを使用して、HttpRequest.Body を適切な展開ストリームでラップします。
  • 要求本文が圧縮されなくなったことを示す Content-Encoding ヘッダーを削除します。

Content-Encoding ヘッダーを含まない要求は、要求展開ミドルウェアによって無視されます。

展開:

  • 要求の本文が読み取られるときに発生します。 つまり、展開は、モデル バインドのエンドポイントで行われます。 要求本文は頻繁に展開されません。
  • 指定された Content-Encoding に対して圧縮されたデータが無効な展開された要求本文を読み取ろうとすると、例外がスローされます。 Brotli では System.InvalidOperationException をスローすることができます: Decoder ran into invalid data. Deflate と GZip では System.IO.InvalidDataException をスローすることができます: The archive entry was compressed using an unsupported compression method.

ミドルウェアが圧縮されたコンテンツを含む要求を検出しても、その要求を展開できない場合、要求はパイプライン内の次のデリゲートに渡されます。 たとえば、サポートされていない Content-Encoding ヘッダー値または複数の Content-Encoding ヘッダー値を持つ要求は、パイプライン内の次のデリゲートに渡されます。

構成

次のコードは、AddRequestDecompression(IServiceCollection)UseRequestDecompression を使用して、既定のContent-Encoding 型の要求の展開を有効にします。

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRequestDecompression();

var app = builder.Build();

app.UseRequestDecompression();

app.MapPost("/", (HttpRequest request) => Results.Stream(request.Body));

app.Run();

既定の展開プロバイダー

要求展開ミドルウェアが既定でサポートする Content-Encoding ヘッダー値を次の表に示します。

Content-Encoding ヘッダー値 説明
br Brotli 圧縮データ形式
deflate DEFLATE 圧縮データ形式
gzip Gzip ファイル形式

カスタム展開プロバイダー

カスタム エンコードのサポートは、IDecompressionProvider を実装するカスタム展開プロバイダー クラスを作成することで追加できます。

public class CustomDecompressionProvider : IDecompressionProvider
{
    public Stream GetDecompressionStream(Stream stream)
    {
        // Perform custom decompression logic here
        return stream;
    }
}

カスタム展開プロバイダーは、対応する Content-Encoding ヘッダー値と共に RequestDecompressionOptions を使用して登録されます。

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRequestDecompression(options =>
{
    options.DecompressionProviders.Add("custom", new CustomDecompressionProvider());
});

var app = builder.Build();

app.UseRequestDecompression();

app.MapPost("/", (HttpRequest request) => Results.Stream(request.Body));

app.Run();

要求サイズの制限

zip 爆弾や展開爆弾から保護するために:

  • 展開された要求本文の最大サイズは、エンドポイントまたはサーバーによって適用される要求本文のサイズ制限に制限されます。
  • 展開された要求本文ストリームから読み取られたバイト数が上限を超えた場合は、ストリームから追加のバイトが読み取られるのを防ぐために InvalidOperationException がスローされます。

優先順位に従って、エンドポイントの最大要求サイズは次の方法で設定されます。

  1. IRequestSizeLimitMetadata.MaxRequestBodySize、MVC エンドポイントの RequestSizeLimitAttribute または DisableRequestSizeLimitAttribute など。
  2. グローバル サーバー サイズの制限 IHttpMaxRequestBodySizeFeature.MaxRequestBodySizeMaxRequestBodySize は要求ごとに IHttpMaxRequestBodySizeFeature.MaxRequestBodySize でオーバーライドできますが、既定では Web サーバーの実装用に構成された制限に設定されます。
Web サーバーにおける実装 MaxRequestBodySize 構成
HTTP.sys HttpSysOptions.MaxRequestBodySize
IIS IISServerOptions.MaxRequestBodySize
Kestrel KestrelServerLimits.MaxRequestBodySize

警告

要求本文のサイズ制限を無効にすると、特に要求本文がバッファー処理されている場合に、制御されていないリソース消費に関するセキュリティ リスクが生じます。 サービス拒否 (DoS) 攻撃のリスクを軽減するために、セーフガードが設定されていることを確認します。

その他のリソース