web-dev-qa-db-ja.com

ミドルウェアを使用してサーバーヘッダーを削除する方法は?

ASP.NET Core 1.0では、すべての応答にヘッダーServer: Kestrelが含まれます。ミドルウェアを使用して、このヘッダーをX-Power-Byなどの他のヘッダーと一緒に削除したいと思います。

次のように設定することで、ホスト構成のKestrelヘッダーを削除できることはわかっていますが、ミドルウェアを使用して削除したいと思います(実際、Httpmoduleがある場合は、このように実行できるので、同じことを学んでいます)。私はそれがうまくいかなかった私のビットを試しました。

new WebHostBuilder()
    .UseKestrel(c => c.AddServerHeader = false)

試したコード:

public class HeaderRemoverMiddleware
{
    private readonly RequestDelegate _next;
    public HeaderRemoverMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        httpContext.Response.OnStarting(callback: removeHeaders, state: httpContext);
        await _next.Invoke(httpContext);
    }

    private Task removeHeaders(object context)
    {
        var httpContext = (HttpContext)context;
        if (httpContext.Response.Headers.ContainsKey("Server"))
        {
            httpContext.Response.Headers.Remove("Server");
        }
        return Task.FromResult(0);
    }
}

public static class HeaderRemoverExtensions
{
    public static IApplicationBuilder UseServerHeaderRemover(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<HeaderRemoverMiddleware>();
    }
}
14
dotnetstep

このコードがKestrel1.0.0の時点で機能していることを確認しました。

.UseKestrel(opt => opt.AddServerHeader = false)

これにより、応答からServer: Kestrelヘッダーが削除されます。


応答から他の任意のヘッダーを削除したい場合は、コードのバリエーションが機能します。これは機能しませんServer: Kestrelヘッダーに対して機能します。これは、KestrelがOnSendingデリゲートの実行後にこれを追加するように見えるためです。

渡したヘッダーをすべて削除するミドルウェアのサンプルを次に示します。

public class HeaderRemoverMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ImmutableList<string> _headersToRemove;

    public HeaderRemoverMiddleware(RequestDelegate next, ImmutableList<string> headersToRemove)
    {
        _next = next;
        _headersToRemove = headersToRemove;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        httpContext.Response.OnStarting(() =>
        {
            _headersToRemove.ForEach(header =>
            {
                if (httpContext.Response.Headers.ContainsKey(header))
                {
                    httpContext.Response.Headers.Remove(header);
                }
            });

            return Task.FromResult(0);
        });

        await _next.Invoke(httpContext);
    }
}

public static class HeaderRemoverExtensions
{
    public static IApplicationBuilder UseHeaderRemover(this IApplicationBuilder builder, params string[] headersToRemove)
    {
        return builder.UseMiddleware<HeaderRemoverMiddleware>(headersToRemove.ToImmutableList());
    }
}

これを使用するには、アプリケーションパイプラインの最上部に追加します。

app.UseHeaderRemover("Content-Type", "AnotherHeader");
20
Nate Barbettini