我应该何时在ASP.NET页面生命周期中为安全页面强制执行SSL?
我的意思是我应该在page_load中进行吗?还是OnInit?或其他一些功能?
我使用以下代码为某些页面强制执行SSL,但是我应该在哪里放置此代码?之前我将它放在OnInit函数中,但是这对ASP.NET向导不起作用。 我是否需要首先检查是否回发?
如果回发丢弃https,我的代码不应该强制执行吗?如果回发没有丢弃https,我的代码不应该停止重定向并转到向导的下一步吗?好像它一直在重定向。
if (!HttpContext.Current.Request.IsSecureConnection) {
HttpContext.Current.Response.Redirect(SiteNavigation.ResolveAbsoluteUrl(true, HttpContext.Current.Request.Url.PathAndQuery));
}
答案 0 :(得分:2)
你基本上有两种选择。
如果您希望所有经过身份验证的页面都在SSL下运行,则可以在表单身份验证上设置requireSSL =“true”属性。只需确保您的登录页面也在HTTPS上运行。
您也可以逐页设置。我发现这在继承自System.Web.UI.Page的“页面基础”类中很有效,并且所有页面都继承自(而不是System.Web.UI.Page)。
public class PageBase : System.Web.UI.Page
{
public bool RequiresSSL {get; set;}
string currentPage = Request.Url.ToString();
public PageBase()
{
Init += new EventHandler(PageBase_Init);
}
void PageBase_Init(object sender, EventArgs e)
{
if ((RequiresSSL) && (WebConfigurationManager.AppSettings["SSLavailable"] == "true"))
{
if (currentPage.ToLower().StartsWith("http://"))
{
redirectTo = "https://" + currentPage.Substring(7);
Response.Redirect(redirectTo);
}
}
else
{
if (currentPage.ToLower().StartsWith("https://"))
{
redirectTo = "http://" + currentPage.Substring(8);
Response.Redirect(redirectTo);
}
}
}
}
SSLavailable的AppSettings值允许您在没有SSL的测试模式下运行时关闭整个机制。
对于需要在SSL模式下运行的页面,他们需要做的就是设置RequiresSSL:
public partial class ChangePassword : PageBase
{
public ChangePassword()
{
PreInit += new EventHandler(ChangePassword_PreInit);
}
void ChangePassword_PreInit(object sender, EventArgs e)
{
RequiresSSL = true;
}
}
它非常顺畅,并且在安全页面之后转到的任何其他页面将自动切换回HTTP协议。
答案 1 :(得分:1)
我通常在OnPreLoad事件中执行此操作以强制使用SSL:
protected override void OnPreLoad(EventArgs e)
{
base.OnPreLoad(e);
String qs;
qs = Request.QueryString;
//// Force the page to be opened under SSL
if (!Request.IsSecureConnection)
{
if (qs != "")
{
qs = "?" + qs;
}
Response.Redirect("https://" +
Request.ServerVariables["SERVER_NAME"].ToString() +
Request.ServerVariables["PATH_INFO"].ToString() + qs);
}
}
如果要为所有页面强制使用SSL,则它可能非常适合HttpModule。我想出了以下内容:
using System;
using System.Web;
namespace CustomHttpModules
{
public class EnforceSSLModule : IHttpModule
{
public void Init(HttpApplication httpApp)
{
httpApp.PreRequestHandlerExecute += this.OnPreRequestHandlerExecute;
}
public void Dispose()
{
}
public void OnPreRequestHandlerExecute(object o, EventArgs e)
{
using (HttpApplication httpApp = (HttpApplication)o)
{
if (HttpContext.Current != null)
{
HttpContext ctx = HttpContext.Current;
String qs;
qs = ctx.Request.QueryString;
//// Force the page to be opened under SSL
if (ctx.Request.IsSecureConnection)
{
if (qs != "")
qs = "?" + qs;
ctx.Response.Redirect("https://" +
ctx.Request.ServerVariables["SERVER_NAME"].ToString() +
ctx.Request.ServerVariables["PATH_INFO"].ToString() + qs);
}
}
}
}
}
}
要在IIS5.1或IIS6中使用HttpModule,请在站点的bin文件夹中删除HttpModule的已编译程序集,并将以下内容添加到web.config的HttpModules部分:
<add type="CustomHttpModules.EnforceSSLModule, dllname" name="EnforceSSLModule" />
(其中 dllname 是没有扩展名的程序集文件的名称)