动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
电脑书籍下载:程序设计书籍 | 数据库教程书籍 | 平面与多媒体书籍 | 网络通讯书籍 | 系统管理书籍 | 网络安全书籍 | 认证考试书籍
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > ASP.NET技巧
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ ASP.NET技巧 ]的信息



本月文章推荐
.利用.net反射动态调用指定程序集.
.ASP.NET热点问题解答14个.
.用.net静态变量取代Application,.
.分享个极好的无刷新二级联动下拉.
.ASP.NET 2.0 正式版中无刷新页面.
.Windows 2003 Server 中DOTNET程.
.远程抓取GOOGLE的自动翻译结果.
.Access数据库在asp.net程序中相对.
.ASP.net 2.0下应用程序离线信息.
.ASP.NET通过DSO访问分析服务器的.
.字符自动截取问题.
.权限树中Checkbox的操作[Asp.Net.
.虚拟主机上asp.net运行权限不足问.
.巧用VS2005解决VS2005网站发布不.
.Asp.Net2.0中实现多任务异步页的.
.ASP.NET设计网络硬盘之两重要类.
.对ASP.NET 2.0下面的新控件的困惑.
.ASP.Net防止刷新自动触发事件的解.
.如何用在ASP.NET中写入事件日志.
."拒绝访问(Access Denied)"错误的.

ASP.NET 2.0 Membership

发表日期:2006-8-28 |


摘要:asp.net 2.0的Membership组件提供了一组非常简单易用的接口供开发者进行用户管理,用户验证。本文将它对它的实现原理进行简单的分析,介绍如何正确的使用,以及如何对它进扩展。

一、MembershipProvider抽象类

在很多情况下,在使用Membership的时候我们并不会直接使用到这个类。在MembershipProvider类定义的都是一些抽象方法和抽象属性,就是这些方法和属性构成了Membership接口的基本规范,而且在.NET 框架内部使用Membership的功能都是通过这个类型调用的。继承类通过实现这些接口来提供不用环境下的用户管理功能,并且对Membership框架本身并没有影响,下面来看看MembershipProvider原形定义:


public abstract class MembershipProvider : ProviderBase

...{

      // Events

      public event MembershipValidatePasswordEventHandler ValidatingPassword;

 

      // Methods

      protected MembershipProvider();

      public abstract bool ChangePassword(string username, string oldPassword, string newPassword);

      public abstract bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer);

      public abstract MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status);

      protected virtual byte[] DecryptPassword(byte[] encodedPassword);

      public abstract bool DeleteUser(string username, bool deleteAllRelatedData);

      internal string EncodePassword(string pass, int passwordFormat, string salt);

      protected virtual byte[] EncryptPassword(byte[] password);

      public abstract MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords);

      public abstract MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords);

      internal string GenerateSalt();

      public abstract MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords);

      public abstract int GetNumberOfUsersOnline();

      public abstract string GetPassword(string username, string answer);

      public abstract MembershipUser GetUser(object providerUserKey, bool userIsOnline);

      public abstract MembershipUser GetUser(string username, bool userIsOnline);

      internal MembershipUser GetUser(string username, bool userIsOnline, bool throwOnError);

      public abstract string GetUserNameByEmail(string email);

      protected virtual void OnValidatingPassword(ValidatePasswordEventArgs e);

      public abstract string ResetPassword(string username, string answer);

      internal string UnEncodePassword(string pass, int passwordFormat);

      public abstract bool UnlockUser(string userName);

      public abstract void UpdateUser(MembershipUser user);

      public abstract bool ValidateUser(string username, string password);

 

      // Properties

      public abstract string ApplicationName ...{ get; set; }

      public abstract bool EnablePasswordReset ...{ get; }

      public abstract bool EnablePasswordRetrieval ...{ get; }

      public abstract int MaxInvalidPasswordAttempts ...{ get; }

      public abstract int MinRequiredNonAlphanumericCharacters ...{ get; }

      public abstract int MinRequiredPasswordLength ...{ get; }

      public abstract int PasswordAttemptWindow ...{ get; }

      public abstract MembershipPasswordFormat PasswordFormat ...{ get; }

      public abstract string PasswordStrengthRegularExpression ...{ get; }

      public abstract bool RequiresQuestionAndAnswer ...{ get; }

      public abstract bool RequiresUniqueEmail ...{ get; }

 

      // Fields

      private MembershipValidatePasswordEventHandler _EventHandler;

      private const int SALT_SIZE_IN_BYTES = 0x10;

}

 


