asp.netでサイト全体にhttpsを強制する最良の方法は?


192

約6か月前に、すべてのリクエストをhttps経由にする必要があるサイトを公開しました。ページへのすべてのリクエストがhttps経由であることを確認できる唯一の方法は、ページ読み込みイベントでそれをチェックすることでした。リクエストがhttp経由でない場合、response.redirect( " https://example.com ")

より良い方法はありますか?理想的には、web.configのいくつかの設定ですか?


ここで私の答えを確認してください。stackoverflow.com
questions / 33882350 /

回答:


250

HSTS(HTTP Strict Transport Security)を使用してください

http://www.hanselman.com/blog/HowToEnableHTTPStrictTransportSecurityHSTSInIIS7.aspxから

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="HTTP to HTTPS redirect" stopProcessing="true">
                    <match url="(.*)" />
                    <conditions>
                        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}/{R:1}"
                        redirectType="Permanent" />
                </rule>
            </rules>
            <outboundRules>
                <rule name="Add Strict-Transport-Security when HTTPS" enabled="true">
                    <match serverVariable="RESPONSE_Strict_Transport_Security"
                        pattern=".*" />
                    <conditions>
                        <add input="{HTTPS}" pattern="on" ignoreCase="true" />
                    </conditions>
                    <action type="Rewrite" value="max-age=31536000" />
                </rule>
            </outboundRules>
        </rewrite>
    </system.webServer>
</configuration>

元の回答(2015年12月4日に上記に置き換え)

基本的に

protected void Application_BeginRequest(Object sender, EventArgs e)
{
   if (HttpContext.Current.Request.IsSecureConnection.Equals(false) && HttpContext.Current.Request.IsLocal.Equals(false))
   {
    Response.Redirect("https://" + Request.ServerVariables["HTTP_HOST"]
+   HttpContext.Current.Request.RawUrl);
   }
}

それはglobal.asax.cs(またはglobal.asax.vb)に入ります

私はそれをweb.configで指定する方法を知りません


7
これは機能しますが、私にとっては危険でした。VS2010でこのコードを実行しながらローカルで実行しようとすると、スタートページが読み込まれませんでした。代わりに、「このWebページは利用できません」というメッセージが表示されました。修正するために、URLに文字列「localhost」が含まれているかどうかをテストする2番目の条件を追加しました。含まれていない場合は、httpsを強制します。
mg1075 2011

3
これは私にリダイレクトループを与えています。コードを追加する前は、問題なく動作しました。助言がありますか?
ジョー

9
これは、いかなる有用なセキュリティも提供しないことに注意してください。実際には、すでに安全なユーザーからの接続のみが保護され、攻撃されているユーザーの接続は保護されません(これは、MITMがリダイレクトを完全に省略して、すべてを「安全な」サイトに転送できるためです)。私見、ユーザーエージェントをリダイレクトすることは、気分が良いブードゥーセキュリティであり、時には危険な安全の幻想を提供します。移動する唯一の方法は、ユーザーエージェントに安全なリソースのみを要求し、そうでない場合はリダイレクトしないように指示することです。これがHSTSの機能です。以下の回答を参照してください。
2014年

2
この回答は「有害」であると見なされ、使用されるべきではありません。上記の@tneによるコメントの通り。
Rosdi Kasim 2015

2
@RosdiKasimこの回答は、2015年12月4日の編集以降、依然として有害と見なされますか
アンドリューモートン

123

他にできることは、 "Strict-Transport-Security"ヘッダーをブラウザーに返すことによってHSTSを使用することです。ブラウザーはこれをサポートする必要があります(現在のところ、サポートしているのは主にChromeとFirefoxです)。ただし、一度設定すると、ブラウザーはHTTP経由でサイトにリクエストを送信せず、HTTPSリクエストに変換してから発行します。 。これをHTTPからのリダイレクトと組み合わせて試してください。

