Community Server专题八:MemberRole之Membership

时间:2022-09-05 09:05:23

 

Community Server专题八:MemberRole之Membership MemberRole是一个在asp.net  1 .1下实现用户管理、角色管理、用户特性信息存储(profile)等的一个组件,该组件被ASP.NET  2.0  Beta 2所采用,也就是ASP.NET  2.0  Beta 2中所说的Membership and Roles。如果你在asp.net  1 .1下采用了MemberRole,那么你的web程序将会很容易的过渡到asp.net  2.0 ,另外多个采取MemberRole进行用户管理的web程序需要整合时也非常容易。我将分4个专题来分析MemberRole,探索一下MemberRole到底是如何工作的,无论对CS的构架还是对了解asp.net  2 .0都是非常有帮助的。
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之MembershipCS中,运用该组件的4个部分:membership、roleManager、profile、anonymousIdentification的运用(整个MemberRole也这四部分功能)。
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership在分析前,准备需要一个工具:Reflector.exe,没有的朋友google一下,下载它。
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership本次专题分析membership,先看一下CS中Membership的配置文件(Web.Config中):
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership
< membership userIsOnlineTimeWindow = " 15 "   >
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership              
< providers >
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                   
< add 
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       name
= " CommunityServerSqlProvider "               
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       type
= " Openlab.AutoRegister.CSAutoBlogGalleryMembershipProvider, Openlab.CSAddOns "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       connectionStringName
= " SiteSqlServer "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       enablePasswordRetrieval
= " false "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       enablePasswordReset
= " true "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       requiresQuestionAndAnswer
= " false "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       requiresUniqueEmail
= " true "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       passwordFormat
= " Hashed "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       applicationName
= " dev "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       description
= " Stores and retrieves membership data from the local Microsoft SQL Server database "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       autoCreateBlog
= " false "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       defaultBlogGroupID
= " 3 "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       autoCreateGallery
= " false "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       defaultGalleryGroupID
= " 2 "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       maxInvalidPasswordAttempts 
=   " 999 "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       passwordAttemptWindow 
=   " 999 "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       minRequiredPasswordLength 
=   " 4 "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                       minRequiredNonalphanumericCharacters 
=   " 0 "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership                   
/>
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership              
</ providers >
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership
</ membership >
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之MembershipuserIsOnlineTimeWindow:这是一个数值,用来计算在线用户的数量,例如:
15 ,就表示如果用户在15分钟后不活动(发出Http请求)CS系统将视该用户不在线。
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之MembershipName:名称
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membershiptype:类的名字空间与所在的程序集合
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之MembershipconnectionStringName:数据库连接字符串节点的key。通过这个key就可以找到连接数据库的用户名与密码
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之MembershipenablePasswordRetrieval:是否打开取回秘密功能
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之MembershipenablePasswordReset:是否打开秘密重新设功能
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之MembershiprequiresQuestionAndAnswer:注册时是否需要填写Question与Answer
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之MembershiprequiresUniqueEmail:注册时是否Email唯一
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之MembershippasswordFormat:密码的加密格式
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之MembershipapplicationName:使用该membership应用程序的名称
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membershipdescription:描述信息
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership 
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership以下4个参数是CCS中添加的,目的是给注册用户自动开通相册和博客
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之MembershipautoCreateBlog:是否当用户注册时自动为该用户建立一个Blog
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之MembershipdefaultBlogGroupID:默认的建立blog的分组ID
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之MembershipautoCreateGallery:是否当用户注册时自动为该用户建立一个相册
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之MembershipdefaultGalleryGroupID:默认的建立相册的分组ID
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership 
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership用Reflector.exe打开MemberRole.dll,你可以看到以下的内容:
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership再打开Microsoft.ScalableHosting.Configuration节点
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership这次我们只关注两个类MembershipConfig、MembershipConfigHandler。MembershipConfigHandler实现了IConfigurationSectionHandler接口。也就是说,CS启动后如果调用ConfigurationSettings.GetConfig(
" memberrolesprototype/membership " ),系统将会自动的调用MembershipConfigHandler中的Create方法把web.config中memberrolesprototype / membership的配置内容读入进行处理。先看以下Create做了些什么:
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership
public   virtual   object  Create( object  parent,  object  configContextObj, XmlNode section)
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership
{
Community Server专题八:MemberRole之Membership      MembershipConfig config1 
= new MembershipConfig(parent as MembershipConfig);
Community Server专题八:MemberRole之Membership      
int num1 = -1;
Community Server专题八:MemberRole之Membership      ConfigUtils.GetAndRemovePositiveIntegerAttribute(section, 
"userIsOnlineTimeWindow"ref num1);
Community Server专题八:MemberRole之Membership      
if (num1 > 0)
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership      
{
Community Server专题八:MemberRole之Membership            config1.UserIsOnlineTimeWindow 
= num1;
Community Server专题八:MemberRole之Membership      }

Community Server专题八:MemberRole之Membership      
string text1 = null;
Community Server专题八:MemberRole之Membership      ConfigUtils.GetAndRemoveStringAttribute(section, 
"hashAlgorithm"ref text1);
Community Server专题八:MemberRole之Membership      
if ((text1 != null&& (text1.Length > 0))
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership      
{
Community Server专题八:MemberRole之Membership            config1.HashAlgorithmType 
= text1;
Community Server专题八:MemberRole之Membership      }

Community Server专题八:MemberRole之Membership      ConfigUtils.CheckForUnrecognizedAttributes(section);
Community Server专题八:MemberRole之Membership      MembershipProvider provider1 
= null;
Community Server专题八:MemberRole之Membership      
foreach (XmlNode node1 in section.ChildNodes)
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership      
{
Community Server专题八:MemberRole之Membership            
if (node1.NodeType != XmlNodeType.Element)
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership            
{
Community Server专题八:MemberRole之Membership                  
continue;
Community Server专题八:MemberRole之Membership            }

Community Server专题八:MemberRole之Membership            
if (node1.Name != "providers")
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership            
{
Community Server专题八:MemberRole之Membership                  
throw new ConfigurationException("Unrecognized tag: " + node1.Name, node1);
Community Server专题八:MemberRole之Membership            }

Community Server专题八:MemberRole之Membership            
foreach (XmlNode node2 in node1.ChildNodes)
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership            
{
Community Server专题八:MemberRole之Membership                  
if (node2.NodeType == XmlNodeType.Element)
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership                  
{
Community Server专题八:MemberRole之Membership                        
if (node2.Name != "add")
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership                        
{
Community Server专题八:MemberRole之Membership                              
throw new ConfigurationException("Unrecognized tag: " + node2.Name, node2);
Community Server专题八:MemberRole之Membership                        }

Community Server专题八:MemberRole之Membership                        
if (provider1 != null)
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership                        
{
Community Server专题八:MemberRole之Membership                              
throw new ConfigurationException("Only one provider can be configured", node2);
Community Server专题八:MemberRole之Membership                        }

Community Server专题八:MemberRole之Membership                        
string text2 = null;
Community Server专题八:MemberRole之Membership                        
string text3 = null;
Community Server专题八:MemberRole之Membership                        ConfigUtils.GetAndRemoveRequiredNonEmptyStringAttribute(node2, 
"name"ref text2);
Community Server专题八:MemberRole之Membership                        ConfigUtils.GetAndRemoveRequiredNonEmptyStringAttribute(node2, 
"type"ref text3);
Community Server专题八:MemberRole之Membership                        NameValueCollection collection1 
= new NameValueCollection();
Community Server专题八:MemberRole之Membership                        
foreach (XmlAttribute attribute1 in node2.Attributes)
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership                        
{
Community Server专题八:MemberRole之Membership                              
if ((attribute1.Name != null&& (attribute1.Name.Length > 0))
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership                              
{
Community Server专题八:MemberRole之Membership                                    collection1.Add(attribute1.Name, attribute1.Value);
Community Server专题八:MemberRole之Membership                              }

Community Server专题八:MemberRole之Membership                        }

Community Server专题八:MemberRole之Membership                        provider1 
= (MembershipProvider) Activator.CreateInstance(Type.GetType(text3, true));
Community Server专题八:MemberRole之Membership                        provider1.Initialize(text2, collection1);
Community Server专题八:MemberRole之Membership                        config1.Provider 
= provider1;
Community Server专题八:MemberRole之Membership                  }

Community Server专题八:MemberRole之Membership            }

Community Server专题八:MemberRole之Membership      }

Community Server专题八:MemberRole之Membership      
return config1;
Community Server专题八:MemberRole之Membership}

Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership 
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership代码有点长,其实这里就是把web.config下面membership节点的配置信息读入,进行初始化,然后通过GetType与Activator.CreateInstance方法反射后实例化一个MembershipProvider。
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之MembershipMembershipProvider又是什么,继续看看:
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership
public   abstract   class  MembershipProvider : ProviderBase
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership
{
Community Server专题八:MemberRole之Membership      
// Events
Community Server专题八:MemberRole之Membership
      public event MembershipValidatePasswordEventHandler ValidatingPassword;
Community Server专题八:MemberRole之Membership 
Community Server专题八:MemberRole之Membership      
// Methods
Community Server专题八:MemberRole之Membership
      protected MembershipProvider();
Community Server专题八:MemberRole之Membership      
public abstract bool ChangePassword(string username, string oldPassword, string newPassword);
Community Server专题八:MemberRole之Membership      
public abstract bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer);
Community Server专题八:MemberRole之Membership      
public abstract MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status);
Community Server专题八:MemberRole之Membership      
protected virtual byte[] DecryptPassword(byte[] encodedPassword);
Community Server专题八:MemberRole之Membership      
public abstract bool DeleteUser(string username, bool deleteAllRelatedData);
Community Server专题八:MemberRole之Membership      
internal string EncodePassword(string pass, int passwordFormat, string salt);
Community Server专题八:MemberRole之Membership      
protected virtual byte[] EncryptPassword(byte[] password);
Community Server专题八:MemberRole之Membership      
public abstract MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords);
Community Server专题八:MemberRole之Membership      
public abstract MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords);
Community Server专题八:MemberRole之Membership      
internal string GenerateSalt();
Community Server专题八:MemberRole之Membership      
public abstract MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords);
Community Server专题八:MemberRole之Membership      
public abstract int GetNumberOfUsersOnline();
Community Server专题八:MemberRole之Membership      
public abstract string GetPassword(string username, string answer);
Community Server专题八:MemberRole之Membership      
public abstract MembershipUser GetUser(object providerUserKey, bool userIsOnline);
Community Server专题八:MemberRole之Membership      
public abstract MembershipUser GetUser(string username, bool userIsOnline);
Community Server专题八:MemberRole之Membership      
public abstract string GetUserNameByEmail(string email);
Community Server专题八:MemberRole之Membership      
protected virtual void OnValidatingPassword(ValidatePasswordEventArgs e);
Community Server专题八:MemberRole之Membership      
public abstract string ResetPassword(string username, string answer);
Community Server专题八:MemberRole之Membership      
internal string UnEncodePassword(string pass, int passwordFormat);
Community Server专题八:MemberRole之Membership      
public abstract bool UnlockUser(string userName);
Community Server专题八:MemberRole之Membership      
public abstract void UpdateUser(MembershipUser user);
Community Server专题八:MemberRole之Membership      
public abstract bool ValidateUser(string username, string password);
Community Server专题八:MemberRole之Membership 
Community Server专题八:MemberRole之Membership      
// Properties
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership
      public abstract string ApplicationName getset; }
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership      
public abstract bool EnablePasswordReset get; }
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership      
public abstract bool EnablePasswordRetrieval get; }
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership      
public abstract int MaxInvalidPasswordAttempts get; }
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership      
public abstract int MinRequiredNonAlphanumericCharacters get; }
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership      
public abstract int MinRequiredPasswordLength get; }
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership      
public abstract int PasswordAttemptWindow get; }
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership      
public abstract MembershipPasswordFormat PasswordFormat get; }
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership      
public abstract string PasswordStrengthRegularExpression get; }
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership      
public abstract bool RequiresQuestionAndAnswer get; }
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership      
public abstract bool RequiresUniqueEmail get; }
Community Server专题八:MemberRole之Membership 
Community Server专题八:MemberRole之Membership      
// Fields
Community Server专题八:MemberRole之Membership
      private MembershipValidatePasswordEventHandler _EventHandler;
