| ASP.NET 开发实例之博客系统(2)--用户管理 |
| 昊天 |
|
《软件报》2008年18期 邮发代号:61-74
在博客系统中,用户管理相关的功能主要涉及:用户注册、登录验证、密码找回、角色分配、参数配置等内容。从实现方式的角度分析,上述功能都是通过对数据库中用户相关数据表的读写完成的。问题是,在每个应用程序中这些功能的实现方法都是大同小异的,如果每次都要重复编写同样的代码,似乎不是一种好的解决思路。事实上,ASP.NET 2.0在设计上已经考虑到了上述情况,专门针对上述应用提供了一套完整的技术框架,而博客系统的用户管理相关功能正是在这套技术框架基础上构建的。
ASP.NET 2.0成员资格和角色管理功能概述
在ASP.NET 2.0中,针对日常应用程序中必须的身份验证和授权功能,专门新增了称之为成员资格功能和角色管理器的设计。其中,成员资格功能主要应用于登录用户的创建、维护和管理,而角色管理器则提供角色创建以及用户角色区分的功能。
ASP.NET 2.0的成员资格功能主要由Membership和MembershipUser两个类组成,其中,Membership的主要功能包括创建、删除、查找、验证用户信息以及返回用户列表等功能,而MembershipUser类的主要功能则用于执行修改用户密码、判断用户当前状态以及用户的附属信息,如最后一次登录时间等。在实际使用过程中,Membership和MembershipUser类通常是配合使用的,一般都是先通过Membership类的静态方法返回一个MembershipUser的实例对象,然后再使用MembershipUser类的属性和方法执行进一步的操作。
角色管理器主要用到的是Roles类,其主要操作包括:创建、删除角色,将用户加入某个角色,从角色中移除某个用户,验证用户的角色以及返回用户的角色信息等功能。在实际使用时,如果要获取某个登录用户的角色信息,除了使用Roles类的内置方法外,还可以通过HttpContext对象的User属性得到RolePrincipal对象,然后再使用RolePrincipal对象的GetRoles方法和IsInRoles方法得到用户的角色列表或判断用户是否归属某个特定的角色。
当使用成员资格和角色管理器功能维护用户信息时,ASP.NET 2.0默认情况下会将相关的数据保存到名为aspnetdb的数据库中,其中所有用到的数据表和存储过程可以通过aspnet_regsql(位于c:\Windows\Microsoft.NET\Framework\v2.0.50727\)这个命令行工具创建。假设我们希望在博客系统中使用ASP.NET 2.0提供的成员资格和角色管理器功能,同时将所有的数据都存储在blogdb数据库,而不是默认的aspnetdb,只要运行aspnet_regsql,然后在安装向导上选择“为应用程序服务配置SQL Server”,并将目标数据库选择为blogdb就可以了。
不过,在我们的博客系统中笔者并没有采用这种方法,而是单独创建了自己的用户表和角色表。那不是没法使用ASP.NET 2.0提供的成员资格和角色管理功能呢?相信很多读者看到这里都会提出这样的疑问。其实不然,考虑到应用场景的差异,ASP.NET 2.0不仅提供了默认的成员资格和角色管理功能,而且专门设计了扩展接口以便开发人员在统一的框架下开发自己的解决方案。这就是ASP.NET 2.0中的成员资格提供程序和角色提供程序。
自定义ASP.NET 2.0的成员资格和角色管理功能
在ASP.NET 2.0中,成员资格功能相关的类Membership和MembershipUser实际上都是调用SqlMembershipProvider的功能,而SqlMembershipProvider则是抽象类MembershipProvider的具体实现。与此相类似,角色管理功能相关的类Roles和RolePrincipal调用的是SqlRoleProvider的功能,而SqlRoleProvider则是抽象类RoleProvider的具体实现。也就是说,在ASP.NET 2.0中,抽象类MembershipProvider和RoleProvider确定了成员资格和角色管理的实现规范。如果在博客系统中既希望使用ASP.NET 2.0内置的成员资格和角色管理功能,又需要将数据保存到自定义结构的表中,那么我们需要做的就是在博客系统中创建抽象类和RoleProvider的自定义实现,然后用自定义实现的类替换掉SqlMembershipProvider和SqlRoleProvider就可以了。
要实现成员资格提供程序MembershipProvider,需要创建一个从抽象类MembershipProvider继承的类,然后实现按照SDK的规范,实现其中必须的方法和类。其中几个比较重要的方法包括:
Initialize方法:该方法的主要功能是从web.config文件中读取和MembershipProvider相关的配置信息,并设置提供程序关联属性的初始值;
ApplicationName 属性:这个属性主要用来指定跟成员资格关联的应用程序的名称。由于ASP.NET 2.0的成员服务允许多个应用程序同时使用,因此该属性是区分相关用户的主要依据。默认情况下,ApplicationName是和用户信息一起存储在数据库中的。
ValidateUser 方法:对用户信息的合法性进行验证;
GetNumberOfUsersOnline 方法:获取登录用户的在线人数;
ResetPassword 方法:重置用户密码;
除了提到的这些方法外,有关成员资格提供程序MembershipProvider的完整实现列表请参阅MSDN中的“实现成员资格提供程序”一节的内容。
在MembershipProvider规定的方法属性之外,我们还可以在此基础上扩展相应的属性和方法,以满足自己程序的需要。一旦在自定义成员资格程序中增加了自定义功能,我们就可以通过Membership的Provider属性调用自定义的方法了。也就是说,需要先将Membership的Provider属性值的类型转换成MembershipProvider的自定义实现,然后再调用扩展的自定义方法或属性。
和成员资格提供程序MembershipProvider类似,自定义的角色管理功能也只需要创建抽象类RoleProvider的自定义实现,然后依照规范实现必须的方法和属性就可以了。
有关角色提供程序RoleProvider的完整实现列表请参阅MSDN中的“实现角色提供程序”一节的内容。
配置自定义成员资格程序
要使自定义实现的提供程序发挥作用,还需要在web.config中进行相应的配置,替换掉默认的SqlMembershipProvider和SqlRoleProvider。
这项功能实现比较简单,只需要在web.config中添加以下配置参数即可。
……
其中最关键的部分就是将type属性的值设置为MembershipProvider和RoleProvider自定义实现类。
构建前台应用界面
完成上述步骤之后,接下来我们就可以进行前台页面的功能实现了。由于ASP.NET 2.0中新增的登录控件是构建在成员资格管理功能之上的,也就是说我们在实现自定义的成员资格提供程序之后,可以通过登录控件在不编写一行代码的前提下完成用户注册、登录验证、密码找回等功能了。下面就以用户注册为例,给大家介绍一下博客系统中的具体实现。
依照先前的数据库设计,在用户注册时需要提供注册名、密码、Email地址、安全问题及答案。与之相对应,需要在先前添加的blogMembershipProvider中设置以下属性:
RequiresQuestionAndAnswer = “true”, RequiresUniqueEmail = “true”
考虑到安全性,还需要设置以下两个属性,以确保用户输入密码的最小长度和复杂度:
minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0"
完成上述设置之后,接下来只需要在页面上放置一个CreateUserWizard控件就大功告成了。
当然,在实际应用中,在输入注册用户信息前一般会显示用户条款,因此还需要在CreateUserWizard控件智能标记上单击“添加/移除 WizardSteps”链接,然后在弹出窗口下新建一个向导步骤,并将改步骤移到最顶端。关闭设置窗口,在新增的“用户条款”向导页上放置一个TextBox,并将其Text属性设置为要显示的用户条款内容,下次注册用户时就会先显示用户条款了。
与之类似,利用自定义MembershipProvider实现结合登录系列控件即可完成其他的相关操作。
除了使用登录控件完成用户前台的操作外,涉及用户管理的后台操作,如调整用户的权限组,重置用户密码等操作就需要通过ASP.NET 2.0的服务器控件单独设计实现页面了。当然,这部分功能同样可以通过Membership、MembershipUser、Roles等成员资格类和角色类完成具体的功能实现。
以上涉及的功能实现都只需要调用ASP.NET 2.0的服务器控件或相关类即可完成,在此就不列举详细的实现代码,请大家自行参考附带的源码。
写在最后
与大家习惯的实现方式不同,本文提到的用户管理功能充分利用ASP.NET 2.0的新增功能,既保留了自定义的灵活性,又大大简化了开发的过程,而且实现的自定义提供程序还可以在多个应用程序之间共享。
有很多朋友在接触ASP.NET 2.0时,最开心的莫过于关注ASP.NET 中新增服务器控件的用法,却很少有人去关注控件背后真正的技术实现,这也是导致很多朋友学习ASP.NET留于皮毛的缘故。从全面掌握一门技术的角度出发,大家在接触到一个新的服务器控件时,一定要在掌握了用法之后,再进一步思考一下用法背后的技术原理。假以时日,技术水平一定能获得较大的提升。
|
|
文章检索
编程>热门文章
|