ぷろじぇくと、みすじら。

ASP.NET MVC Core 2.0のアプリケーション全体でHTTPSを強制する

Created at:

ASP.NET MVC Core 2.0のアプリケーションでHTTPSを強制するには、RequireHttpsフィルター(RequireHttpsAttributeクラス)をグローバルフィルターに追加することで実現できます。

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services
        .AddMvc(options =>
        {
            options.Filters.Add(new RequireHttpsAttribute());
        });
}

注意点として、RequireHttpsAttributeフィルターはOnAuthorizationメソッド、つまりフィルターパイプラインの一番最初である認可フェーズで処理されるので、ほかの認証/認可フィルターはこのフィルターより後に登録する必要があります。

MicrosoftのサイトにはRewriteエンジンを使う方法も書かれていますが、大抵のケースではフィルターで追加する方法で間に合うと思います。

MVCを使わないASP.NET Coreでもリダイレクトしたい

また、MVCではないASP.NET Coreで同じようなことをしたい場合には以下のようなMiddlewareを書くとよいでしょう(動作未確認)。

public static IApplicationBuilder UseRedirectToHttps(this IApplicationBuilder app)
{
    return app.Use((context, next) =>
    {
        var req = context.Request;
        if (!req.IsHttps)
        {
            var newUrl = new StringBuilder().Append("https://").Append(req.Host.Host).Append(req.PathBase).Append(req.Path).Append(req.QueryString);
            context.Response.Redirect(newUrl.ToString(), permanent: true);
            return Task.CompletedTask;
        }

        return next();
    });
}

IHostingEnvironmentをConfigureServiceで使いたい

ところでグローバルなフィルターを追加するのはいいのですが、環境によっては例えばデバッグ実行時や開発環境では追加したくないということもあります。

Configure メソッド内であれば env.IsProduction() といった感じで切り替えできるのですが、ConfigureService メソッドには IHostingEnvironment が渡ってこないのです。

ではどうするかというと Startup クラスにプロパティやフィールドをはやして、保持しておくという方法で解決できます。まあ Configuration も保持してますしね。

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
        .AddEnvironmentVariables();
    Configuration = builder.Build();
    HostingEnvironment = env;
}

public IHostingEnvironment HostingEnvironment { get; }

一度保持してしまえば ConfigureServices から参照可能になるので環境ごとに切り替えができます。

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services
        .AddMvc(options =>
        {
            if (HostingEnvironment.IsProduction())
            {
                options.Filters.Add(new RequireHttpsAttribute());
            }
        });
}