其中修饰符为internal是几个方法是密码的辅助方法,用于加密,解密和验证密码。但这边的设计似乎有一些问题,将这些方法定义为internal范围好像有点不妥,将这些方法定义在基类中,就是为了能够被复用,但是从效果上来看,不是这样的,因为internal的成员只允许在本程序集内被使用(正常情况下,不包括反射等其它方法),这就是说我们自己扩展的MembershipProvider是无法使用到这些方法的。而且从目前应用范围来看,目前这些方法也只有在SqlMembershipProvider中被使用到,所以我认为应该将这些方法修饰符修改为protected。

二、Membership 静态类

上面提到过,一般情况下我们都不会直接去使用到MembershipProvider抽象,因为这涉及到如何去实例化真正的Membership服务类的问题,涉及到配置和实例化对象的问题一般都是比较棘手的问题,对初学者来说,想要掌握也不是那么容易。那在.NET框架中就是通过Membership(Static Class)这个静态类来屏蔽掉这一层的复杂关系。Membership(Static Class)除了使用者屏蔽读配置文件,初始对象等一些基本工作外,还有一个重要的作用就是重载所有的MembershipProvider所以有API,甚至为了让用户更加方便的使用,将这些方法重载为静态方法,并且提供了MembershipProvider基本API基础上更加丰富的重载实现供使用者调用。这就直接支持了不管是在UI层,还是其它的各个工程,只需要引用System.Web.Security命名空间,就可以不用关心任何细节的享受到Membership给我们提供的各种便利。下面来看看Membership(Static Class)的原型定义:(利用Lutz Roder’s .NET Reflector可以查看它的所有实现。)

public static class Membership

...{

      // Events

      public static  event MembershipValidatePasswordEventHandler ValidatingPassword;

 

      // Methods

      static Membership();

      public static MembershipUser CreateUser(string username, string password);

      public static MembershipUser CreateUser(string username, string password, string email);

      public static MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, out MembershipCreateStatus status);

      public static MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status);

      public static bool DeleteUser(string username);

      public static bool DeleteUser(string username, bool deleteAllRelatedData);

      public static MembershipUserCollection FindUsersByEmail(string emailToMatch);

      public static MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords);

      public static MembershipUserCollection FindUsersByName(string usernameToMatch);

      public static MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords);

      public static string GeneratePassword(int length, int numberOfNonAlphanumericCharacters);

      public static MembershipUserCollection GetAllUsers();

      public static MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords);

      private static string GetCurrentUserName();

      public static int GetNumberOfUsersOnline();

      public static MembershipUser GetUser();

      public static MembershipUser GetUser(bool userIsOnline);

      public static MembershipUser GetUser(object providerUserKey);

      public static MembershipUser GetUser(string username);

      public static MembershipUser GetUser(object providerUserKey, bool userIsOnline);

      public static MembershipUser GetUser(string username, bool userIsOnline);

      public static string GetUserNameByEmail(string emailToMatch);

      private static void Initialize();

      public static void UpdateUser(MembershipUser user);

      public static bool ValidateUser(string username, string password);

 

      // Properties

      public static string ApplicationName ...{ get; set; }

      public static bool EnablePasswordReset ...{ get; }

      public static bool EnablePasswordRetrieval ...{ get; }

      public static string HashAlgorithmType ...{ get; }

      internal static bool IsHashAlgorithmFromMembershipConfig ...{ get; }

      public static int MaxInvalidPasswordAttempts ...{ get; }

      public static int MinRequiredNonAlphanumericCharacters ...{ get; }

      public static int MinRequiredPasswordLength ...{ get; }

      public static int PasswordAttemptWindow ...{ get; }

      public static string PasswordStrengthRegularExpression ...{ get; }

      public static MembershipProvider Provider ...{ get; }

      public static MembershipProviderCollection Providers ...{ get; }

      public static bool RequiresQuestionAndAnswer ...{ get; }

      public static int UserIsOnlineTimeWindow ...{ get; }

 

      // Fields

      private static char[] punctuations;

      private static bool s_HashAlgorithmFromConfig;

      private static string s_HashAlgorithmType;

      private static bool s_Initialized;

      private static Exception s_InitializeException;

      private static object s_lock;

      private static MembershipProvider s_Provider;

      private static MembershipProviderCollection s_Providers;

      private static int s_UserIsOnlineTimeWindow;

}

 

说到这里,就不得不多罗嗦两句。在看Membership(Static Class)实现代码的过程中,可以发现,每一个Membersip API重载都最后都是调用属性Provider的方法,这个属性的类型就是MembershipProvider类型,只有看到这里,你也许才会理解MembershipProvider的重要作用了吧。还有一个Providers属性,这个属性就是获得web.config中配置的所有的Membership提供服务类。它们都是静态属性,但是它们怎么去实例化的呢?就是通过调用Membership. Initialize()这个方法,在每次调用这两个属性的时候,都会调用这个方法去判断是否已初始化了Membership提供服务类了,如果没有则去调用配置服务类,读取配置内容,从而进行初始化。到此你可能也就不难理解了,为什么我们使用那么简单了!

