因此,在我的代码中,我想检测我的登录页面是否被称为http,并将其重定向到https。
我知道有一些非代码方法来修饰这只猫,但是由于令人沮丧的技术问题,我已经支持在代码中进行操作。
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。
获取“Internet Explorere无法显示网页,网址是HTTP,而不是HTTPS。 没有得到信息错误......同样的事情发生在调试器中没有运行。
那我错过了什么?它似乎不是火箭科学,我在许多博客上看到过类似的代码......
我做错了什么?我认为它必须是一个完全明显的新秀错误,但我没有看到它。
答案 0 :(得分:82)
我也会做一个!Request.IsLocal
来确保我没有调试,不过如果你使用的是一个真正的IIS实例,并且在调试时应用了一个不应该成为问题的证书。
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()
。
注意:我已将此更新为与推荐的模式一致,以根据framework documentation终止请求。
在页面处理程序中使用此方法终止请求时 一页并开始另一页的新请求,将endResponse设置为 false然后调用CompleteRequest方法。如果指定true 对于endResponse参数,此方法调用End方法 原始请求,抛出ThreadAbortException异常 当它完成。此异常对Web有不利影响 应用程序性能,这就是为什么传递false的原因 建议使用endResponse参数。有关更多信息,请参阅 结束方法。
答案 1 :(得分: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);
}
答案 2 :(得分:9)
在我看来,以下是最好的全方位方法。
三个原因
MVC
和Web API
,因为它是在IIS
级别完成的。https
网站时,永久重定向可能会让您感到困惑。)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>
答案 3 :(得分:7)
您也可以使用新的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);
}
答案 4 :(得分:2)
这是我的解决方案:
// 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重定向,在某些情况下可能是适当的响应。
答案 5 :(得分:2)
我还建议使用tvalfonsso的解决方案,但如果您有一些网址重写(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);
}
答案 6 :(得分:2)
我能够执行https重定向的方法之一是:
在应用程序池中,我的应用程序仅在端口443上运行,因此无法进行未加密的会话(除非通过漏洞破解加密方案......)。我在端口80上创建了另一个具有相同IP地址的应用程序,其中只包含 web.config 文件,其中包含以下代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpRedirect enabled="true" destination="https://yourWebsiteURL.com" />
</system.webServer>
答案 7 :(得分:1)
免责声明 - 我参与了这个项目的开发
我建议使用http://nuget.org/packages/SecurePages/它使您能够保护特定页面或使用Regex来定义匹配。它还会强制所有与Regex不匹配或直接指定的页面返回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);
答案 8 :(得分:1)
在我的开发环境中,我希望有一个单独的发布目录,其中IIS安装了自签名证书,这与我的代码目录不同,没有我直接在Visual Studio内部调试的证书。在这种情况下,!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,当我需要在本地测试http和https重定向时,在我的发布目录中设置为false。
我添加IsPostBack
只是为了通过在不需要时跳过额外的ssl检查来提高(略微)效率。
答案 9 :(得分:0)
让IIS在不使用重写的情况下完成此操作的简单方法:
您还可以从web.config的HttpErrors部分添加。