设为首页 收藏本站
查看: 1039|回复: 0

[经验分享] Community Server专题八:MemberRole之Membership

[复制链接]

尚未签到

发表于 2016-11-10 02:32:47 | 显示全部楼层 |阅读模式
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都是非常有帮助的。
CS中,运用该组件的4个部分:membership、roleManager、profile、anonymousIdentification的运用(整个MemberRole也这四部分功能)。
在分析前,准备需要一个工具:Reflector.exe,没有的朋友google一下,下载它。
本次专题分析membership,先看一下CS中Membership的配置文件(Web.Config中):
  :这是一个数值,用来计算在线用户的数量,例如:15,就表示如果用户在15分钟后不活动(发出Http请求)CS系统将视该用户不在线。
DSC0000.gif <membershipuserIsOnlineTimeWindow="15">

<providers>

<add

name="CommunityServerSqlProvider"

type
="Openlab.AutoRegister.CSAutoBlogGalleryMembershipProvider,Openlab.CSAddOns"

connectionStringName
="SiteSqlServer"

enablePasswordRetrieval
="false"

enablePasswordReset
="true"

requiresQuestionAndAnswer
="false"

requiresUniqueEmail
="true"

passwordFormat
="Hashed"

applicationName
="dev"

description
="StoresandretrievesmembershipdatafromthelocalMicrosoftSQLServerdatabase"

autoCreateBlog
="false"

defaultBlogGroupID
="3"

autoCreateGallery
="false"

defaultGalleryGroupID
="2"

maxInvalidPasswordAttempts
="999"

passwordAttemptWindow
="999"

minRequiredPasswordLength
="4"

minRequiredNonalphanumericCharacters
="0"

/>

</providers>

</membership>

userIsOnlineTimeWindow
Name:名称
type:类的名字空间与所在的程序集合
connectionStringName:数据库连接字符串节点的key。通过这个key就可以找到连接数据库的用户名与密码
enablePasswordRetrieval:是否打开取回秘密功能
enablePasswordReset:是否打开秘密重新设功能
requiresQuestionAndAnswer:注册时是否需要填写Question与Answer
requiresUniqueEmail:注册时是否Email唯一
passwordFormat:密码的加密格式
applicationName:使用该membership应用程序的名称
description:描述信息

以下4个参数是CCS中添加的,目的是给注册用户自动开通相册和博客
autoCreateBlog:是否当用户注册时自动为该用户建立一个Blog
defaultBlogGroupID:默认的建立blog的分组ID
autoCreateGallery:是否当用户注册时自动为该用户建立一个相册
defaultGalleryGroupID:默认的建立相册的分组ID

用Reflector.exe打开MemberRole.dll,你可以看到以下的内容:
DSC0001.jpg
再打开Microsoft.ScalableHosting.Configuration节点
DSC0002.jpg
这次我们只关注两个类MembershipConfig、MembershipConfigHandler。MembershipConfigHandler实现了IConfigurationSectionHandler接口。也就是说,CS启动后如果调用ConfigurationSettings.GetConfig("memberrolesprototype/membership"),系统将会自动的调用MembershipConfigHandler中的Create方法把web.config中memberrolesprototype/membership的配置内容读入进行处理。先看以下Create做了些什么:

publicvirtualobjectCreate(objectparent,objectconfigContextObj,XmlNodesection)
DSC0003.gif DSC0004.gif
DSC0005.gif {
DSC0006.gif MembershipConfigconfig1
=newMembershipConfig(parentasMembershipConfig);
intnum1=-1;
ConfigUtils.GetAndRemovePositiveIntegerAttribute(section,
"userIsOnlineTimeWindow",refnum1);
if(num1>0)
DSC0007.gif DSC0008.gif
{
config1.UserIsOnlineTimeWindow
=num1;
DSC0009.gif }

stringtext1=null;
ConfigUtils.GetAndRemoveStringAttribute(section,
"hashAlgorithm",reftext1);
if((text1!=null)&&(text1.Length>0))
{
config1.HashAlgorithmType
=text1;
}

ConfigUtils.CheckForUnrecognizedAttributes(section);
MembershipProviderprovider1
=null;
foreach(XmlNodenode1insection.ChildNodes)
{
if(node1.NodeType!=XmlNodeType.Element)
{
continue;
}

if(node1.Name!="providers")
{
thrownewConfigurationException("Unrecognizedtag:"+node1.Name,node1);
}

foreach(XmlNodenode2innode1.ChildNodes)
{
if(node2.NodeType==XmlNodeType.Element)
{
if(node2.Name!="add")
{
thrownewConfigurationException("Unrecognizedtag:"+node2.Name,node2);
}

if(provider1!=null)
{
thrownewConfigurationException("Onlyoneprovidercanbeconfigured",node2);
}

stringtext2=null;
stringtext3=null;
ConfigUtils.GetAndRemoveRequiredNonEmptyStringAttribute(node2,
"name",reftext2);
ConfigUtils.GetAndRemoveRequiredNonEmptyStringAttribute(node2,
"type",reftext3);
NameValueCollectioncollection1
=newNameValueCollection();
foreach(XmlAttributeattribute1innode2.Attributes)
{
if((attribute1.Name!=null)&&(attribute1.Name.Length>0))
{
collection1.Add(attribute1.Name,attribute1.Value);
}

}

provider1
=(MembershipProvider)Activator.CreateInstance(Type.GetType(text3,true));
provider1.Initialize(text2,collection1);
config1.Provider
=provider1;
}

}

}

returnconfig1;
DSC00010.gif }




