2011-03-14 97 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