65.9K
CodeProject 正在变化。 阅读更多。
Home

自动从 HTTP 切换到 HTTPS

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.29/5 (4投票s)

2006年10月11日

CPOL

2分钟阅读

viewsIcon

65081

downloadIcon

509

实现了一种场景,您希望强制页面特定的 HTTP/HTTPS 渲染。

引言

您可能希望强制网站中的某些页面仅在安全协议下渲染。同样,为了减少服务器负载,您可能拒绝其他页面上的安全访问。

Yahoo! Mail 作为示例

如果您浏览到 http://mail.yahoo.com/,您将通过 HTTP 302 重定向到 https://login.yahoo.com/config/login_verify2?&.src=ym。登录后,您将通过脚本块重定向到非安全 URL:http://us.f348.mail.yahoo.com/ym/login?.rand=432ghtrtnrp1l

为什么使用两种不同的重定向方法?

当使用 HTTP 302 从非安全 URL(即 *http:* 协议)重定向到安全 URL(即 *https:* 协议)时,Internet Explorer 仅会在证书存在问题时才显示对话框。

但是,在相反的情况下(即使用 HTTP 302 从安全 URL 重定向到非安全 URL),Internet Explorer 始终会显示警告对话框。这很糟糕。幸运的是,事实证明,如果您使用脚本块执行相同的重定向,则不会显示警告。

实现

首先,我们定义一个自定义配置类,以便可以将我们的 URL 基本字符串放置到 *web.config* 中

using System;
using System.Configuration;
namespace AA.switchprotocol
{
    public class SwitchProtocolSection : ConfigurationSection
    {
        [ConfigurationProperty("urls", IsRequired = true)]
        public UrlsFormElement Urls
        {
            get { return (UrlsFormElement)base["urls"]; }
        }
    }
    public class UrlsFormElement : ConfigurationElement
    {
        [ConfigurationProperty("baseUrl", IsRequired = true)]
        public string BaseUrl
        {
            get { return (string)base["baseUrl"]; }
        }
        [ConfigurationProperty("baseSecureUrl", IsRequired = true)]
        public string BaseSecureUrl
        {
            get { return (string)base["baseSecureUrl"]; }
        }
    }
}

现在我们可以在 *web.config* 中定义我们的基本 URL 字符串

<?xml version="1.0"?>
<configuration>
   <configSections>
      <section 
         name="SwitchProtocol"
         type="AA.switchprotocol.SwitchProtocolSection, __code"/>
   </configSections>
   <SwitchProtocol>
      <urls baseUrl="https://" 
            baseSecureUrl="https://" />
   </SwitchProtocol>
   <system.web>
      <compilation debug="false"/>
   </system.web>
</configuration>

接下来,定义一个简单的配置设置访问器

using System;
using System.Web.Configuration;
namespace AA.switchprotocol
{
   public static class Globals
   {
      public readonly static SwitchProtocolSection Settings =
         (SwitchProtocolSection)WebConfigurationManager.
            GetSection("SwitchProtocol");
   }
}

实现一个带有自定义重定向逻辑的基本页面类

using System;
namespace AA.switchprotocol.UI
{
   public class BasePage : System.Web.UI.Page
   {
      protected override void OnLoad(EventArgs e)
      {
         string scheme = Request.Url.Scheme;
         if (_issecure)
         {
            if (scheme != "https")
            {
               Response.Redirect(
                  Globals.Settings.Urls.BaseSecureUrl +
                  Request.RawUrl);
            }
         }
         else
         {
            if (scheme != "http")
            {
               string to = Globals.Settings.Urls.BaseUrl + 
                              Server.UrlEncode(Request.RawUrl);
               Server.Transfer("~/Tranz.aspx?to=" + to);
            }
         }
         base.OnLoad(e);
      }
      private bool _issecure = false;
      protected bool IsSecure {
         get { return _issecure; }
         set{ _issecure = value; }
      }
   }
}

实现 *Tranz.aspx*,它负责脚本块重定向

<%@ Page Language="C#" Theme="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
   _to = Server.UrlDecode(Request.QueryString["to"]);
}
private string _to;
protected void js()
{
   Response.Write("window.location.replace(\"" + _to + "\");");
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<script type="text/javascript" language="JavaScript">
<!--
<% js(); %>
-->
</script>
<title></title></head><body></body>
</html>

实现一个基本页面,默认情况下为安全

using System;
namespace AA.switchprotocol.UI
{
   public class SecurePage : BasePage
   {
      protected override void OnLoad(EventArgs e)
      {
         IsSecure = true;
         base.OnLoad(e);
      }
   }
}

结论

如果您从 BasePage 派生您的页面,它将拦截安全请求并使用脚本块进行重定向。如果您从 SecurePage 派生,它将拦截非安全请求并使用 HTTP 302 重定向。这模仿了 Yahoo! Mail 的功能,并且适用于您只有少量页面必须安全,而其他页面不应安全的情况。

© . All rights reserved.