protected void Application_BeginRequest(Object sender, EventArgs e)
{
  switch (Request.Url.Scheme)
  {
    case "https":
      Response.AddHeader("Strict-Transport-Security", "max-age=300");
      break;
    case "http":
      var path = "https://" + Request.Url.Host + Request.Url.PathAndQuery;
      Response.Status = "301 Moved Permanently";
      Response.AddHeader("Location", path);
      break;
  }
}

HSTSに対応していないブラウザーはヘッダーを無視するだけですが、それでもスイッチステートメントによってキャッチされ、HTTPSに送信されます。


6
これまでにHSTSヘッダーについて聞いたことはありませんが、見た目はとてもかっこいいです。このような小さいmax-age値(5分)を使用する理由はありますか?リンク先のウィキペディアの記事では、大きな値(6〜12か月)に設定することを推奨しています。
dana 2013

5
+1。Troyのブログにあるこの非常に広範な記事をチェックしてください。リダイレクトを使用するだけでセキュリティが低下する理由の詳細が含まれています。ヒント:特に、SSL Stripツールに対して脆弱なままになる可能性があります。 troyhunt.com/2011/11/…–
オランデニソン

3
また、NWebsecをチェックする価値があります。これにより、これ(およびそれ以上)が非常に簡単になります。
Tieson T. 2014

16
スイッチをラップして、if(!Request.IsLocal)デバッグが中断しないようにする必要があります。
ジャスティンJスターク

1
いい答えだ。微妙な点-Httpヘッダー( "Strict-Transport-Security")の場合、NWebSecのようなライブラリを使用することをお勧めします。複数のオプションが、あちこちに広がるのではなく、構成の1つの場所に集中しているためです。
Ognyan Dimitrov 2014

89

IIS7モジュールを使用すると、リダイレクトできます。

    <rewrite>
        <rules>
            <rule name="Redirect HTTP to HTTPS" stopProcessing="true">
                <match url="(.*)"/>
                <conditions>
                    <add input="{HTTPS}" pattern="^OFF$"/>
                </conditions>
                <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="SeeOther"/>
            </rule>
        </rules>
    </rewrite>

12
また、IIS 7.0の場合、URL書き換えモジュール2.0をインストールする必要があります
Chris

特定のページでhttpsリクエストのみを受け入れるようにするには、このリンクがシンプルで役立つことがわかりました-support.microsoft.com/kb/239875
Manik Arora

21

ASP.NET MVCを使用しているユーザー向け。以下を使用して、2つの方法でサイト全体にSSL / TLS over HTTPSを強制できます。

ハードウェイ

1-RequireHttpsAttributeをグローバルフィルターに追加します。

GlobalFilters.Filters.Add(new RequireHttpsAttribute());

2-偽造防止トークンにSSL / TLSの使用を強制する:

AntiForgeryConfig.RequireSsl = true;

3-Web.configファイルを変更して、デフォルトでHTTPSを要求するようCookieに要求する:

<system.web>
    <httpCookies httpOnlyCookies="true" requireSSL="true" />
</system.web>

4-NWebSec.Owin NuGetパッケージを使用し、次のコード行を追加して、サイト全体でStrict Transport Securityを有効にします。以下にPreloadディレクティブを追加して、サイトをHSTS Preloadサイトに送信することを忘れないでください。詳細はこちらこちら。OWINを使用していない場合は、NWebSecサイトでWeb.configメソッドを読むことができます。

// app is your OWIN IAppBuilder app in Startup.cs
app.UseHsts(options => options.MaxAge(days: 30).Preload());

5-NWebSec.Owin NuGetパッケージを使用し、次のコード行を追加して、サイト全体で公開キー固定(HPKP)を有効にします。詳細はこちらこちら

// app is your OWIN IAppBuilder app in Startup.cs
app.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: 30));

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

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

簡単な方法

使用するASP.NET MVC定型で、このすべてとはるかに内蔵したプロジェクトを生成するためのVisual Studioプロジェクトテンプレートを。また、上のコードを表示することができますGitHubの


