web-dev-qa-db-ja.com

httpからhttpsへのasp.net c#リダイレクト

したがって、私のコードでは、ログインページがhttpと呼ばれているかどうかを検出し、httpsにリダイレクトします。

この猫の皮を剥ぐための非コードの方法があることは知っていますが、イライラする技術的な理由のために、私はコードでそれを行うことにバックアップしています。

_            if (!Request.IsSecureConnection)
            {
                string redirectUrl = Request.Url.ToString().Replace("http:", "https:");
                Response.Redirect(redirectUrl);
            }
_

したがって、これをPage_Load(...)にドロップし、デバッガーがVS2008s IISではなく実際のIISを使用していることを確認し、デバッグを実行します。

デバッガーで、ワルツに沿ってResponse.Redirect( " https://localhost/StudentPortal3G/AccessControl/AdLogin.aspx ")を押し、f5を押します。

「Internet ExplorerでWebページを表示できません。URLはHTTPSでなくHTTPです。情報エラーを取得できません...デバッガーで実行していないのと同じことが起こります。

だから私は何が欠けていますか?それはロケット科学ではないようです、私は多くのブログで同様のコードを見てきました...

何が間違っていますか?私はそれが完全に明らかなルーキーの間違いでなければならないと思いますが、私はそれを見ていません。

49

デバッグするときに証明書を適用してIISの実際のインスタンスを使用している場合でも、デバッグしていないことを確認するために_!Request.IsLocal_も行います問題になりません。

_if (!Request.IsLocal && !Request.IsSecureConnection)
{
    string redirectUrl = Request.Url.ToString().Replace("http:", "https:");
    Response.Redirect(redirectUrl, false);
    HttpContext.ApplicationInstance.CompleteRequest();
}
_

注:この回答は、HttpContextが現在のコンテキストを保持するプロパティであるコントローラー内のMVCコンテキストを想定しています。 WebFormsをまだ使用していないか、退化した方法でコンテキストを参照している場合は、HttpContext.Current.ApplicationInstance.CompleteRequest()を使用する必要があります。

注: framework documentation に従って要求を終了する推奨パターンと一致するように、これを更新しました。

ページハンドラーでこのメソッドを使用して、あるページのリクエストを終了し、別のページの新しいリクエストを開始する場合、endResponseをfalseに設定してからCompleteRequestメソッドを呼び出します。 endResponseパラメーターにtrueを指定すると、このメソッドは元の要求に対してEndメソッドを呼び出し、完了時にThreadAbortException例外をスローします。この例外はWebアプリケーションのパフォーマンスに悪影響を与えるため、endResponseパラメーターにfalseを渡すことをお勧めします。詳細については、Endメソッドを参照してください。

82
tvanfosson

私は通常、すべてのページが継承する基本クラスのOnPreInitから次を呼び出します。もちろん、すべてのページでこれを行うことができます...しかし、あなたは今それをしたくないでしょうか?

各ページに2つのプロパティがあるため、各ページのSSL要件(RequiresSSL)を指定できる一方、必要に応じてチェックをオーバーライドおよびリダイレクトすることもできます(IgnoreRequiresSSLを使用すると、エラーページなどのページに役立ちます)暗号化するかどうかは書き直しますが、わかりません)が、もちろん、簡単なセットアップのためにこれらを削除することができます。

    protected override void OnPreInit(EventArgs e)
    {
        base.OnPreInit(e);

        if (!IsPostBack)
            RedirectAccordingToRequiresSSL();

        ...
    }

    /// <summary>
    /// Redirect if necessary to ssl or non-ssl enabled URL dependant on RequiresSSL property setting.
    /// </summary>
    private void RedirectAccordingToRequiresSSL()
    {
        if (IgnoreRequiresSSL) return;

        if (RequiresSSL)
        {
            if (!Request.IsSecureConnection) // Need to redirect to https
                RedirectAccordingToRequiresSSL(Uri.UriSchemeHttps);
        }
        else if (Request.IsSecureConnection)
        {
            RedirectAccordingToRequiresSSL(Uri.UriSchemeHttp);
        }

        // Otherwise don't need to do any redirecting as already using the correct scheme
    }

    /// <summary>
    /// Redirect as requested to specified scheme
    /// </summary>
    /// <param name="scheme"></param>
    private void RedirectAccordingToRequiresSSL(string scheme)
    {
        var url = scheme + Uri.SchemeDelimiter + Request.Url.Authority + Request.Url.PathAndQuery;
        Response.Redirect(url, false);
    }
24
Ted

私の意見では、以下が最善のオールラウンドなアプローチです。

