0

ログインと安全なhttpsページを処理するユーザーコントローラーのほとんどのアクションでRequireHttps属性を使用しています。

httpである私のホームページには、次のようにログインページへのリンクがあります(MVC 4 Razor View):-

<a href="@Url.Action("Login", "User")">Login</a>

リンクは、httpsアドレスのログインページに正しく移動します。ただし、IISログを見ると、ログインURLに2つのエントリがあります。1つはポート80に、もう1つはポート443にあります。

これは私が心配すべき問題ですか?

@ Url.Actionで、httpsモードを強制できることはわかっていますが、これが最善の方法かどうかはわかりません。さらに、これによりポートが削除されます。これは、VS2012でIISExpressを使用する場合に煩わしいものです。次に、@ Url.Actionをさらに拡張して、hostname:portを含める必要があります。

したがって、(a)これが懸念事項であるかどうか、および(b)URLをhttpsに強制する他の方法があるかどうかが懸念事項であるかどうかを確認しています。

4

3 に答える 3

4

ほとんどのチュートリアルでは、混合モードサイト(HTTPとHTTPSの両方)を使用することで、SSLの目的を無効にすることに同意します(特定のパスでSSLが必要な場合は、SSL以外の接続に切り替えます)。HTTPSに切り替えたら、少なくともユーザーがログアウトするまで、すべてのユーザーにHTTPSを使用し続けるように強制することをお勧めします。HTTPSを使用するサイトが1つあり、サイトにアクセスしたら、URL書き換えルールを使用してユーザーをHTTPSに切り替えるだけで、HTTPSのみが許可されます。

<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>

これを行ったら、HTTPSも要求するように認証Cookieを設定することもお勧めします。フォーム認証の場合、これはweb.configで次のように設定するのと同じくらい簡単です。

<authentication>
    <forms requireSSL="true" />
</authentication>

また、Strict-Transport-Securityを使用してサイトにSSLが必要であることを示すなど、ブラウザーがサイトを正しく処理するのに役立つように設定できるヘッダーのいくつかを確認することをお勧めします。ヘッダーは実行できる優れた補足手段ですが、最終的にはブラウザーが強制するために残されており、排他的に依存するべきではないことに注意してください。

あなたが説明している症状に悩まされることはなく、ログで気付いている問題の解決に役立つことを願っているので、これらの手順をお勧めします。

修正:ああ、私も言及するのを忘れました。HTTPSは、従来のHTTPよりも接続を確立するのに少し集中的です。物事の壮大な計画にはあまりありませんが、それでもそれは何かです。そのオーバーヘッドの一部を減らすために、HTTPキープアライブを利用することをお勧めします。

更新: SSLを介した通信は、認証されていることを意味するものではありません。これは、安全な/暗号化された接続を介して話していることを意味します。

あなたのAmazonの例を見てみましょう。このサイトにアクセスすると、HTTPを介した通常の接続を利用できるようになります。ログインしていません。サイトを閲覧しているだけです。必要に応じて、HTTPSに切り替えることができ、同じサイトを取得できますが、まだログインしていません。これで、ログインしようとすると、HTTPSモニカで示されているように、SSLを介して話すようにリダイレクトされます(まだ行っていない場合)。実際にログインした後でも、SSLを介して通信します。ログイン中にURLのプロトコル部分からSを削除して、SSLを使用しないように手動で切り替えようとしても、HTTPSの使用に戻ります。これが正しい方法です。通常、認証後に暗号化されていないセッションに戻らないことをお勧めします。これは通常、認証CookieがプレーンHTTPを介して送信されることはないため、セッションハイジャックを回避するためです。外部ソースにあるリソースが、信頼できるサイトにあることを確認してください。HTTP接続中の外部リソースアクセスもSSL接続を介して行う必要があります。繰り返しますが、SSLを介して通信するからといって、それらのソースにログインしているわけではありません。私のアプリはSSLを介した100%アクセスですが、サイトにはGoogleアナリティクスとGoogleマップの統合もあります(明らかに両方とも私のドメインの外部にあります)。SSL経由でGoogleと話していることを確認します。これらを使用するために、実際にGoogleにログインする必要はありません。同じことが外部画像にも当てはまります。URLを確認してください」

更新:このようなログで2つのヒットが発生する理由は、ログインリンクがHTTP経由で要求されているためです。最初に、HTTPS属性のヒットが必要であると、SSLを使用していないことが認識され、HTTPSを使用して自分自身にリダイレクトされます。プロトコル。ActionLink URLを更新すると、これを回避できますが、ご存知のとおり、見苦しくなります。

Url.Action("Login", "User", null, "https", Request.Url.Host)
于 2013-02-27T18:00:52.040 に答える
3

これをglobal.ascxに追加します

protected void Application_BeginRequest()
        {
            if (!Context.Request.IsSecureConnection)
                Response.Redirect(Context.Request.Url.ToString().Replace

("http:", "https:"));
        }

これにより、すべてのリクエストがhttpではなくhttpsに変換されます

于 2014-03-24T10:34:05.763 に答える
0

属性の装飾に応じて適切なプロトコルを生成するUrl.Actionの拡張機能を作成します。確認させてください

public static class Extensions
{
    public static string SecuredAction(this UrlHelper helper, string action, string controller)
    {
        bool requireSSL = false;
        var route = System.Web.Routing.RouteTable.Routes.Select(r => r as System.Web.Routing.Route) .Where(r =>
            r != null && r.Defaults != null && r.Defaults["controller"] != null && r.Defaults["controller"].ToString().Equals(controller, StringComparison.InvariantCultureIgnoreCase)
            && r.Defaults["action"] != null && r.Defaults["action"].ToString().Equals(action, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();

        if(route == null)
            return helper.Action(action, controller);

        //Get the method and check if requiere ssl
        MemberInfo method = route.DataTokens["TargetActionMethod"] as MemberInfo;
        requireSSL = method.CustomAttributes.Any(a => a.AttributeType == typeof(RequireHttps)) || method.DeclaringType.CustomAttributes.Any(a => a.AttributeType == typeof(RequireHttps));

        //Return the correct protocol
        if(helper.RequestContext.HttpContext.Request.IsSecureConnection && !requireSSL)
            return helper.Action(action, controller, null, "http");

        if (!helper.RequestContext.HttpContext.Request.IsSecureConnection && requireSSL)
            return helper.Action(action, controller, null, "https");

        return helper.Action(action, controller);
    }
}
于 2014-10-14T05:10:10.613 に答える