asp.net c#从httpredirect到https
所以在我的代码中,我想检测我的login页面是否被称为http,并将其redirect到https。
我知道有没有代码的方式来剥皮这只猫,但令人沮丧的技术reasosn我支持在代码中做它。
if (!Request.IsSecureConnection) { string redirectUrl = Request.Url.ToString().Replace("http:", "https:"); Response.Redirect(redirectUrl); }
所以我把它放在我的Page_Load(...)
,确保我的debugging器使用真正的IIS,而不是VS2008的IIS,并打中debugging。
在debugging器中,华尔兹,命中Response.Redirect(“ https://localhost/StudentPortal3G/AccessControl/AdLogin.aspx ”),命中f5。
获取“互联网Explorere不能显示网页,url是HTTP,而不是HTTPS。没有得到一个信息错误…同样的事情发生没有运行在debugging器。
那么我错过了什么? 它似乎不是火箭科学,我已经看过很多博客上的类似的代码…
我究竟做错了什么? 我认为这应该是一个非常明显的新秀错误,但我没有看到它。
我会做一个!Request.IsLocal
以及确保我没有debugging,但如果你正在使用一个真实的IIS实例与debugging时应用的证书不应该是一个问题。
if (!Request.IsLocal && !Request.IsSecureConnection) { string redirectUrl = Request.Url.ToString().Replace("http:", "https:"); Response.Redirect(redirectUrl, false); HttpContext.ApplicationInstance.CompleteRequest(); }
注意:这个答案假定一个Controller中的MVC上下文,其中HttpContext
是一个拥有当前上下文的属性。 如果您不幸仍然使用WebForms或以退化的方式引用上下文,则需要使用HttpContext.Current.ApplicationInstance.CompleteRequest()
。
注意:我已经更新了这个与build议的模式一致,根据框架文档来终止请求。
在页面处理程序中使用此方法来终止一个页面的请求并为另一个页面启动一个新的请求时,将endResponse设置为false,然后调用CompleteRequest方法。 如果为endResponse参数指定true,则此方法将为原始请求调用End方法,该方法在完成时引发ThreadAbortExceptionexception。 此exception对Web应用程序性能有不利影响,因此build议为endResponseparameter passingfalse。 有关更多信息,请参阅End方法。
我通常在OnPreInit中调用以下所有页面inheritance的基类中的以下内容。 当然,你可以在每一页都做到这一点,但是现在你不想那么做了吗?
请注意,我有两个属性为每个页面,以便我可以指定每个页面的SSL要求(RequiresSSL),而我也可以重写和redirect检查,如果我想(与IgnoreRequiresSSL,这对页面有用,如错误页面重写和不知道它们是否被encryption),但当然,你可以删除这些简单的设置。
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); }
在我看来,以下是最好的全面方法。
三个原因
- 它适用于
MVC
和Web API
因为它是在IIS
级完成的。 - 它不影响本地/debugging设置。 (永久redirect可以打乱你的电脑上非
https
网站的debugging)。 - 使用永久redirect,所有未来的请求将自动转到
https
只需将以下内容添加到您的项目的“Web.config”中的<system.web>
部分即可。
<system.web> .... <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.web>
你也可以使用新的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); }
我也build议tvalfonsso的解决scheme,但是如果你有一些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); }
免责声明 – 我参与了这个项目的开发
我会build议使用http://nuget.org/packages/SecurePages/它使您能够保护特定页面或使用正则expression式来定义匹配。; 它也将强制所有页面不匹配正则expression式或直接指定回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);
这是我的解决scheme:
// 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主机名。 它301redirect,在某些情况下可能是正确的回应。
在我的开发环境中,我希望有一个单独的发布目录,IIS安装了一个自签名的证书,这与我的代码目录不同,没有证书,我直接在Visual Studio中进行debugging。 在这种情况下, !Request.IsLocal
并不理想,因为它在开发环境中的任何地方都不起作用,甚至在带有cert的IIS目录中也是如此。 我更喜欢这个:
if (!IsPostBack && !HttpContext.Current.IsDebuggingEnabled) { // do http->https and https->http redirection here }
HttpContext.Current.IsDebuggingEnabled
是基于web.config中编译debug =“true / false”的值。 我有它在我的代码目录中设置为true,当我需要在本地testinghttp和httpsredirect时,我的发布目录中为false。
我添加IsPostBack
只是为了使它稍微更有效率,通过在不需要的时候跳过额外的ssl检查。
我能够执行httpsredirect的方法之一是以下几点:
在应用程序池中,我的应用程序仅在端口443上运行,因此不可能发生未encryption的会话(除非encryptionscheme因为漏洞而中断)。 我使用相同的IP地址在端口80上创build了另一个应用程序,其中只包含一个web.config文件,其代码如下所示
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <httpRedirect enabled="true" destination="https://yourWebsiteURL.com" /> </system.webServer>