3つの理由

  1. MVCレベルで行われるように、IISWeb APIの両方で機能します。
  2. ローカル/デバッグ設定には影響しません。 (PCでhttps以外のサイトをデバッグする場合、永続的なリダイレクトが混乱する可能性があります)。
  3. 永続的なリダイレクトを使用するため、今後のリクエストはすべて自動的にhttpsに送られます

プロジェクトの「Web.config」の<system.webServer>セクションに次を追加するだけです。

 <system.webServer>
 ....

 <rewrite>
  <rules>
    <rule name="HTTP to HTTPS redirect" stopProcessing="true">
      <match url="(.*)" />
      <conditions>
        <add input="{HTTP_Host}" pattern="localhost" negate="true" />
        <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>
9
Zapnologica

新しいUriBuilderを使用することもできます。

Dim context As HttpContext = HttpContext.Current
If Not context.Request.IsSecureConnection Then
    Dim secureUrl As New UriBuilder(context.Request.Url)
    secureUrl.Scheme = "https"
    secureUrl.Port = 443
    context.Response.Redirect(secureUrl.ToString, False)
    Return
End If

C#

HttpContext context = HttpContext.Current;
if (!context.Request.IsSecureConnection)
{
    UriBuilder secureUrl = new UriBuilder(context.Request.Url);
    secureUrl.Scheme = "https";
    secureUrl.Port = 443;
    context.Response.Redirect(secureUrl.ToString(), false);
}
7

Httpsリダイレクトを実施できた方法の1つは、次の方法です。

アプリプールでは、ポート443のみでアプリケーションを実行しているため、暗号化されていないセッションが発生する可能性はありません(暗号化スキームが脆弱性を突破しない限り)。次のコードを含むweb.configファイルのみを含む同じIPアドレスで、ポート80に別のアプリケーションを作成しました

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
    <httpRedirect enabled="true" destination="https://yourWebsiteURL.com" />
</system.webServer>
3
Erkin Djindjiev

また、tvalfonssoの解決策をお勧めしますが、URLを書き換える場合は少し変更します(RawUrlはUrlとは異なります)

    if (SPPage == SPPages.StartAutotrading && !Request.IsLocal && !Request.IsSecureConnection)
        {
            string redirectUrl = (Request.Url.ToString().Replace(Request.Url.PathAndQuery.ToString(), "") + Request.RawUrl).Replace("http:", "https:");
            Response.Redirect(redirectUrl);
        }
2
Robert Benyi

私のソリューションは次のとおりです。

// Force HTTPS connection
if (!Request.IsSecureConnection)
{
    var uri = new Uri(Request.Url.ToString());
    var redirectUrl = Settings.CanonicalDomain + uri.PathAndQuery;
    Response.Status = "301 Moved Permanently";
    Response.AddHeader("Location", redirectUrl);
    Response.End();
}

どこSettings.CanonicalDomainはHTTPSホスト名です。 301リダイレクトは、場合によっては適切な応答である可能性があります。

2
Tom Gullen

免責事項-私はこのプロジェクトの開発に関わっていました

http://nuget.org/packages/SecurePages/ を使用することをお勧めします。特定のページを保護したり、正規表現を使用して一致を定義したりできます。また、正規表現に一致しないページまたはHTTPに直接指定されていないすべてのページを強制します。

NuGet経由でインストールできます:Install-Package SecurePages

ドキュメントはこちら: https://github.com/webadvanced/Secure-Page-manager-for-asp.net#secure-pages

簡単な使用法:

SecurePagesConfiguration.Urls.AddUrl("/cart");

または

SecurePagesConfiguration.Urls.AddRegex(@"(.*)account", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
1
Paul

私の開発環境では、IISを使用して、Visual Studio内で直接デバッグする証明書のないコードディレクトリとは異なる自己署名証明書をインストールした別の発行ディレクトリが必要です。このシナリオでは!Request.IsLocalは、IISディレクトリの証明書がある場合でも、開発環境のどこでも機能しないため、理想的ではありません。

if (!IsPostBack && !HttpContext.Current.IsDebuggingEnabled) 
{
    // do http->https and https->http redirection here
}

HttpContext.Current.IsDebuggingEnabledは、web.config内のコンパイルdebug = "true/false"の値に基づいています。コードディレクトリでtrueに設定し、httpおよびhttpsリダイレクションをローカルでテストする必要がある場合は公開ディレクトリでfalseに設定します。

IsPostBackを追加するのは、不要な場合に余分なsslチェックをスキップすることで(わずかに)より効率的にするためです。

1
TTT