web-dev-qa-db-ja.com

HTTPSへのリダイレクト

安全ではないすべての着信要求をHTTPSにリダイレクトする推奨方法は何ですか。ミドルウェアコンポーネントを作成する必要がありますか?その場合、サーバー名を取得する方法がわかりませんでした。

public class RedirectHttpMiddleware
{
    RequestDelegate _next;

    public RedirectHttpMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.IsSecure)
            await _next(context);
        else
        {
            var server = "";  // How do I get the server name?
            context.Response.Redirect("https://" + server + context.Request.Path);
        }
    }
}
35
William

独自のミドルウェアクラスを使用できますが、通常、スタートアップ構成で次のようなことを行います。

app.Use(async (context, next) =>
{
    if (context.Request.IsHttps)
    {
        await next();
    }
    else
    {
        var withHttps = Uri.UriSchemeHttps + Uri.SchemeDelimiter + context.Request.Uri.GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Scheme, UriFormat.SafeUnescaped);
        context.Response.Redirect(withHttps);
    }
});

これはURL全体、クエリ文字列、およびすべてを取得し、GetComponentsを使用してすべてを取得します除く URLのスキーム。次に、HTTPSスキームがコンポーネントURLの先頭に追加されます。

これは完全な.NET Frameworkで動作します。ASP.NETCoreの場合、次のようなことができます。

app.Use(async (context, next) =>
{
    if (context.Request.IsHttps)
    {
        await next();
    }
    else
    {
        var withHttps = "https://" + context.Request.Host + context.Request.Path;
        context.Response.Redirect(withHttps);
    }
});

これにより、ホストとHTTPSスキームへのパスが追加されます。クエリやハッシュなどの他のコンポーネントを追加することもできます。

43
vcsjones

.NET Core 2.0以前の場合( 2.0の公式ドキュメント ):

[RequireHttps]属性/フィルターを使用します。コントローラーに対してこれを行うことができます。

[RequireHttps]
public class AccountController {
}

または、ConfigureServicesメソッドのStartup.csにこれを追加します。

services.Configure<MvcOptions>(options =>
{
    options.Filters.Add(new RequireHttpsAttribute());
}

また、vcsjonesの答えも正しいことを追加したかっただけですが、リダイレクトを引き起こす他のミドルウェア/コードの前に、設定の早い段階でこのコードを追加する必要があります。私の場合、Identity Frameworkミドルウェアを追加する直前に追加しました。

16
Josh Mouch

完全な答えは番号1にありますが、HTTPSのセットアップを停止しないで、追加のステップに進んでください。

1-RequireHttpsAttributeを使用してHTTPSにリダイレクトし、MVCオプションでSSLポートを設定します。 launchSettings.jsonからSSLポートも読み取りますが、これは開発モードでのみ必要です。

2-AddAntiforgeryを使用して、偽造防止トークンでHTTPSを要求します。

3-NWebsec.AspNetCore.Middleware NuGetパッケージとUseHstsメソッドを使用して、サイト全体で厳格なトランスポートセキュリティ(HSTS)を有効にします。下にプリロードを追加して、サイトを HSTSプリロードサイト に送信することを忘れないでください。詳細情報 here および here

4-NWebsec.AspNetCore.Middleware NuGetパッケージとUseHpkpメソッドを使用して、サイト全体で公開キー固定(HPKP)を有効にします。これを間違えた場合、基本的にサイトをDoSしていることに注意してください。詳細情報 here および here

5-使用するURLにhttpsスキームを含めます。 コンテンツセキュリティポリシー(CSP) HTTPヘッダーおよび サブリソースの整合性(SRI) 一部のブラウザーでスキームを模倣すると、ニースが再生されません。 HTTPSについて明示することをお勧めします。例えば.

<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.4/bootstrap.min.js"></script>

6- ASP.NET MVC Boilerplate Visual Studioプロジェクトテンプレートを使用して、これらすべてとさらに多くの組み込みのプロジェクトを生成します。 GitHub でコードを表示することもできます。

上記のすべての後、Startupクラスは次のようになります。

public class Startup
{
    private readonly int? sslPort;

    public Startup(IHostingEnvironment hostingEnvironment)
    {
        if (hostingEnvironment.IsDevelopment())
        {
            var launchConfiguration = new ConfigurationBuilder()
                .SetBasePath(hostingEnvironment.ContentRootPath)
                .AddJsonFile(@"Properties\launchSettings.json")
                .Build();
            // During development we won't be using port 443.
            this.sslPort = launchConfiguration.GetValue<int>("iisSettings:iisExpress:sslPort");
        }
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddAntiforgery(options =>
            {
                options.RequireSsl = true;
            });
            .AddMvc(options =>
            {
                options.Filters.Add(new RequireHttpsAttribute());
                options.SslPort = sslPort;
            });
    }

    public void Configure(IApplicationBuilder application)
    {
        application
            .UseHsts(options => options.MaxAge(days: 18 * 7).IncludeSubdomains().Preload())
            .UseHpkp(options => options
                .Sha256Pins(
                    "Base64 encoded SHA-256 hash of your first certificate e.g. cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs=",
                    "Base64 encoded SHA-256 hash of your second backup certificate e.g. M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE=")
                .MaxAge(days: 18 * 7)
                .IncludeSubdomains())
            .UseCsp(options => options
                .UpgradeInsecureRequests(this.sslPort.HasValue ? this.sslPort.Value : 443))
            .UseMvc();
    }
}
12

.NET CoreのDEV環境でポートを取得する場合は、env.IsDevelopment()を見て、条件付きでSSLポートをlaunchSettings.json

if (env.IsDevelopment())
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile(@"Properties/launchSettings.json", optional: false, reloadOnChange: true);
    var launchConfig = builder.Build();
    sslPort = launchConfig.GetValue<int>("iisSettings:iisExpress:sslPort");
}