代码有点长,其实这里就是把web.config下面membership节点的配置信息读入,进行初始化,然后通过GetType与Activator.CreateInstance方法反射后实例化一个MembershipProvider。
MembershipProvider又是什么,继续看看:
MembershipProvider是实现继承了ProviderBase的一个类,其实ProviderBase并没有什么,看看代码
publicabstractclassMembershipProvider:ProviderBase
{
//Events
publiceventMembershipValidatePasswordEventHandlerValidatingPassword;

//Methods
protectedMembershipProvider();
publicabstractboolChangePassword(stringusername,stringoldPassword,stringnewPassword);
publicabstractboolChangePasswordQuestionAndAnswer(stringusername,stringpassword,stringnewPasswordQuestion,stringnewPasswordAnswer);
publicabstractMembershipUserCreateUser(stringusername,stringpassword,stringemail,stringpasswordQuestion,stringpasswordAnswer,boolisApproved,objectproviderUserKey,outMembershipCreateStatusstatus);
protectedvirtualbyte[]DecryptPassword(byte[]encodedPassword);
publicabstractboolDeleteUser(stringusername,booldeleteAllRelatedData);
internalstringEncodePassword(stringpass,intpasswordFormat,stringsalt);
protectedvirtualbyte[]EncryptPassword(byte[]password);
publicabstractMembershipUserCollectionFindUsersByEmail(stringemailToMatch,intpageIndex,intpageSize,outinttotalRecords);
publicabstractMembershipUserCollectionFindUsersByName(stringusernameToMatch,intpageIndex,intpageSize,outinttotalRecords);
internalstringGenerateSalt();
publicabstractMembershipUserCollectionGetAllUsers(intpageIndex,intpageSize,outinttotalRecords);
publicabstractintGetNumberOfUsersOnline();
publicabstractstringGetPassword(stringusername,stringanswer);
publicabstractMembershipUserGetUser(objectproviderUserKey,booluserIsOnline);
publicabstractMembershipUserGetUser(stringusername,booluserIsOnline);
publicabstractstringGetUserNameByEmail(stringemail);
protectedvirtualvoidOnValidatingPassword(ValidatePasswordEventArgse);
publicabstractstringResetPassword(stringusername,stringanswer);
internalstringUnEncodePassword(stringpass,intpasswordFormat);
publicabstractboolUnlockUser(stringuserName);
publicabstractvoidUpdateUser(MembershipUseruser);
publicabstractboolValidateUser(stringusername,stringpassword);

//Properties
publicabstractstringApplicationName{get;set;}
publicabstractboolEnablePasswordReset{get;}
publicabstractboolEnablePasswordRetrieval{get;}
publicabstractintMaxInvalidPasswordAttempts{get;}
publicabstractintMinRequiredNonAlphanumericCharacters{get;}
publicabstractintMinRequiredPasswordLength{get;}
publicabstractintPasswordAttemptWindow{get;}
publicabstractMembershipPasswordFormatPasswordFormat{get;}
publicabstractstringPasswordStrengthRegularExpression{get;}
publicabstractboolRequiresQuestionAndAnswer{get;}
publicabstractboolRequiresUniqueEmail{get;}

//Fields
privateMembershipValidatePasswordEventHandler_EventHandler;
privateconstintSALT_SIZE_IN_BYTES=0x10;
}


原来
仅仅只是保护了两个虚属性的类,设置这个类只是一种设计模式,没有特别的用途。我们把重点集中到MembershipProvider上,MembershipProvider类是Provider构架的一种体现形式,Provider构架常常用到对数据库的访问上,实现多数据库,同时也可以很好的隔离数据层与业务层的代码有利于协作开发。具体实现是这样的,先把要操作数据库的方法抽象出来,单独的放入一个abstract类,例如:MembershipProvider,然后通过继承,把这些抽象的方法全部的实现出来,例如:SqlMembershipProvider。这样有什么好处呢?对于三层构架的web应用程序来说,中间的业务逻辑层调用操作数据库的方法是从MembershipProvider,对于该层来说它并不关心该抽象层是如何被继承后实现抽象方法的。它只关心抽象层中是否有它想要的方法。如果能理解到这里,嘿嘿,我们的机会就来了,因为这隔离了具体的数据库操作实现,更进一步说就是隔离了使用何种数据库。再从团队协作考虑,假设你的MembershipProvider定义的完善后,继承MembershipProvider实现SQL Server操作的SqlMembershipProvider类中的方法无论怎么改变,都不会影响其它人员在业务逻辑层的开发。听起来这种方式好像很美,但是要实现这样的功能还需要一个关键的技术,那就是反射,所以我们看到在配置的字段里有这样的字节:。
publicabstractclassProviderBase
{
//Methods
protectedProviderBase();
publicvirtualvoidInitialize(stringname,NameValueCollectionconfig);

//Properties
publicvirtualstringDescription{get;}
publicvirtualstringNameborder-right: #808080 1px solid; border-top: #808080

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-297988-1-1.html 上篇帖子: SQL 修改排序规则 下篇帖子: windows server 进程system.exe pid=4 占用 80端口
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表