web-dev-qa-db-ja.com

.net Core X Forwarded Protoが機能しない

ロードバランサーの背後で.net core 1.1アプリケーションを動作させ、httpsを強制するように取り組んでいます。 Startup.csに次の設定があります

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider serviceProvider, IOptions<Auth0Settings> auth0Settings)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();


    var startupLogger = loggerFactory.CreateLogger<Startup>();


    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
        app.UseBrowserLink();
        startupLogger.LogInformation("In Development");
    }
    else
    {
        startupLogger.LogInformation("NOT in development");
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseMiddleware<HttpsRedirectMiddleware>();
    app.UseForwardedHeaders(new ForwardedHeadersOptions
    {
        ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
    });`
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationScheme= CookieAuthenticationDefaults.AuthenticationScheme,
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
            CookieHttpOnly = true,
            SlidingExpiration = true
        });

HttpsRedirectMiddlewareは、LBにX-Forwarded-Protoが設定されていることを検証するためのものであり、設定され、唯一の値としてhttpsとして返されます。サイト( https://myapp.somedomain.net )にアクセスすると、認証されていないことがわかり、( http://myapp.somedomain.net/アカウント/ログオン?ReturnUrl =%2f )。 SSL接続が失われ、ポート80に切り替えられました。 .netコアのドキュメントでは、以下のように「UseForwardedHeaders」を使用するように言われていますが、私の場合は機能しません。この切り替えが発生しても、コンソールロガーにはミドルウェアからのエラーや警告はありません。

短期間の修正として、これを「UseForwardedHeaders」の下に配置しました

    app.Use(async (context, next) =>
    {
        var xproto = context.Request.Headers["X-Forwarded-Proto"].ToString();
        if (xproto!=null && xproto.StartsWith("https", StringComparison.OrdinalIgnoreCase)){
            startupLogger.LogInformation("Switched to https");
            context.Request.Scheme = "https";
        }
        await next();

    });

上記は完璧に動作しますが、ハックです。正しい方法でやりたいです。

19
Josh

.net Coreには、転送されるヘッダーのデフォルトセットがあります。 IIS統合の場合、デフォルトは127.0.0.1です。ソースコードを追跡した後、既知のネットワークと既知のプロキシをクリアして、転送されたリクエストを受け入れることができます。ファイアウォールを設定するか、既知のネットワークをプライベートサブネットにロックします。

    var forwardingOptions = new ForwardedHeadersOptions()
    {
        ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
    };
    forwardingOptions.KnownNetworks.Clear(); //Loopback by default, this should be temporary
    forwardingOptions.KnownProxies.Clear(); //Update to include
    app.UseForwardedHeaders(forwardingOptions);

dotnet net core 2.xのアップデート。問題をデバッグした後、プロキシ/ロードバランサーまたはプライベートネットワークのIPを設定します。これにより、プロキシ/ロードバランサーをバイパスして、転送されたヘッダーを偽造するのを防ぎます。

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardLimit = 2;
    options.KnownProxies.Add(IPAddress.Parse("192.168.1.5")); //Replace with IP of your proxy/load balancer
    options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("192.168.1.0"),24));;
}) //192.168.1.0/24 allows any from 192.168.1.1-254;

https://docs.Microsoft.com/en-us/aspnet/core/Host-and-deploy/proxy-load-balancer?view=aspnetcore-2.2#forwarded-headers-middleware-options

41
Josh

ロードバランサーを使用している場合、通常、ロードバランスでSSL接続を終了し、HTTP経由でアプリケーションにリクエストを送信します。

これでうまくいきました。 AWSロードバランサーでSSL終了を使用しています。

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedProto
});

これにより、X-Forwarded-ProtoヘッダーでRequest.Schemeが更新され、すべてのリダイレクトリンクの生成で正しいスキームが使用されるようになります。

X-Forwarded-Proto:元のクライアントとプロキシからのスキーム。

0
Sunil Buddala