八、更加具体的保护措施
我们的目标是,让授权用户能够浏览一个包含了已经购买的软件的页面,并且通过单击其中的链接就可以下载特定的商品。列出产品时,可以使用表结构,但是如何来保护链接呢? 之前我们介绍的方法只是防止匿名用户下载压缩文件,但是现在我们要防止授权用户直接浏览压缩文件。为此,我们需要编写一个定制的处理程序。
定制的HTTP处理程序是实现了IHttpHandler接口的类。这个接口定义了一个称为ProcessRequest的方法,以及一个Boolean类型的名为IsReusable的属性。该属性决定了其它请求是否能够利用同一个处理程序,所以这里简单返回一个真值。这个方法将会收到一个HttpContext类型的参数。这变量为我们提供了访问该请求整个上下文的权限,包括请求中的信息和订制另一个方向上的请求的方法。
现在,我们要创建一个称为FileDenialHandler的处理程序,它的作用是停止一个请求,并将用户重定向到一个页面来通知他们访问被拒绝。当这个处理程序取得该请求的时候,就会调用ProcessRequest方法并且执行重定向。
{
context.Response.Redirect(
"~/Downloads/Files/AccessDenied.aspx");
}
如您所见,这个页面位于根目录的Downloads/Files文件夹中,完整的FileDenialHandler.cs处理程序如下所示:
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
namespace DotNetDude.Web.UI
{
public class FileDenialHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.Redirect(
"~/Downloads/Files/AccessDenied.aspx");
}
public bool IsReusable
{
get
{
return true;
}
}
}
}
现在,这个FileDenialHandler类什么也没做,所以必须将其写入站点。为了这样,我们将其放入web.config文件的
文件web.config列出了配置部分的所有特殊处理程序,并为其规定了相应的信息,包括实例化这个处理程序的谓词,匹配要让这个处理程序来处理的文件的通配符路径,以及用于该定制的处理程序的类型定义。在这个例子中,添加的配置部分如下所示:
<add verb="*" path="*.zip"
type="DotNetDude.Web.UI.
FileProtectionHandler,
DotNetDude.HttpHandlers"/>
</httpHandlers>
参数type是标准的.NET完全限定名写法,并通过逗号组合了一个组件程序集名称。在实际的Web项目中编写处理程序的时候,可以省去程序集名称。
现在这个条目将所有的压缩文件请求转发给新的处理程序,因此立即将请求重定向到“Access Denied”页面。即使在本例中跳过该IIS条目,它仍然会照常工作,因为这些事情都交由我们的处理程序了。 然而,我们想要的效果是让系统在判定匿名用户访问非法的ZIP 文件之前,首先把他们导航至登录页面。
如果检查框架目录中的web.config文件,就会发现一列处理常见文件扩展名用于ASP.NET的处理程序。定义这个文件中的
所以您可能问,无什么不只用Microsoft提供的处理程序来处理压缩文件呢? 答案是,当然可以用,不过我们需要自己的“access denied”页面,这样通过定制我们自己的拒绝页面,就能跟我们的网站风格保持一致。在某些情况下,我们还想为用户提供更多的信息,甚至向管理员发送“未经授权的尝试”类电子邮件。
这里只是防止下载所有的压缩文件,但是我们实际想要做的是什么?对了,我们要取得从我们站点上文件下载方式的绝对控制权。我们不想让用户直接浏览压缩文件。通过表结构,我们可建立一个项目、用户列表,以及每个用户购买产品的关系表。因此如果我们有一个用户名和一个产品序列号,就可以通过一个简单的数据库查询来判断这个用户是否购买了这个产品。同时,我们还想让用户只需单击一个链接就能启动查询并确定是否被允许下载文件。 这些功能的确非常令人向往。