ASP.NET 2.0的新增服务、控件与功能
角色管理器
如果不支持基于角色的安全性,那么成员身份服务和登录控件将是不完善的。在ASP.NET 1.x中,要将窗体身份验证与角色结合起来,需要编写代码以将角色信息映射到各个传入的请求。ASP.NET 2.0中新的角色管理器(它可以与成员身份服务配合使用,也可以不与其配合使用)取消了对此类代码的需求,并且简化了基于角色授予用户访问各种资源权限的任务。
角色管理是基于提供程序的,它通过Web.config启用。角色管理器通过新的Roles类来公开API,该类公开了名为 CreateRole、DeleteRole和AddUserToRole等的方法。值得注意的是,您或许永远不需要调用这些方法,因为 Webadmin.axd完全能够创建角色、将用户分配给角色以及完成其他任务。一旦启用,基于角色的安全性就能够使用所提供的角色信息以及 Web.config文件中的URL身份验证指令来工作—这与ASP.NET 1.x中您已经熟悉的URL身份验证相同。
既然您已经熟悉了成员身份服务、登录控件以及ASP.NET角色管理器,那么您或许希望看到同时使用这三者的示例。本文可下载的代码示例包含一个两页的应用程序,它演示了Visual Studio 2005样式的窗体身份验证。要部署该应用程序并对其进行测试,请首先将PublicPage.aspx、LoginPage.aspx和 Web.config复制到Web服务器的某个虚拟目录中。在该虚拟目录中创建一个名为Secure的子目录,然后将 ProtectedPage.aspx和其他Web.config文件复制到该子目录中。
启动Webadmin.axd,并且将站点配置为使用窗体身份验证,将成员身份和角色服务配置为使用您选择的提供程序。同时,还要创建名为Bob和Alice的用户以及名为Manager和 Developer的角色。将Bob指定为Manager角色,将Alice指定为Developer角色。(我不会列出所有步骤,因为在您使用任一方法阅读本文之前,它们很可能会改变。幸运的是,Webadmin.axd相当直观,并且它具有向导,可以引导您完成设置过程。)
接下来,在浏览器中激活PublicPage.aspx,并单击“View Secret Message”按钮以查看ProtectedPage.aspx。ASP.NET会将您重定向到LoginPage.aspx,该页面使用Login控件来请求用户名和密码。使用Bob的用户名和密码登录。ProtectedPage.aspx应该显示在浏览器窗口中,因为Bob是Manager,并且可以通过Secure目录中的Web.config文件将访问权授予经理。请注意LoginName控件显示的用户名以及LoginStatus控件显示的“Log out”链接。最后,关闭浏览器,然后重新打开它并重新激活PublicPage.aspx。单击“View Secret Message”并以Alice的身份登录。这一次,您将无法到达ProtectedPage.aspx,因为Alice不是经理。
我使用了一个类似的应用程序来讲述ASP.NET 1.x中的窗体身份验证,但1.x版本要求编写非常多的代码。2.0版本因其简洁而不同寻常,尤其是没有任何用于验证在登录窗体中键入的凭据、或者将用户名映射到角色的代码。如果您仍然不相信,请尝试用ASP.NET 1.x实现同一应用程序!此外,请确保检验Webadmin.axd对Web.config所作的更改。除了其他内容以外,您还应该看到一个启用角色 Manager并且可能会指定角色管理提供程序的元素。
您可能很想知道角色Manager是否经过了到数据库(在其中,角色被存储到每个请求中)的往返行程。值得庆幸的是,答案是“否”。它将角色编码到Cookie中,并且为了保密而将它们加密。如果一个用户对应了众多的角色(这种情况不太可能发生),以至于无法将这些角色编码到一个Cookie中,则该Cookie将包含一个最近使用角色的列表,并且仅在迫不得已时才查询数据库。
个性化
另一个新增的服务是个性化,它提供了一种现成的解决方案,用于解决存储站点用户的个性化设置问题。目前,此类设置通常存储在Cookie、后端数据库或这两者中。无论这些设置存储在何处,ASP.NET 1.x都不能提供什么帮助。这需要由您来设置和管理后端数据存储,以及使用经过身份验证的用户名、Cookie或其他某种机制来关联个性化数据。
ASP.NET 2.0个性化服务使得存储各个用户的设置以及随意检索这些设置变得非常容易。该服务基于用户配置文件—您可以使用新的元素在Web.config中予以定义。下面的代码节选自Web.config:
<profile>
<properties>
<add />
<add Type="System.DateTime" />
<add Type="System.Int32" defaultValue="0" />
</properties>
</profile>
它定义了一个包含三个属性的配置文件:一个名为Theme的字符串,一个名为Birthday的DateTime值,以及一个名为LoginCount的整数。后面这个属性被赋予默认值0。
在运行时,您可以使用页面的Profile属性(该属性引用包含该配置文件中定义的属性的动态编译类的实例)来访问当前用户的这些属性。例如,下列语句可从当前用户的配置文件中读取属性值:
string theme = Profile.Theme;
DateTime birthday = Profile.Birthday;
int logins = Profile.LoginCount;
还可以将值赋予配置文件属性:
Profile.Theme = "SmokeAndGlass";
Profile.Birthday = new DateTime (1959, 9, 30);
Profile.LoginCount = Profile.LoginCount + 1;
个性化服务的一个明显优势是强类型化。另一个优势在于个性化数据是按需读写的。请将此与会话状态(无论是否使用,都会将其加载并保存到每个请求中)进行对比。但是,个性化服务的最大优势可能在于您不必显式地将数据存储在任何位置;系统会替您完成该工作,并且它会永久性地存储数据,以便数据在您需要时随时可用。配置文件不会像会话那样超时。
那么,个性化数据存储在哪里呢?这要依具体情况而定。个性化服务基于提供程序,因此您可以将其配置为使用任何可用的提供程序。ASP.NET 2.0将至少附带两个个性化提供程序:一个用于Access,另一个用于SQL Server。如果您不另行指定,则个性化服务将使用Access提供程序,默认情况下,该提供程序会将个性化数据存储在本地Data\ AspNetDB.mdb中。您可以通过修改Web.config(手动或使用Webadmin.axd)来改用SQL Server数据库。如果您不希望将个性化数据存储在Access数据库或SQL Server数据库中,则可以编写自己的提供程序。
默认情况下,ASP.NET使用经过身份验证的用户名作为所存储的个性化数据的键,但您也可以将其配置为支持匿名用户。首先,通过将以下语句添加到Web.config中来启用匿名标识:
<anonymousIdentification enabled="true" />
然后,将allowAnonymous="true"添加到您要为匿名用户存储的配置文件属性中:
<name="Theme" allowAnonymous="true" />
现在,Theme属性可以作为个性化设置使用,而无论站点的调用方是否经过了身份验证。
默认情况下,匿名标识使用Cookie来标识回返用户。由支持的属性可以用各种方式来配置这些Cookie。例如,您可以指定Cookie名称,并指明是否应该将该Cookie的内容加密。您还可以将个性化服务配置为使用无Cookie的匿名标识,因此它将依靠URL Munging来标识回返用户。甚至还存在一个自动检测选项:如果请求浏览器支持Cookie,则使用Cookie;如果不支持,则使用URL Munging。
要查看个性化的工作方式,请运行本文随附的下载资料中的Personalize.aspx示例。它会让站点的每个访问者选择一个主题,然后记录该主题,并且每当该访问者返回时都将应用该主题。请注意,该主题是在页面的PreInit事件(它是一个新事件,它的激发时间甚至早于Init)中以编程方式应用于该页面的。
在您运行该示例之前,需要启用匿名标识,并定义一个包含名为Theme的字符串属性的配置文件。以下代码行显示了执行上述两项任务的Web.config文件:
<configuration>
<system.web>
<anonymousIdentification enabled="true" />
<profile>
<properties>
<property allowAnonymous="true" />
</properties>
</profile>
</system.web>
</configuration>
SQL缓存依赖性
ASP.NET 1.x中令人遗憾地缺少的另一项功能是数据库缓存依赖性。可以将ASP.NET应用程序缓存中放置的项目与其他缓存项目联系起来,或者与文件系统中的对象联系起来,但不能与数据库实体联系起来。ASP.NET 2.0通过引入SQL缓存依赖性来纠正这一由于疏忽而造成的错误。
SQL缓存依赖性由新的SQLCacheDependency类的实例表示。它们的用法非常简单。下面的语句将一个名为ds的数据集插入到应用程序缓存中,并且在该数据集和Northwind数据库的Products表之间创建依赖性:
Cache.Insert ("ProductsDataSet", ds,new SqlCacheDependency ("Northwind", "Products");
如果Products表的内容改变,则ASP.NET会自动删除该数据集。
SQL缓存依赖性还可以与ASP.NET输出缓存配合使用。下面的指令指示ASP.NET缓存来自包含页面的输出,直至Products表的内容改变或者满60秒为止(满足任一条件即可):
<%@ OutputCache Duration="60" VaryByParam="None"
SqlDependency="Northwind:Products"
%>
SQL缓存依赖性适用于SQL Server 7.0、SQL Server 2000和即将问世的SQL Server 2005。对于SQL Server 2005,无需进行任何准备;但必须将SQL Server 7.0和SQL Server 2000数据库配置为支持SQL缓存依赖性。准备工作涉及到创建数据库触发器,以及创建一个特殊的表,以供ASP.NET在确定是否已经发生更改时参考。该表由一个后台线程使用可配置的轮询间隔(默认为5秒钟)来定期轮询。在SQL Server 2005中,要检测更改,既不需要特殊的表,也不需要轮询。此外,SQL Server 2005缓存依赖性可以在行级应用,而SQL Server 7.0和SQL Server 2000缓存依赖性在表级工作。您可以使用Aspnet_regsqlcache.exe工具或Webadmin.axd来准备数据库,以使其支持SQL 缓存依赖性。
1