实现分布式的Membership和上下文传递剖析.docx

上传人:b****5 文档编号:8224725 上传时间:2023-01-30 格式:DOCX 页数:18 大小:22.27KB
下载 相关 举报
实现分布式的Membership和上下文传递剖析.docx_第1页
第1页 / 共18页
实现分布式的Membership和上下文传递剖析.docx_第2页
第2页 / 共18页
实现分布式的Membership和上下文传递剖析.docx_第3页
第3页 / 共18页
实现分布式的Membership和上下文传递剖析.docx_第4页
第4页 / 共18页
实现分布式的Membership和上下文传递剖析.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

实现分布式的Membership和上下文传递剖析.docx

《实现分布式的Membership和上下文传递剖析.docx》由会员分享,可在线阅读,更多相关《实现分布式的Membership和上下文传递剖析.docx(18页珍藏版)》请在冰豆网上搜索。

实现分布式的Membership和上下文传递剖析.docx

实现分布式的Membership和上下文传递剖析

实现分布式的Membership和上下文传递

通过上一篇了解了模块内基本的层次划分之后,接下来我们来聊聊PetShop中一些基本基础功能的实现,以及一些设计、架构上的应用如何同WCF进行集成。

本篇讨论两个问题:

实现分布式的Membership和客户端到服务端上下文(Context)的传递。

一、如何实现用户验证

对登录用户的验证是大部分应用所必需的,对于ASP.NET来说,用户验证及帐号管理实现在成员资格(Membership)模块中。

同ASP.NET的其他模块一样,微软在设计Membership的时候,为了实现更好地可扩展性,采用了策略(Strategy)设计模式:

将模块相关的功能定义在被称为Provider的抽象类型中,并通过继承它提供具体的Provider。

如果这些原生的Provider不能满足你的需求,你也可以通过继承该抽象的Provider,创建自定义的Provider。

通过ASP.NET提供的配置,你可以很轻易地把自定义的Provider应用到你的应用之中。

在一般情况下,最终的编程人员并不通过Provider调用相关的功能,而是通过一个外观(Facade)类实现对相关功能的调用。

ASP.NET成员资格模块的设计基本上可以通过下面的类图1反映出来:

最终的编程人员通过外观类型(FaçadeClass)Membership调用成员资格相关的功能,比如用户认证、用户注册、修改密码等;Membership通过抽象类MembershipProvider提供所有的功能,至于最终的实现,则定义在一个个具体的MembershipProvider中。

基于成员资格信息不同的存储方式,ASP.NET提供了两个原生的MembershipProvider:

SqlMembershipProvider和ActiveDirectoryMembershipProvider,前者基于SQLServer数据库,后者基于AD。

如果这两个MembershipProvider均不能满足需求,我们还可以自定义MembershipProvider。

clip_image002

图1ASP.NETMembership设计原理

我们的案例并不会部署于AD之中,所以不能使用ActiveDirectoryMembershipProvider;直接通过Web服务器进行数据库的存取又不符合上述物理部署的要求(通过应用服务器进行数据库访问),所以SqlMembershipProvider也不能为我们所用。

为此需要自定义MembershipProvider,通过WCF服务调用的形式提供成员资格所有功能的实现。

我们将该自定义MembershipProvider称为RemoteMembershipProvider。

图2揭示了RemoteMembershipProvider实现的原理:

RemoteMembershipProvider通过调用WCF服务MembershipService提供对成员资格所有功能的实现;MembershipService则通过调用Membership实现服务;最终的实现还是落在了SqlMembershipProvider这个原生的MembershipProvider上。

clip_image004

图2RemoteMembershipProvider实现原理

1、服务契约和服务实现

首先来看看MembershipService实现的服务契约的定义。

由于MembershipService最终是为RemoteMembershipProvider这个自定义MembershipProvider服务的,所以服务操作的定义是基于MembershipProvider的API定义。

MembershipProvider包含两种类型的成员:

属性和方法,简单起见,我们可以为MembershipProvider每一个抽象方法定义一个匹配的服务操作;而对于所有属性,完全采用服务端(应用服务器)的MembershipProvider相关属性。

在RemoteMembershipProvider初始化的时候通过调用MembershipService获取所有服务端MembershipProvider的配置信息。

为此,我们为MembershipProvider的所有属性定义了一个数据契约:

MembershipConfigData。

在PetShop中,MembershipConfigData和服务契约一起定义在Infrastructures.Service.Interface项目中。

1:

usingSystem.Runtime.Serialization;

2:

usingSystem.Web.Security;

3:

namespaceArtech.PetShop.Infrastructures.Service.Interface

