2011-03-14 93 views
46

因此,在我的代碼中,我想檢測我的登錄頁面是否被稱爲http,並將其重定向到https。asp.net c#從http重定向到https

我知道有非代碼的方式來剝皮這隻貓,但令人沮喪的技術reasosn我支持在代碼中做它。

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

所以我在Page_Load(...)下降這一點,以確保我的調試器使用真正的IIS,沒有VS2008s IIS,並創下調試。

在調試器中,華爾茲沿,命中 Response.Redirect(「https://localhost/StudentPortal3G/AccessControl/AdLogin.aspx」), 命中f5。

獲得「互聯網Explorere無法顯示該網頁,網址是HTTP,HTTPS不是。 沒有收到信息的錯誤...同樣的事情發生不是在調試器中運行。

所以我錯過什麼?它看來不是火箭科學,我已經看到了很多博客的代碼類似......

什麼我做錯了什麼?我想,這必須是一個完全明顯新手的錯誤,但我沒有看到它。

+1

在IE關閉「顯示友好的錯誤消息」,看看它說。如果「友好」(我使用這個術語鬆散地)打開錯誤消息,並且IE獲得非200狀態代碼並且信息少於512字節,它會打開盲區。 – NotMe 2011-03-14 22:36:59

+0

嘗試包括http://msdn.microsoft.com/en-us/library/system.uri.scheme.aspx來處理協議。 – 2011-03-14 22:40:16

+0

@Chris - 我將該設置關閉並仍然出現相同的錯誤。任何想法如何獲取信息錯誤? – 2011-03-15 14:46:09

回答

80

我會做一個!Request.IsLocal,以確保我沒有調試,但如果你使用的是一個真正的實例在調試時應用證書的IIS的IIS應該不是問題。

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到 假,然後調用CompleteRequest方法。如果您爲endResponse參數指定了真 ,則此方法會調用原始請求的 的End方法,該方法在完成時會拋出ThreadAbortException異常 。此異常對Web應用程序性能造成不利影響,這就是爲什麼建議將 endResponse參數傳遞爲false的原因。有關更多信息,請參見 End方法。

+0

只有一個問題這個重定向:會話變量可能會丟失 – 2014-05-09 21:40:58

+0

@The_Ghost怎麼這樣?我不確定你在做什麼。 – tvanfosson 2014-05-09 22:03:31

+0

沒有「false」作爲Response.Redirect的第二個參數,會話變量將會丟失。已經遇到同樣的問題 – 2014-05-13 17:28:39

24

我通常從OnPreInit中調用以下基類中的所有頁面繼承的內容。當然,你可以在每一頁都做到這一點......但你現在不想這麼做嗎?

請注意,我有每個頁面的兩個屬性,以便我可以指定每個頁面的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); 
    } 
+0

這顯然是一種更好的解決方法,我在搜索時閱讀了你的文章,但直到我實施作品的「醜陋」soloution,這不會是正確的嗎?因爲最後從HTTP到https「手動」的ResponseRedirect,我是否正確? – 2011-03-15 15:02:42

+1

是的。您的核心問題是沒有正確安裝證書並將其分配到網站 - 如果您需要幫助,請詢問。 – Ted 2011-08-09 17:36:54

+0

+1有幫助,並有更好的通用目的soloution,即使我與上面明顯的答案。 – 2011-08-09 21:45:57

1

免責聲明 - 我參與了這個項目

我會建議使用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); 
+0

感謝您發佈您的答案!請務必仔細閱讀[自助推廣常見問題](http://stackoverflow.com/faq#promotion)。另請注意,每次鏈接到您自己的網站/產品時,您都必須*發佈免責聲明。 – 2013-02-09 01:02:08

+1

酷,有人要回去告訴大家誰曾經自我提升他們的工作,以便補充一點免責聲明公平起見... – TheLegendaryCopyCoder 2015-07-02 12:43:11

1

這裏是我的解決方案:

// 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重定向,這在某些情況下可能是正確的響應。

1

在我的開發環境,我喜歡用一個自簽名的證書安裝IIS單獨發佈目錄,這是不同的形式,我的代碼目錄,而我直接調試的Visual Studio的內部證書。在這種情況下!Request.IsLocal並不理想,因爲它不會在你的開發環境,在任何地方工作,甚至在與證書的IIS目錄。我喜歡這樣的:

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

HttpContext.Current.IsDebuggingEnabled是基於你的web.config編譯調試=「真/假」的值。我有它在我的代碼目錄設置爲true,並在我的發佈目錄的錯誤,當我需要測試HTTP和HTTPS重定向本地。

我在IsPostBack添加只是讓它(略)通過在不需要時跳過額外的SSL檢查更有效。

2

我也建議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); 
     } 
5

您還可以使用新的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); 
} 
+0

這是好多了!因爲你可以使用默認值以外的端口443 – 2017-03-03 06:29:43

1

其中之一,我是能夠執行的HTTPS重定向目標的途徑以下內容:

在應用程序池我有我的應用程序運行得443端口,以便有針對發生未加密的會話沒有方法可行(除非加密方案通過漏洞打破..)。我創建了80端口另一個應用程序與只包含網絡相同的IP地址。配置文件用下面的代碼

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

7

在我看來,以下是最優質的全方位的辦法。

理由三

  1. ,因爲它是在IIS級別完成它同時適用於MVCWeb API
  2. 它不影響本地/調試設置。 (在您的電腦上調試非https網站時,永久性重定向可能會讓您感到困惑)。
  3. 使用永久重定向,因此未來所有的請求都會自動轉到https

只需添加以下到您的<system.webServer>節你爲你的項目「Web.config中」。

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

這回答很好,除了''標籤進入''。 – 2017-01-14 16:10:17