因此,在我的代码中,我想检测我的登录页面是否被称为http,并将其重定向到https。
我知道有一些非代码方法来修饰这只猫,但由于技术原因令人沮丧,我已经支持在代码中进行操作。
if (!Request.IsSecureConnection)
{
string redirectUrl = Request.Url.ToString().Replace("http:", "https:");
Response.Redirect(redirectUrl);
}
所以我把它放在我的Page_Load(...)
中,确保我的调试器使用真正的IIS,而不是VS2008s IIS,并点击调试。
在调试器中,华尔兹一起,点击Response.Redirect(“qazxsw i”),点击f5。
获取“Internet Explorer无法显示网页,网址是HTTP,而不是HTTPS。没有收到信息错误...同样的事情发生在调试器中没有运行。
那我错过了什么?它似乎不是火箭科学,我在许多博客上看到了类似的代码......
我究竟做错了什么?我认为它必须是一个完全明显的新秀错误,但我没有看到它。
我也做一个https://localhost/StudentPortal3G/AccessControl/AdLogin.aspx以确保我没有调试,但是如果你使用的是一个真正的IIS实例,并且在调试时应用了一个不应该成为问题的证书。
!Request.IsLocal
注意:此答案假定控制器中的MVC上下文,其中if (!Request.IsLocal && !Request.IsSecureConnection)
{
string redirectUrl = Request.Url.ToString().Replace("http:", "https:");
Response.Redirect(redirectUrl, false);
HttpContext.ApplicationInstance.CompleteRequest();
}
是包含当前上下文的属性。如果您还不幸使用WebForms或以简并方式引用上下文,则需要使用HttpContext
。
注意:我已根据HttpContext.Current.ApplicationInstance.CompleteRequest()
将此更新为与推荐的模式一致以终止请求。
在页面处理程序中使用此方法终止对一个页面的请求并为另一个页面启动新请求时,请将endResponse设置为false,然后调用CompleteRequest方法。如果为endResponse参数指定true,则此方法为原始请求调用End方法,该方法在完成时抛出ThreadAbortException异常。此异常对Web应用程序性能有不利影响,这就是建议为endResponse参数传递false的原因。有关更多信息,请参阅End方法。
我通常在我的所有页面继承的基类中从OnPreInit调用以下内容。当然,你可以在每一页都这样做......但你现在不想这样做吗?
请注意,我为每个页面都有两个属性,以便我可以为每个页面指定SSL要求(RequiresSSL),同时我也可以覆盖并重定向检查是否需要(使用IgnoreRequiresSSL,这对于您错误页面这样的页面很有帮助重写并且不知道它们是否会被加密,但当然,您可以删除这些以进行简单的设置。
framework documentation
在我看来,以下是最好的全方位方法。
三个原因
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
网站时,永久重定向会让你烦恼)。https
只需将以下内容添加到项目“Web.config”中的https
部分即可。
<system.webServer>
您还可以使用新的UriBuilder:
<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>
C#
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
这是我的解决方案:
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);
}
其中// 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();
}
是您的HTTPS主机名。它301重定向,在某些情况下可能是适当的响应。
我还建议使用tvalfonsso的解决方案,但如果你有一些网址重写(RawUrl与Url不同),可以进行一些小修改
Settings.CanonicalDomain
我能够执行https重定向的方法之一是:
在应用程序池中,我的应用程序仅在端口443上运行,因此没有可能发生未加密的会话(除非加密方案是通过漏洞破解的......)。我在端口80上创建了另一个具有相同IP地址的应用程序,其中只包含一个带有以下代码的web.config文件
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);
}
免责声明 - 我参与了这个项目的开发
我建议使用<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpRedirect enabled="true" destination="https://yourWebsiteURL.com" />
</system.webServer>
它使您能够保护特定页面或使用正则表达式来定义匹配。它还会强制所有与Regex不匹配或直接指定的页面返回HTTP。
您可以通过NuGet:http://nuget.org/packages/SecurePages/安装它
文件在这里:Install-Package SecurePages
简单用法:
https://github.com/webadvanced/Secure-Page-manager-for-asp.net#secure-pages
要么
SecurePagesConfiguration.Urls.AddUrl("/cart");
在我的开发环境中,我喜欢有一个单独的发布目录,其中IIS安装了自签名证书,这与我的代码目录不同,没有我直接在Visual Studio内部调试的证书。在这种情况下,SecurePagesConfiguration.Urls.AddRegex(@"(.*)account", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
并不理想,因为它在开发环境的任何地方都不起作用,即使在带有cert的IIS目录中也是如此。我更喜欢这个:
!Request.IsLocal
if (!IsPostBack && !HttpContext.Current.IsDebuggingEnabled)
{
// do http->https and https->http redirection here
}
基于web.config中编译debug =“true / false”的值。我在我的代码目录中设置为true,当我需要在本地测试http和https重定向时,在我的发布目录中设置为false。
我添加HttpContext.Current.IsDebuggingEnabled
只是为了通过在不需要时跳过额外的ssl检查(稍微)更高效。