Community Server专题八:MemberRole之Membership      
private const int SALT_SIZE_IN_BYTES = 0x10;
Community Server专题八:MemberRole之Membership}

Community Server专题八:MemberRole之Membership原来MembershipProvider是实现继承了ProviderBase的一个类,其实ProviderBase并没有什么,看看代码
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership
public   abstract   class  ProviderBase
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership
{
Community Server专题八:MemberRole之Membership      
// Methods
Community Server专题八:MemberRole之Membership
      protected ProviderBase();
Community Server专题八:MemberRole之Membership      
public virtual void Initialize(string name, NameValueCollection config);
Community Server专题八:MemberRole之Membership 
Community Server专题八:MemberRole之Membership      
// Properties
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership
      public virtual string Description get; }
Community Server专题八:MemberRole之MembershipCommunity Server专题八:MemberRole之Membership      
public virtual string Name get; }
Community Server专题八:MemberRole之Membership 
Community Server专题八:MemberRole之Membership      
// Fields
Community Server专题八:MemberRole之Membership
      private string _Description;
Community Server专题八:MemberRole之Membership      
private bool _Initialized;
Community Server专题八:MemberRole之Membership      
private string _name;
Community Server专题八:MemberRole之Membership}

Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之MembershipProviderBase仅仅只是保护了两个虚属性的类,设置这个类只是一种设计模式,没有特别的用途。我们把重点集中到MembershipProvider上,其实MembershipProvider类是Provider构架的一种体现形式,Provider构架常常用到对数据库的访问上,实现多数据库,同时也可以很好的隔离数据层与业务层的代码有利于协作开发。具体实现是这样的,先把要操作数据库的方法抽象出来,单独的放入一个abstract类,例如:MembershipProvider,然后通过继承,把这些抽象的方法全部的实现出来,例如:SqlMembershipProvider。这样有什么好处呢?对于三层构架的web应用程序来说,中间的业务逻辑层调用操作数据库的方法是从MembershipProvider,对于该层来说它并不关心该抽象层是如何被继承后实现抽象方法的。它只关心抽象层中是否有它想要的方法。如果能理解到这里,嘿嘿,我们的机会就来了,因为这隔离了具体的数据库操作实现,更进一步说就是隔离了使用何种数据库。再从团队协作考虑,假设你的MembershipProvider定义的完善后,继承MembershipProvider实现SQL Server操作的SqlMembershipProvider类中的方法无论怎么改变,都不会影响其它人员在业务逻辑层的开发。听起来这种方式好像很美,但是要实现这样的功能还需要一个关键的技术,那就是反射,所以我们看到在配置的字段里有这样的字节:。
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membershiptype
= " Openlab.AutoRegister.CSAutoBlogGalleryMembershipProvider, Openlab.CSAddOns "
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership这就是为了通过反射找到MembershipProvider具体方法实现的类而做的准备。
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership注:由于分析的代码来源于宝玉的CCS,在CCS中为了实现注册后能自动开通博客与相册又继承了SqlMembershipProvider类,重写了几个方法(关键是其中的Initialize与CreateUser方法)。
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership只要你继承MembershipProvider类,对其中的抽象方法进行实现,无论你是实现对Access的操作,还是其它数据库,都是没有问题的。在asp.net 
2.0  beta2中的Membership已经提供access与sql server两种数据库操作实现。不过MemberRole.dll程序集中只实现了SqlMembershipProvider,也就是对SQL Server的操作。
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership其实Membership是一个没有表示层的运用组件,它包含了逻辑层与数据操作层,数据层我在这个专题中就不多做解释,他的实现是在SqlMembershipProvider类中,你可以通过Reflector.exe慢慢研究。上面的文字说过,实现Provider模式后业务逻辑层对数据层具体实现就不关心了,在MemberRole.dll中的Membership,它把所有的这些逻辑用一个类包装起来,那就是Membership类:
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership对于引用MemberRole.dll实现Membership功能的web app(DNN,CS就是典型)来说,只要做合适的配置之后就可以直接使用了。
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership例如,要建立一个用户只要调用Membership.CreateUser的静态方法,就可以完成(Membership会根据内部的方法和具体的数据库操作,把用户信息写入数据库)。
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership对于使用Membership来开发web app的程序员来说,完全可以不必要了解这些细节,asp 
2.0  beta2就没有提供这样的机会,MS只要求你会用就可以了,不过很庆幸的是CS给我们提供了这样的一个机会,了解这些操作的实质(包括URL Rewrite等功能也是一样,这些功能都可以在asp  2.0  beta2中直接使用,而不要构架如何代码)。
Community Server专题八:MemberRole之Membership
Community Server专题八:MemberRole之Membership这个专题只是大致的讲解了Membership,下一个专题,我们将更深入的去看看Membership的数据层的操作实现以及数据库表的设计(包括存储过程)。
Community Server专题八:MemberRole之Membership