3
また、を使用する場合<authentication mode="Forms">、内部にある必要があります<forms requireSSL="true">
Pluto

1
@ muhammad-rehan-saeed mvc5ボイラープレートを使用していますが、サイトは本番サーバーでhttpをhttpsに自動的にリダイレクトしないため、localhostでのみ、何かが欠けていますか?
Diin 2015

これは、この質問をするのに適切なフォーラムではありません。GitHubサイトに問題を投稿します。RequireHttpsAttributeリダイレクトを行います。あなたが持っている限り、それは問題ないはずです。
ムハンマドレーハンサイード2015

@MuhammadRehanSaeed、あなたの答えが大好きです。しかし... MakeCertで作成された証明書のSHA256ハッシュを取得するにはどうすればよいですか?私が持っているのはSHA-1サムプリントだけです...たまたま知っていますか?
ダイアナ

1
@Diana このリンクは、その方法を示しています。
ムハンマドレーハンサイード2017

13

何らかの理由でIISでこれを設定できない場合は、リダイレクトを行うHTTPモジュールを作成します。

using System;
using System.Web;

namespace HttpsOnly
{
    /// <summary>
    /// Redirects the Request to HTTPS if it comes in on an insecure channel.
    /// </summary>
    public class HttpsOnlyModule : IHttpModule
    {
        public void Init(HttpApplication app)
        {
            // Note we cannot trust IsSecureConnection when 
            // in a webfarm, because usually only the load balancer 
            // will come in on a secure port the request will be then 
            // internally redirected to local machine on a specified port.

            // Move this to a config file, if your behind a farm, 
            // set this to the local port used internally.
            int specialPort = 443;

            if (!app.Context.Request.IsSecureConnection 
               || app.Context.Request.Url.Port != specialPort)
            {
               app.Context.Response.Redirect("https://" 
                  + app.Context.Request.ServerVariables["HTTP_HOST"] 
                  + app.Context.Request.RawUrl);    
            }
        }

        public void Dispose()
        {
            // Needed for IHttpModule
        }
    }
}

次に、それをDLLにコンパイルし、プロジェクトへの参照として追加して、web.configに配置します。

 <httpModules>
      <add name="HttpsOnlyModule" type="HttpsOnly.HttpsOnlyModule, HttpsOnly" />
 </httpModules>

これは単にglobal.asaxに固定するよりも複雑なようです-興味があるだけですが、利点はありますか?
ブライアンマッケイ

1
利点は、使用しない場合は、web.configでモジュールをコメント化することです。このソリューション構成可能ですが、他の構成はできません。
Bob Yexley、2009年

2
私は少し混乱しています。私app.BeginRequest += new OnBeginRequest;Initメソッドのようなものを期待していました、そしてOnBeginRequest現在のInitメソッドが含んでいるものを含んでいるでしょう。このモジュールは期待どおりに機能しますか?
JakubŠturc10年

それは動作しません。OnBeginRequestイベントなどを追加する必要があります。そうすると機能します。
SnAzBaZ 2010年

私はこの欠陥のあるコードを編集しますが、それを安全にするために、HSTSも使用する必要があります。Troy Huntの答えを参考にして、モジュールにしてください。support.microsoft.com/en-us/kb/307996を参照してください(昔ながらですが、良い点です)。
Marc L.

4

あなたがする必要があるのは:

1)以下のような本番サーバーまたはステージサーバーに応じて、web.config内にキーを追加します。

<add key="HttpsServer" value="stage"/>
             or
<add key="HttpsServer" value="prod"/>

2)Global.asaxファイル内に以下のメソッドを追加します。