`

SSLポートを取得したら、@ vcsjonesが投稿したソリューションにポートを組み込むことができます。

3
long2know

開発環境でカスタムポートを使用するように、@ vcsjonesの回答を少し変更しました。 @ long2knowにもクレジットされています。

_app.Use(async (context, next) =>
{
    var request = context.Request;

    if (request.IsHttps)
    {
        await next();
    }
    else
    {
        var devPort = Configuration.GetValue<int>("iisSettings:iisExpress:sslPort");

        var Host = env.IsDevelopment() && devPort > 0
            ? new HostString(request.Host.Host, devPort)
            : new HostString(request.Host.Host);

        string newUrl = $"https://{Host}{request.PathBase}{request.Path}{request.QueryString}";
        context.Response.Redirect(newUrl, true);
    }
});
_

これはapp.UseStaticFilesまたはapp.UseMvcの前に表示する必要があります。それ以外の場合は無視されます。

ポートは_launchSettings.json_ファイルから取得する必要があるため、このファイルを_Startup.cs_のConfigurationBuilderに追加する必要があることに注意してください。

.AddJsonFile(@"Properties/launchSettings.json", optional: false, reloadOnChange: true)

2

AlwaysHttpsMiddleware.cs、 RequiresHttpsAttributeに触発された

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

public class AlwaysHttpsMiddleware
{
    private readonly RequestDelegate _next;

    public AlwaysHttpsMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.IsHttps)
        {
            await _next.Invoke(context);
        }
        else
        {
            var request = context.Request;

            // only redirect for GET requests, otherwise the browser might
            // not propagate the verb and request body correctly.

            if (!string.Equals(request.Method, "GET", StringComparison.OrdinalIgnoreCase))
            {
                context.Response.StatusCode = StatusCodes.Status403Forbidden;
                await context.Response.WriteAsync("This site requires HTTPS.");
            }
            else
            {
                var newUrl = string.Concat(
                    "https://",
                    request.Host.ToUriComponent(),
                    request.PathBase.ToUriComponent(),
                    request.Path.ToUriComponent(),
                    request.QueryString.ToUriComponent());

                context.Response.Redirect(newUrl);
            }
        }
    }
}

Startup.cs

public void Configure(IApplicationBuilder app)
{
    if (_env.IsProduction())
    {
        app.UseMiddleware<AlwaysHttpsMiddleware>();
    }
 }
2
Shaun Luttin

ASP.NET Core 2.1では、これを使用するだけです:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();   // <-- Add this !!!!!
    }

    app.UseHttpsRedirection(); // <-- Add this !!!!!
    app.UseStaticFiles();
    app.UseCookiePolicy();

    app.UseMvc();
}
1
Yanga

DOTNet CoreアプリケーションをHTTPSで実行するには、次の3つの手順を実行します。

  1. アプリケーションのlaunchSettings.jsonファイルに移動し、希望するhttpsポートを44390-44399から入力します enter image description here
  2. Startup.csファイルを編集します。次のコードを入力してください。

    services.Configure<MvcOptions>(options =>
    {
        options.SslPort = 44390;
        options.Filters.Add(new RequireHttpsAttribute());
    });
    

    enter image description here

  3. ソリューションエクスプローラーからプロジェクトルートディレクトリを右クリックし、[プロパティ]を選択します。 [SSLを有効にする]をオンにし、SSLリンクをコピーして、アプリURL領域に追加します。 enter image description here

    1. アプリケーションを起動します。常にHTTPSコンテキストで実行されます。
0
Johnny

ここにはいくつかの素晴らしい答えがありますが、IISの有無に関係なく、ローカルデバッグ中にプロトコルを変更しないソリューションが必要でした。ADauthをパイプラインに追加した直後Startup.Configureメソッドこれは完全なフレームワーク用ですここでの他のソリューションは、CoreのURLを再構築する方法を概説しています。

app.Use(async (context, next) =>
{
    if (context.Request.IsHttps || // Handles https straight to the server 
        context.Request.Headers["X-Forwarded-Proto"] == Uri.UriSchemeHttps || // Handles an IIS or Azure passthrough
        context.Request.Host.ToString().StartsWith("localhost",true, System.Globalization.CultureInfo.InvariantCulture) || // Ignore for localhost
        context.Request.Headers["X-Forwarded-Proto"].Contains( Uri.UriSchemeHttps )) // X-Forwarded-Proto can have multiple values if there are multiple proxies 
    {
        await next();
    }
    else
    {
        var withHttps = Uri.UriSchemeHttps + Uri.SchemeDelimiter + context.Request.Host + context.Request.Path + context.Request.QueryString;
        context.Response.Redirect(withHttps);
    }
});
0
EricksonG

https://github.com/aspnet/KestrelHttpServer/issues/916 で説明されている1つの手法は、これをweb.configに追加することです。

<rewrite>
      <rules>
          <rule name="HTTP/S to HTTPS Redirect" enabled="true" stopProcessing="true">
          <match url="(.*)" />
          <conditions logicalGrouping="MatchAny">
              <add input="{SERVER_PORT_SECURE}" pattern="^0$" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_Host}/{R:1}" redirectType="Permanent" />
          </rule>
      </rules>
</rewrite>
0
SaltySub2