三、SqlMembershipProvider介绍和使用配置

OK,通过上面的介绍应该基本可以了解Membership的整体结构了吧?(如何还没有,可能是你没有打开Lutz Roder’s .NET Reflector去分析它的实现代码,或者是对抽象类的作用还没弄明白)。不管怎么样,我们最终的目的就是要学会如何去使用。

在这之前,我先要介绍一下,在.NET 框架中提供的两个MembershipProvider实现类:ActiveDirectoryMembershipProvider和SqlMembershipProvider(如何知道这两个类的?在MembershipProvider的Derived Types就可以看到所有的继承类了。)前者是提供基本活动目录下的用户管理(我也没有实践过),后者就是我们最经常使用到的基于SqlServer的用户管理实现。

到了介绍如何使用了,其实园子里已经有了这方面的文章((翻译)怎么在ASP.NET 2.0中使用Membership),我也不多费口舌了。但这边要告诉大家一个最直接的学习和参考使用的办法。在系统盘找到并打开machine.config,找到AspNetSqlMembershipProvider节点,看到没有,其实这个就是一个最基本的Membership配置了,只不过是还少了一个defaultProvider属性的指定,指定了这个属性后,你再使用Login控件,进行用户登录验证就无需使用任何代码了。不信你可以试试。(关于Forms验证,就不在这里多做介绍,可以参考相关资料。关于SqlMembershipProvider的更多属性的介绍可以参看MSDN)。

四、如何自定义MembershipProvider,现有其它的MembershipProvider资源

那么,我们如何去自定义一个MembershipProvider呢?其实如果你已经了解了Membership的结构后我相信对你来说已经不是一件很难的事了,但是考虑到要完整的写一个MembershipProvider还是有一定的工作量和难度的。对于我们来说,更多的地方可能是对现有的Provider进行扩展,如SqlMembershipProvider。那其实这是非常简单的,我们只需要继承自SqlMembershipProvider,(悄悄告诉你,在Initialize方法config参数中保存的就是Provider对应配置节的属性名和值)然后扩展和重写所需的方法就可以了。使用的时候,在Provider配置节中,将type的值改为你的类名就OK了。

最后,在市面上已经有好多不同环境的MembershipProvider了,如mysql,Oracle等。这里给出Mysql 的实现:http://www.codeproject.com/aspnet/mysqlmembershipprovider.asp ,更多不同的实现,相信你从google上找到更多的帮助。

好了,说多了,说了这么多希望能对不辞辛苦看完本篇blog的您有所帮助,谢谢 ^_*

上一篇:收藏一段小的.net下的验证码片段 人气:5783
下一篇:在Visual Studio 2005和ASP.NET 2.0中使用强类型数据存取 人气:5285
浏览全部ASP.NET 2.0的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-7-25 WikyBlog v1.7.0.1 多国语言版
2008-7-25 乐彼网上开店系统(56770 Eshop)
2008-7-25 赛特网站管理系统sitecms v3.6.0
2008-7-25 Modoer多功能点评系统 v1.0.1 Bu
2008-7-25 Shangducms Teamsuit! v1.1.0 开
2008-7-25 幻影动漫网视频系统(Ppdong) v1.
2008-7-25 acteecompany企业网站建设系统 v
2008-7-25 恒浪整合管理系统 ims v4.1 ACCE
2008-7-25 艺术图库系统 v1.0 beta
2008-7-19 UltraEdit 简体中文增强版 14.10
2008-7-19 CentOS 5.2 i386 LiveCD
2008-7-19 Snapture多功能相机 v1.4
2008-7-19 iAcces中文输入法 v1.0Build016
2008-7-19 Cookbook烹饪秘籍 v2.5
2008-7-19 苹果专用DVD转换工具 v1.1.59汉化
2008-7-19 Modem修复软件ZiPhone修改版04.0
2008-7-19 AgileMessenger即时通讯工具美化
2008-7-19 Sketches画图软件 v0.7b6破解版


  发表评论
姓 名: 验证码:
内 容:
[ 汉字翻译拼音 ] [ 广告代码 ] [ 符号对照表 ] [ 进制转换 ] [ 经典小工具 ] [ 个税计算 ] [ 汉字简繁转换 ] [ 普通单位换算 ] [ 公制单位换算 ]
[ 生辰老黄历 ] [ 国内电话区号 ] [ 国家代码与域名缩写 ] [ 文字加密解密 ] [ 健康查询 ] [ 万年历 ] [ 手机号码查询 ] [ ip搜索 ] [ Google PR查询 ]
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号