void Application_BeginRequest(Object sender, EventArgs e)
{
    //if (ConfigurationManager.AppSettings["HttpsServer"].ToString() == "prod")
    if (ConfigurationManager.AppSettings["HttpsServer"].ToString() == "stage")
    {
        if (!HttpContext.Current.Request.IsSecureConnection)
        {
            if (!Request.Url.GetLeftPart(UriPartial.Authority).Contains("www"))
            {
                HttpContext.Current.Response.Redirect(
                    Request.Url.GetLeftPart(UriPartial.Authority).Replace("http://", "https://www."), true);
            }
            else
            {
                HttpContext.Current.Response.Redirect(
                    Request.Url.GetLeftPart(UriPartial.Authority).Replace("http://", "https://"), true);
            }
        }
    }
}

3

サイトでSSLサポートを構成できない場合(つまり、httpsをオン/オフにできる必要がある場合)-保護したいコントローラー/コントローラーアクションの[RequireHttps]属性を使用できます。



2

上記の@Joeの場合、「これによりリダイレクトループが発生します。コードを追加する前に、うまく機能しました。何か提案はありますか?– Joe Nov 8 '11 at 4:13」

これは私にも起こりました。そして、私が信じていたのは、Webサーバーの前でSSL要求を終了するロードバランサーがあったことです。そのため、私のWebサイトは、元のブラウザが「https」であると要求した場合でも、常に「http」であると考えていました。

私はこれが少しハックだと認めますが、私にとってうまくいったのは、人物がすでにリダイレクトされたことを理解するために活用できる "JustRedirected"プロパティを実装することでした。そのため、リダイレクトを保証する特定の条件をテストし、条件を満たす場合は、リダイレクトの前にこのプロパティ(セッションに格納されている値)を設定します。2回目にリダイレクトのhttp / https条件が満たされた場合でも、リダイレクトロジックをバイパスして、「JustRedirected」セッション値をfalseにリセットします。独自の条件付きテストロジックが必要になりますが、以下にプロパティの簡単な実装を示します。

    public bool JustRedirected
    {
        get
        {
            if (Session[RosadaConst.JUSTREDIRECTED] == null)
                return false;

            return (bool)Session[RosadaConst.JUSTREDIRECTED];
        }
        set
        {
            Session[RosadaConst.JUSTREDIRECTED] = value;
        }
    }

2

私は中に私の2セントを投げるつもりです。IFあなたはIISサーバー側へのアクセスを持って、あなたはプロトコルバインディングを使用してHTTPSを強制することができます。たとえば、BlahというWebサイトがあるとします。:IISでは、セットアップ二つのサイトいただきたい何とか、と何とか(リダイレクト)。以下のために何とかのみ設定HTTPS結合を(そしてFTPあなたがする必要がある場合は、だけでなく、セキュアな接続を介してそれを強制することを確認してください)。以下のために何とか(リダイレクト)のみを設定HTTPバインディングを。最後に、Blah(リダイレクト)HTTPリダイレクトセクションで、301リダイレクトをに設定し、正確な宛先を有効にします。IISの各サイトがそれを指していることを確認してくださいhttps://blah.com独自のルートフォルダがないと、Web.configがすべて失敗します。またHSTS、ブラウザによる後続のリクエストが常にHTTPSに強制され、リダイレクトが発生しないように、HTTPSサイトで設定されていることを確認してください。


2

これは@Troy Huntに基づくより完全な回答です。この関数を次のWebApplicationクラスに追加しますGlobal.asax.cs

    protected void Application_BeginRequest(Object sender, EventArgs e)
    {
        // Allow https pages in debugging
        if (Request.IsLocal)
        {
            if (Request.Url.Scheme == "http")
            {
                int localSslPort = 44362; // Your local IIS port for HTTPS

                var path = "https://" + Request.Url.Host + ":" + localSslPort + Request.Url.PathAndQuery;

                Response.Status = "301 Moved Permanently";
                Response.AddHeader("Location", path);
            }
        }
        else
        {
            switch (Request.Url.Scheme)
            {
                case "https":
                    Response.AddHeader("Strict-Transport-Security", "max-age=31536000");
                    break;
                case "http":
                    var path = "https://" + Request.Url.Host + Request.Url.PathAndQuery;
                    Response.Status = "301 Moved Permanently";
                    Response.AddHeader("Location", path);
                    break;
            }
        }
    }

