安全开关(Security Switch) 使各种asp.net网络应用程序可以自动切换页面请求/资源之间的HTTP和HTTPS协议而不需要在HTML中编写绝对url。
通过2.x以上版本的Security Switch(支持asp.net2以及更高版本.net),你可以很容易地在您的网站通过使用SSL证书来实现HTTPS访问。这是通过一个asp.net的模块(IHttpModule)来实现的
特别注意:
安全开关(Security Switch)这个项目的老版本的名字是SecureWebPageModule库。
配置
-------------
配置安全开关是一个简单的过程。打开web.config 文件为您的web应用程序,或网站,添加如下的配置(注意···线条所包含的地方就是配置)
<configuration>
...
<configSections>
...
<section name="securitySwitch" type="SecuritySwitch.Configuration.Settings, SecuritySwitch" />
</configSections>
<securitySwitch mode="RemoteOnly">
<paths>
<add path="~/Login.aspx" />
</paths>
</securitySwitch>
<system.web>
...
<httpModules>
...
<!-- for IIS <= 6.x, IIS 7.x + 经典模式, and Web Development Server (Cassini) -->
<add name="SecuritySwitch" type="SecuritySwitch.SecuritySwitchModule, SecuritySwitch" />
</httpModules>
...
</system.web>
...
<system.webServer>
...
<validation validateIntegratedModeConfiguration="false" />
<modules>
...
<!-- 如果是 IIS 7.x + 集成模式 -->
<add name="SecuritySwitch" type="SecuritySwitch.SecuritySwitchModule, SecuritySwitch" />
</modules>
...
</system.webServer>
...
</configuration>
首先,在configSections元素集合添加一个新的部分定义。这告诉ASP.net,它可以看到一个小节更低的命名,“securitySwitch”。接下来,添加上述的部分。securitySwitch的部分您将实际配置模块。
现在,我们设置模式为“RemoteOnly”和添加一个条目到路径为登录。aspx页面(更多关于这些设置将在下面展示)。最后,添加模块条目到 system.web/httpModules(IIS < = 6.x,IIS 7.x(启用经典模式 ),其他的Web开发服务器/例如Cassini)或者是 system.webServer/modules(IIS 7.x(启用集成模式),或两者兼而有之。上面的例子片段演示添加了在系统中添加了这两种不同的模块,并且添加了 system.webServer/validation元素,以防止IIS从抱怨条目添加到包含/ httpModules。
另一个许多人忘记的重要步骤,是在项目中包含SecuritySwitch的程序集。只需要复制SecuritySwitch的dll文件到你的网站的bin文件夹,或者在你的项目中,添加对SecuritySwitch的dll的引用即可 .
securitySwitch模块的配置是通过web.config。主要的元素本身有多个属性,但没有一个是必需的。以下节点声明是非常有效的,将启用模块并使用默认值。注意,必须要有路径元素和至少一个添加元素条目。
<securitySwitch>
<paths>
...
</paths>
</securitySwitch>
securitySwitch的元素可能有以下属性,这些属性可以设置为一个允许的值。定义如下
属性名称 | 中文翻译 | 数据类型 | 默认值 | 允许的值 |
baseInsecureUri | 基于不安全的URL | string | [null] | 任何有效的URI |
baseSecureUri | 基于安全的URL | string | [null] | 任何有效的URI |
bypassSecurityWarning | 绕开安全警告 | bool | false | true, false |
ignoreAjaxRequests | 忽略Ajax请求 | bool | false | true, false |
ignoreImages | 忽略图片 | bool | true | true, false |
ignoreStyleSheets | 忽略样式表 | bool | true | true, false |
ignoreSystemHandlers | 忽略系统处理器 | bool | true | true, false |
mode | 模式 | Mode | On | On, RemoteOnly, LocalOnly, Off |
offloadedSecurityHeaders | string | [null] | query string like name/value pairs | |
offloadedSecurityServerVariables | string | [null] | query string like name/value pairs | |
securityPort | 安全端口 | int? | [null] | port indicating secure connection |
当你没有一个SSL证书安装在相同的域名作为你的标准站点(通过HTTP访问),或者如果你的服务器设置为HTTPS通过非标准端口(不是443的端口),设置baseSecureUri为一个有效的URI。
设置baseSecureUri 将指示模块把那些需要从HTTP切换到HTTPS的需求,重定向到一个以baseSecureUri开始的URL。 例如,如果baseSecureUri是“https://secure.mysite.com”,刚好有一个请求是http://www.mysite.com/Login.aspx ( login.aspx已经被配置需要通过https安全访问),该模块将把访问者重定向到https://secure.mysite.com/Login.aspx。 类似地,如果baseSecureUri 是“https://secure.somehostingsite.com/mysite”,游客将被重定向到https://secure.somehostingsite.com/mysite/Login.aspx。
同样,当你为baseSecureUri提供了一个值,并且baseInsecureUri也设置为一个有效的URI。 那么当站点从HTTPS切换到HTTP时,该模块会将访问者带回到你的http标准站点。。基于前面的例子,如果 baseInsecureUri是“http://www.mysite.com”,访问者请求https://secure.somehostingsite.com/mysite/Info/ContactUs.aspx会被重定向到http://www.mysite.com/Info/ContactUs.aspx。
如果baseSecureUri或baseInsecureUri这2个值任何一个已经设置了,那么您必须把这两个值都设置掉。 因为该模块需要知道切换的时候,如何使用这2个基本URI来完成切换。
当你想尝试避免浏览器从HTTPS到HTTP切换时提示警告,那么需要将bypassSecurityWarning设置为true。 当服务器发出一个重定向请求,许多浏览器提醒游客将从HTTPS删除用户。这对浏览器来说未必是 一个糟糕的特性。然而,如果可能的话,一些网站所有者/开发人员希望避免这样的安全警告。当bypassSecurityWarning设置为ture,该模块将放弃"发布一个重定向请求"的这么一个惯例,而是将输出一个“refresh刷新”头,随后是一些JavaScript脚本来改变访问者的位置。一个refresh刷新标题不是一个标准HTTP标头。然而,很多浏览器都尊重它和“刷新”当前位置与指定的URL后一个超时。该模块设置 URL重定向到适当位置,并且超时时间为0(立刻执行)。此外,一个小的JavaScript块输出到浏览器作为备份。如果浏览器不尊敬刷新头,JS脚本将设置window's location 到适当的URL。
当将ignoreAjaxRequests设置为true时会忽略所有AJAX请求的模块,不管请求的路径。 当为true时,如果是通过AJAX来请求,这个设置将会覆盖任何匹配的路径的设置,。如果为false,模块将会像其他任何匹配的路径一样检验并处理请求。
ignoreImages在默认的情况下设置为true,将会指示SecuritySwith添加一些特殊的路径,这些路径将会忽略类似于“图像”文件夹和最常见的web图像文件的请求(请求文件与常见的web映像扩展,例如 .gif .jpg .png等
ignoreStyleSheets 在默认的情况下设置为true时,此模块添加特殊路径来忽略请求类似于“styles”或“stylesheets”文件夹和文件的.css后缀名的任何请求。
当ignoreSystemHandlers是true时(缺省值),该模块将自动添加一个特殊的路径,确保.axd请求在程序处理期间将被忽略处理。这是一个很大的方便,因为 asp.net 有足够充足的WebResource.axd处理程序可以使用。同样,当这个模块评估需要重定向请求时,Trace.axd和任何其他处理程序的.axd扩展将被忽略。这将避免浏览器提示混合安全警告。比如,当一个页面需要通过HTTPS协议才能访问,但是这个页面的某些资源需要通过不同的协议(比如HTTP)才能访问,那么这个混合安全警告就出现了。如果没有这个设置,当一个通过HTTPS协议的WebResource.axd 请求访问的时候,该模块将会发现,没有路径条目能匹配。因此,模块会将请求重定向到使用HTTP,导致混合安全警报。注意,你可以禁用这一设置和手动添加WebResource.axd 和任何其他你特别想要忽略的axd模块路径。
mode属性决定了在什么情况下模块评估请求。值为“On”允许所有的请求,而不管他们的起源。“RemoteOnly "将指示模块只考虑请求是由一个远程计算机发出的。如果一个请求是在实际的Web服务器(即127.0.0.1 localhost,等等),该模块将不会执行。同样,设置模式为”LocalOnly”时表示只有当一个请求是由Web服务器发出时才会执行。最后,“关”完全禁用模块。
使用offloadedSecurityHeaders指定请求头可能会从一个卸载安全设备(比如一个专用的SSL服务器/加速器;如ISA服务器等)出现。表明这是一个安全的连接。这个属性的值应该像一个查询字符串并且没有"?"领导。这个值类似于一个 键值对(如SSL = Yes)。如果有超过一个数据头模块则应该考虑,以一个&字符来界定每一对值(如 SSL = Yes & HTTPS = on & name = joey)
使用offloadedSecurityServerVariables指定服务器变量可能会从一个卸载安全设备(比如一个专用的SSL服务器/加速器;如ISA服务器等)出现,这表明是一个安全的连接。这个属性的值应该像查询字符串并且没有"?"领导,这个值类似于一个 键值对对(如HTTP_X_FORWARD_PROTOCOL=HTTPS)。如果有多个服务器变量模块则应该考虑,每一对键值对以一个&字符界定开 (例如 HTTP_X_FORWARD_PROTOCOL=HTTPS&SSL=on)。
使用securityPort来表示一个端口,必须匹配请求的端口为了保证模块是通过一个安全的连接来接收请求。
Paths路径
~~~~~
在安全开关的部分元素里面,有一个paths路径元素。路径元素是一组条目,告诉模块如何处理特定的请求。ASP。NET开发人员应该很熟悉添加路径条目。每个元素的路径集合是一个“添加”元素,以及属性。下面是一个例子,一些路径条目。
<securitySwitch>
<paths>
<add path="~/Info/Contact.aspx" matchType="Exact" />
<add path="~/Login.aspx" />
<add path="~/Manage" />
<add path="~/Admin(/|/[Dd]efault\.aspx)?$" matchType="Regex" ignoreCase="false" security="Insecure" />
<add path="~/Admin/" />
<add path="~/Media/" security="Ignore" />
<add path="~/Cms/Default\.aspx\?([a-zA-Z0-9\-%_= ]+&)*pageId=2(&[a-zA-Z0-9\-%_= ]+)*$" matchType="Regex" />
</paths>
</securitySwitch>
第一个条目将确保所有 访问Info文件夹下的aspx页面将会通过https访问。matchType的是“Exact”,意味着只有当一个准确的请求这条路径才会匹配。换句话说,如果有任何的尾巴,查询字符串,或书签包括在请求时,它将不会被重定向(例如/Info/Contact.aspx?ref=email, /Info/Contact.aspx#form这样的都不会被https)
接下来的两个(网页~/login.aspx和所有路径包含~/manage开头的,可能是manage文件夹,也有可能是manageNews.aspx这样的网页)将会通过https进行安全请求。因为没有指定matchType,那么默认的值是“StartsWith”。这个可以更好的为这两个进行工作,因为通常登录页面login.aspx的网址后面都会有一个查询字符串(例如你是从一个页面被直接跳转到登陆页 /login.aspx?ReturnUrl=manage.aspx) 。同样,任何在/manage文件夹也是安全的。而且,网页 /ManagementNews.aspx也将是安全的,因为这个网页的请求包含 /manage
第四和第五项都是关于 /Admin目录。第五个条目确保任何请求到 /Admin子目录都是通过https来安全访问的。并且,第四个条目的优先级要高于第五条,因为它是先列出的。它将security(安全)属性设置为insecure(不安全的),那么表示模块通过http这种不安全的方式来访问 /Admin目录默认的页面。它的matchType设置为“Regex”,也就是用正则表达式来匹配出一个默认的页面(例如 /Admin 或者是 /Admin/ 或者是/Admin/default.aspx)。同时,ignoreCase(忽略大小写)属性被设为false(也就是不忽略大小写,也就是大小写代表不同含义)来证明一个观点; /Admin/Default.aspx 和 /Admin/default.aspx 是两个不同的请求(两个default的d字母大小写不一样)。 因为我们在正则里面写了[De],所以正则都会给我们进行匹配(也就是Default或者是default都可以,因为我们写了 [De])。如果我们省略 ignoreCase属性,或者将它设置为true(缺省值),正则表达式就可以简单的重写成 “~ /Admin(/|/Default\.aspx)?$”,这个时候就不用管default是大小写了,此时都会被匹配。
第六个条目将迫使模块忽略任何对Media文件夹的访问。这一点很重要,如果你运行的是一个网站在IIS 7.x的集成模式或者如果你有一个通配符处理程序设置IIS处理所有请求都通过ASP.net的管道。那么在这些情况下,使用 /Media/Images/Title.jpg的页面将使用相同的协议。如果排除一个页面通过HTTPS引用图像,图像请求将被重定向到HTTP的模块;导致混合安全警告在浏览器。
最后的条目,当请求/Cms/Default.aspx页面时,使用正则表达式来匹配特定的查询字符串值。 如果一个不安全的请求(即http协议)来访问 /Cms/default.aspx?pageId = 2,它将被重定向到Https以确保它是安全的访问。该条目甚至可以,只要当查询字符串中任何包含pageId = 2这个参数,他就会匹配去用Https。它可以是第一个参数,唯一的参数,或第三个参数(例如 /Cms/default.aspx?cache=On&pageId = 2 &author =joey)。
最后,如果没有路径条目匹配一个请求时,该模块将确保它不安全地访问(也就是说,如果没有匹配到Https,那么就通过HTTP来访问)。这可以防止“陷在HTTPS”。即,访问该网站通过HTTPS和继续通过HTTPS请求的资源。这样的行为将导致更多的CPU使用率在服务器(SSL需要更多一点的处理加密)和更多的带宽消耗(加密的数据本身是大于原始数据)。要么最终可能会花费你或你的客户可能更大一点的托管账单!
注意你的路径排序,顺序是很重要。在上面的示例中,条目四,五是下令专门来获得期望的结果。如果第四个条目(将security(安全)属性设置为了“不安全”)的顺序在第五个条目的下面,那么第四个模块永远不会运行。该模块过程中的条目的顺序规定他们,从上到下,一旦发现一个匹配的条目,就作用于它。事实上,将security属性设置为“不安全”唯一的原因是需要覆盖更一般的下面的条目。在上面的例子中,任何在 /Admin目录下的文件都会通过Https来安全访问,如果没有第四个条目覆盖默认页面的这种行为的话。(第四个条目设置 /Admin文件夹下的default.aspx可以通过http这种不安全的协议来访问)
智能感知和 安全开关( securitySwitch)节点模式
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
当在web.config文件编辑securitySwitch节点的时候如果需要启用智能感知,那么我们在解决方案里面添加一个xmlns属性小节,包括提供的模式文件。下面是一个示例的部分与必要的属性。
<securitySwitch xmlns="http://SecuritySwitch-v4.xsd" ...>
<paths>
...
</paths>
</securitySwitch>
一定要在您的解决方案包括SecuritySwitch-v4.xsd文件(就是在项目上,右键,添加现有项,选择SecuritySwitch-v4.xsd文件即可),或给VS来安装模式文件。如果Visual Studio在您的解决方案里并不自动检测模式文件,你可以将它添加到模式属性在Properties窗口,而 web.config文件是开放的。安装模式文件,Visual Studi会用到所有项目中,复制 xsd文件到适当的目录中,如下所示([版本)表明你安装到的Visual Studio版本)。
* 32位操作系统: %ProgramFiles%\Microsoft Visual Studio [version]\Xml\Schemas
* 64位操作系统: %ProgramFiles(x86)%\Microsoft Visual Studio [version]\Xml\Schemas
请求的动态评估
------------------------------
可能有时您不能配置需要Https保护的路径,因为您的应用程序生成的url /路径动态。特别是内容管理系统(CMS)。在这些情况下,你可以从配置部分省略paths元素,并提供一个事件处理程序模块的 EvaluateRequest事件. 为此,在你的网站添加一个Global.asax文件命名的全局事件处理程序, “SecuritySwitch_EvaluateRequest”以及以下签名
protected void SecuritySwitch_EvaluateRequest(object sender, EvaluateRequestEventArgs e)
{
// TODO: 基于当前的请求更新 e.ExpectedSecurity
}
设置事件参数的ExpectedSecurity的安全值, 那么模块的请求将优先使用它,而不是试图通过路径的配置而找出如何请求。
额外的资源
--------------------
* 原文的代码项目
http://www.codeproject.com/KB/web=security/WebPageSecurity_v2.aspx
* 维基百科上的 传输层安全协议(TLS)和安全套接字层(SSL)
http://en.wikipedia.org/wiki/Transport_Layer_Security
* 提示/技巧:启用SSL在IIS 7.0使用自签名证书(感觉有点像是自己做个证书,自己玩)
http://weblogs.asp.net/scottgu/archive/2007/04/06/tip-trick-enabling-ssl-on-iis7-using-self-signed-certificates.aspx
* 如何在IIS 7设置SSL
http://learn.iis.net/page.aspx/144/how-to-set-up-ssl-on-iis-7/
小提示:<securitySwitch mode="On"> mode属性决定了在什么情况下使用模块评估请求。
这里的mode主要有以下4种选择情况,分别是 On(默认),RemoteOnly,LocalOnly,Off
On 使模块的所有请求,不管他们的起源,来自各个方向的请求都使用SSL。
RemoteOnly 将指示模块只考虑请求是由一个远程计算机。如果一个请求是在实际的Web服务器(即127.0.0.1 localhost,等等),该模块将不会行动。
LocalOnly 表示模块在本地调试时使用。
Off 完全禁用模块。表示SSL不可用。
小提示:axd 一般是ASP.NET网站程序里的一个HttpHandler
其实扩展名为ashx与为axd基本上是一样的,都是用于写web handler,可以通过它来调用IHttpHandler类,它免去了普通.aspx页面的控件解析以及页面处理的过程。
唯一不同的地方是:axd扩展名的必须要在web.config中的<httpHandlers>中进行注册,而ashx直接在项目中当成aspx那样添加使用即可。
trace.axd 是微软的一个项目。 配置 ASP.NET 代码,跟踪服务以控制如何收集、存储和显示跟踪结果。
一些嵌入式资源默认就是用WebResource.axd获取