4:

{

5:

[DataContract(Namespace="

6:

publicclassMembershipConfigData

7:

{

8:

[DataMember]

9:

publicstringApplicationName

10:

{get;set;}

11:

12:

[DataMember]

13:

publicboolEnablePasswordReset

14:

{get;set;}

15:

16:

[DataMember]

17:

publicboolEnablePasswordRetrieval

18:

{get;set;}

19:

20:

[DataMember]

21:

publicintMaxInvalidPasswordAttempts

22:

{get;set;}

23:

24:

[DataMember]

25:

publicintMinRequiredNonAlphanumericCharacters

26:

{get;set;}

27:

28:

[DataMember]

29:

publicintMinRequiredPasswordLength

30:

{get;set;}

31:

32:

[DataMember]

33:

publicintPasswordAttemptWindow

34:

{get;set;}

35:

36:

[DataMember]

37:

publicMembershipPasswordFormatPasswordFormat

38:

{get;set;}

39:

40:

[DataMember]

41:

publicstringPasswordStrengthRegularExpression

42:

{get;set;}

43:

44:

[DataMember]

45:

publicboolRequiresQuestionAndAnswer

46:

{get;set;}

47:

48:

[DataMember]

49:

publicboolRequiresUniqueEmail

50:

{get;set;}

51:

}

52:

}

在服务契约中,定义了一个额外的方法GetMembershipConfigData获取服务端MembershipProvider的所有配置信息,而对于服务操作的定义,则与MembershipProvider同名抽象方法相对应。

1:

usingSystem.ServiceModel;

2:

usingSystem.Web.Security;

3:

namespaceArtech.PetShop.Infrastructures.Service.Interface

4:

{

5:

[ServiceContract(Namespace="

6:

publicinterfaceIMembershipService

7:

{

8:

[OperationContract]

9:

boolChangePassword(stringusername,stringoldPassword,stringnewPassword);

10:

[OperationContract]

11:

boolChangePasswordQuestionAndAnswer(stringusername,stringpassword,stringnewPasswordQuestion,stringnewPasswordAnswer);

12:

[OperationContract]

13:

MembershipUserCreateUser(stringusername,stringpassword,stringemail,stringpasswordQuestion,stringpasswordAnswer,boolisApproved,objectproviderUserKey,outMembershipCreateStatusstatus);

14:

[OperationContract]

15:

boolDeleteUser(stringusername,booldeleteAllRelatedData);

16:

[OperationContract]

17:

MembershipUserCollectionFindUsersByEmail(stringemailToMatch,intpageIndex,intpageSize,outinttotalRecords);

18:

[OperationContract]

19:

MembershipUserCollectionFindUsersByName(stringusernameToMatch,intpageIndex,intpageSize,outinttotalRecords);

20:

[OperationContract]

21:

MembershipUserCollectionGetAllUsers(intpageIndex,intpageSize,outinttotalRecords);

22:

[OperationContract]

23:

intGetNumberOfUsersOnline();

24:

[OperationContract]

25:

stringGetPassword(stringusername,stringanswer);

26:

[OperationContract(Name="GetUserByName")]

27:

MembershipUserGetUser(stringusername,booluserIsOnline);

28:

[OperationContract(Name="GetUserByID")]

29:

MembershipUserGetUser(objectproviderUserKey,booluserIsOnline);

30:

[OperationContract]

31:

stringGetUserNameByEmail(stringemail);

32:

[OperationContract]

33:

stringResetPassword(stringusername,stringanswer);

34:

[OperationContract]

35:

boolUnlockUser(stringuserName);

36:

[OperationContract]

37:

voidUpdateUser(MembershipUseruser);

38:

[OperationContract]

39:

boolValidateUser(stringusername,stringpassword);

40:

[OperationContract]

41:

MembershipConfigDataGetMembershipConfigData();

42:

}

43:

}

服务的实现,则异常简单,我们须要做的仅仅是通过Membership.Provider获得当前的MembershipProvider,调用同名的属性或方法即可。

MembershipService定义在Infrastructures.Service中,定义如下:

1:

usingSystem.Web.Security;

2:

usingArtech.PetShop.Infrastructures.Service.Interface;

3:

namespaceArtech.PetShop.Infrastructures.Service

4:

{

5:

publicclassMembershipService:

IMembershipService

6:

{

7:

#regionIMembershipServiceMembers

8:

9:

publicboolChangePassword(stringusername,stringoldPassword,stringnewPassword)

10:

{

11:

returnMembership.Provider.ChangePassword(username,oldPassword,newPassword);

12:

}

13:

14:

publicboolChangePasswordQuestionAndAnswer(stringusername,stringpassword,stringnewPasswordQuestion,stringnewPasswordAnswer)

15:

{

16:

returnMembership.Provider.ChangePasswordQuestionAndAnswer(username,password,newPasswordQuestion,newPasswordAnswer);

17:

}

18:

//其他成员

19:

publicMembershipConfigDataGetMembershipConfigData()

20:

{

21:

returnnewMembershipConfigData

22:

{

23:

ApplicationName=Membership.Provider.ApplicationName,

24:

EnablePasswordReset=Membership.Provider.EnablePasswordReset,

25:

EnablePasswordRetrieval=Membership.Provider.EnablePasswordRetrieval,

26:

MaxInvalidPasswordAttempts=Membership.Provider.MaxInvalidPasswordAttempts,

27:

MinRequiredNonAlphanumericCharacters=Membership.Provider.MinRequiredNonAlphanumericCharacters,

28:

MinRequiredPasswordLength=Membership.Provider.MinRequiredPasswordLength,

29:

PasswordAttemptWindow=Membership.Provider.PasswordAttemptWindow,

30:

PasswordFormat=Membership.Provider.PasswordFormat,

31:

PasswordStrengthRegularExpression=Membership.Provider.PasswordStrengthRegularExpression,

32:

RequiresQuestionAndAnswer=Membership.Provider.RequiresQuestionAndAnswer,

33:

RequiresUniqueEmail=Membership.Provider.RequiresUniqueEmail

34:

};

35:

}

36:

37:

#endregion

38:

}

39:

}

2、RemoteMembershipProvider的实现

由于RemoteMembershipProvider完全通过调用WCF服务的方式提供对所有成员资格功能的实现,所以进行RemoteMembershipProvider配置时,配置相应的终结点就可以了。

1:

xmlversion="1.0"?

>

2:

3:

4:

5:

6:

7:

8:

9:

10:

11:

12:

//localhost/PetShop/Infrastructures/MembershipService.svc"behaviorConfiguration="petShopBehavior"binding="ws2007HttpBinding"contract="Artech.PetShop.Infrastructures.Service.Interface.IMembershipService"name="membershipservice"/>

13:

14:

15:

在RemoteMembershipProvider中,通过Initialize方法获取配置的终结点名称并创建服务代理。

通过该代理调用GetMembershipConfigData操作获取服务端MembershipProvider的配置信息,并对RemoteMembershipProvider进行初始化,RemoteMembershipProvider定义如下:

1:

usingSystem.Collections.Specialized;

2:

usingSystem.Configuration;

3:

usingSystem.Linq;

4:

usingSystem.Web.Security;

5:

usingArtech.PetShop.Common;

6:

usingArtech.PetShop.Infrastructures.Service.Interface;

7:

8:

namespaceArtech.PetShop.Infrastructures

9:

{

10:

publicclassRemoteMembershipProvider:

MembershipProvider

11:

{

12:

privatebool_enablePasswordReset;

13:

privatebool_enablePasswordRetrieval;

14:

//其他字段成员

15:

16:

publicIMembershipServiceMembershipProxy

17:

{get;privateset;}

18:

19:

publicoverrideintMaxInvalidPasswordAttempts

20:

{

21:

get{returnthis._maxInvalidPasswordAttempts;}

22:

}

23:

24:

//其他属性成员

25:

publicoverridevoidInitialize(stringname,NameValueCollectionconfig)

26:

{

27:

if(!

config.AllKeys.Contains("endpoint"))

28:

{

29:

thrownewConfigurationErrorsException("Missingthemandatory\"endpoint\"configuraitonproperty.");

30:

}

31:

32:

this.MembershipProxy=ServiceProxyFactory.Create(config["endpoint"]);

33:

base.Initialize(name,config);

34:

MembershipConfigDataconfigData=this.MembershipProxy.GetMembershipConfigData();

35:

this.ApplicationName=configData.ApplicationName;

36:

this._enablePasswordReset=configData.EnablePasswordReset;

37:

this._enablePasswordRetrieval=configData.EnablePasswordRetrieval;

38:

//......

39:

}

40:

}

41:

}

对于其他抽象方法的实现,仅仅须要通过上面创建的服务代理,调用相应的服务操作即可。

注:

为了避免在服务操作调用后频繁地进行服务代理的关闭(Close)和终止(Abort)操作,我们采用基于AOP的方式实现服务的调用,将这些操作封装到一个自定义的RealProxy中,并通过ServiceProxyFactory创建该

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 工学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1