(ローカルビルドでSSLを有効にするには、プロジェクトのプロパティドックで有効にします)


1

-> [RequireHttps]をパブリッククラスHomeController:Controllerに追加するだけです。

->そして、GlobalFilters.Filters.Add(new RequireHttpsAttribute());を追加します。Global.asax.csファイルの 'protected void Application_Start()'メソッド内。

これにより、アプリケーション全体がHTTPSに強制されます。


これが、WebFormsまたはWebAPIで構築されたAPIを使用して提供されるページで機能するとは思わない。MVCコントローラーのみをカバーします。
Marc L.

1

私はいつか、意味のあるベストプラクティスを探すのに費やしましたが、次のことが私にとって完璧に機能することがわかりました。これがいつかあなたを救ってくれることを願っています。

使用する設定ファイル(例えばasp.netのウェブサイト) https://blogs.msdn.microsoft.com/kaushal/2013/05/22/http-to-https-redirects-on-iis-7-x-and-をより高い/

または独自のサーバー https://www.sslshopper.com/iis7-redirect-http-to-https.html

[SHORT ANSWER]単に以下のコードが内部に入ります

<system.webServer> 
 <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}{REQUEST_URI}" 
        redirectType="Permanent" />
        </rule>
       </rules>
 </rewrite>

1

IIS10(Windows 10およびServer 2016)では、バージョン1709以降、WebサイトでHSTSを有効にするための新しいより簡単なオプションがあります。

マイクロソフトはここで新しいアプローチの利点を説明し、プログラムで、またはApplicationHost.configファイル(web.configに似ていますが、個々のサイトレベルではなくIISレベルで動作します)を直接編集して変更を実装する方法のさまざまな例を提供します)。ApplicationHost.configはC:\ Windows \ System32 \ inetsrv \ configにあります。

リンクの腐敗を避けるために、ここでは2つのサンプルメソッドの概要を説明しました。

方法1 -ApplicationHost.configファイルを直接編集する<site>タグの間に次の行を追加します。

<hsts enabled="true" max-age="31536000" includeSubDomains="true" redirectHttpToHttps="true" />

方法2-コマンドライン:管理者特権のコマンドプロンプトから次のコマンドを実行します(CMDを右マウスでクリックして管理者として実行します)。IISマネージャーに表示されるサイトの名前でContosoを交換することを忘れないでください。

c:
cd C:\WINDOWS\system32\inetsrv\
appcmd.exe set config -section:system.applicationHost/sites "/[name='Contoso'].hsts.enabled:True" /commit:apphost
appcmd.exe set config -section:system.applicationHost/sites "/[name='Contoso'].hsts.max-age:31536000" /commit:apphost
appcmd.exe set config -section:system.applicationHost/sites "/[name='Contoso'].hsts.includeSubDomains:True" /commit:apphost
appcmd.exe set config -section:system.applicationHost/sites "/[name='Contoso'].hsts.redirectHttpToHttps:True" /commit:apphost

アクセスが制限されているホストされた環境にいる場合は、Microsoftがその記事で提供している他の方法がより良い選択肢となる可能性があります。

IIS10バージョン1709は現在Windows 10で利用できますが、Windows Server 2016では別のリリーストラックにあり、パッチまたはサービスパックとしてリリースされません。1709の詳細については、ここを参照てください。


0

ASP.NET Coreを使用している場合は、nugetパッケージSaidOut.AspNetCore.HttpsWithStrictTransportSecurityを試すことができます。

次に、追加する必要があります

app.UseHttpsWithHsts(HttpsMode.AllowedRedirectForGet, configureRoutes: routeAction);

これにより、httpsスキームを使用して行われるすべてのリクエストにHTTP StrictTransportSecurityヘッダーも追加されます。

コードとドキュメントの例https://github.com/saidout/saidout-aspnetcore-httpswithstricttransportsecurity#example-code

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.