分享
 
 
 

ASP.NET2.0应用中定制安全凭证之实践篇

王朝asp·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

一、方案架构

本方案架构很简单——它用一个Web服务来包装ASP.NET 2.0提供者并且为远程客户暴露该凭证管理,你甚至还能在该架构中加上一些失去的功能。然后,在提供一个丰富的用户接口和全面凭证管理经验的同时,使用一个Windows表单应用程序来消费该Web服务。该Web服务配置文件将包含特定于该凭证存储的指令。然而,这的确意味着所有由该Web服务管理的应用程序都将可以共享这些指令。

尽管你能够从头到尾地构建该Web服务,也就是说,首先用静态方法Roles和Membership来包装它们并定义该Web服务,我却更喜欢一种契约驱动的方法:首先设计执行各种操作的最好接口将是什么,并且直到需要时才考虑怎样实现它们。这样做可以确保由Web服务暴露的接口支持所有要求的管理功能并且还将减少该客户应用程序与任何实现细节(例如包装提供者)之间的耦合。

ASP.NET 2.0的一个更好的特点是它支持Web服务接口,你可以定义并且让该Web服务暴露逻辑接口,就象类的表现一样。为此,你需要用WebServiceBinding属性修饰你的接口并且经由WebMethod属性来暴露单个的接口方法。然后,你将有一个派生于这个接口的类并实现该接口,而且编译器将要求你支持该接口的所有方法。

为了管理和交互于凭证存储和Web服务配置,我定义了5个接口-IApplicationManager,IMembershipManager,IPasswordManager,IroleManager和IUserManager。

(一) IApplicationManager

该IApplicationManager接口显示于所附源码中的列表2,允许管理员删除一指定的应用程序-也就是说,从数据库中删除所有到它的参考并且删除它的所有用户和角色。IApplicationManager允许从存储中删除所有的应用程序,并且它能返回在该存储中的所有应用程序的一个列表。注意,这个接口作为一个内部的接口被定义-public或internal可见性修饰词对Web服务接口都是无意义的。该接口上的每个方法用WebMethod属性加以修饰并有一个该方法的简短描述。此外,存取凭证存储的所有方法都被设置为使用事务处理。这样以来,两种操作-如删除一应用程序和创建一用户将在彼此完全隔离的情况下执行,从而保证了如删除所有用户等复杂操作的原子性。.NET 2.0中的Web服务只能启动一个新事务,而且它是由WebMethod属性的TransactionOption属性来控制的。最后一点是把WebServiceBinding属性应用于接口上。这就指定该接口是一个客户和服务都能绑定到的Web服务接口。为了把该接口以一个WSDL契约方式暴露给外界,你需要使用一个shim类。这个shim类的设计是必要的,因为你不能把一个接口作为一Web服务暴露,而且你也不能在其上应用WebService属性。这个shim类还将经由WebService属性为该接口命名空间定义。下面的代码显示了IApplicationManagerShim抽象类的定义。

[WebService(Name="IApplicationManager",

Namespace="http://CredentialsServices",

Description="IApplicationManager is used to manage

applications. This web service is only

the definition of the interface. You

cannot invoke method calls on it.")]

abstract class IApplicationManagerShim : IApplicationManager{

public abstract void DeleteApplication(string application);

public abstract string[] GetApplications();

public abstract void DeleteAllApplications();

}

因为IApplicationManagerShim是一个类,所以你可以把它暴露为一个Web服务。因为它是一抽象类且所有方法被定义为抽象方法,所以不需要(也不能)实现任何方法。为了使其看起来就象该接口,IapplicationManagerShim把WebService属性的属性名设置为IApplicationManager(代替缺省的类名)。现在,你可以使用IApplicationManager.asmx文件来暴露该接口。

<%@ WebService Language="C#"

CodeBehind="~/App_Code/IApplicationManagerShim.cs"

Class="IApplicationManagerShim"%>

现在,如果你浏览到IApplicationManager.asmx页面,你就会看到该接口定义。你可以使用WSDL.exe的serverInterface选项来把接口定义输入到客户端或任何其它想绑定到该接口定义上的服务。

(二) IMembershipManager

IMembershipManager接口(见所附源码中的列表3)允许你管理用户帐户的所有方面-创建和删除用户帐户,更新用户帐户,检索用户帐户细节以及检索在一应用程序中的所有用户。

(三) IRoleManager

IRoleManager接口允许你管理逻辑角色的所有方面-创建和删除角色,从角色中增加和删除用户以及检索在一应用程序中的所有角色。

[WebServiceBinding("IRoleManager")]

interface IRoleManager{

[WebMethod(...)]

void CreateRole(string application,string role);

[WebMethod(...)]

bool DeleteRole(string application,string role,bool throwOnPopulatedRole);

[WebMethod(...)]

void AddUserToRole(string application,string userName, string role);

[WebMethod(...)]

void DeleteAllRoles(string application,bool throwOnPopulatedRole);

[WebMethod(...)]

string[] GetAllRoles(string application);

[WebMethod(...)]

string[] GetRolesForUser(string application,string userName);

[WebMethod(...)]

string[] GetUsersInRole(string application, string role);

[WebMethod(...)]

void RemoveUserFromRole(string application,string userName, string roleName);

//更多成员

}

(四) IPasswordManager

这个IPasswordManager接口主要提供与应用程序口令策略相关的只读信息。

[WebServiceBinding("IPasswordManager")]

interface IPasswordManager{

[WebMethod(...)]

bool EnablePasswordReset(string application);

[WebMethod(...)]

bool EnablePasswordRetrieval(string application);

[WebMethod(...)]

string GeneratePassword(string application,int length,

int numberOfNonAlphanumericCharacters);

[WebMethod(...)]

bool RequiresQuestionAndAnswer(string application);

[WebMethod(...)]

string ResetPassword(string application,string userName);

[WebMethod(...)]

string GetPassword(string application,string userName,string passwordAnswer);

[WebMethod(...)]

void ChangePassword(string application,string userName,string newPassword);

//更多成员

}

典型地,该策略存储在应用程序的配置文件中。该策略包括是否启动口令重置和检索,口令强度和口令回答策略等。你也可以使用IpasswordManager来生成一相应于该口令强度策略的新口令。另外,IpasswordManager可用于重置、改变或检索一指定用户的口令。

(五) IUserManager

IUserManager接口允许校验用户凭证,检索角色身份以及获取指定用户是其成员之一的所有角色。该接口用于测试和分析目的。

[WebServiceBinding("IUserManager")]

public interface IUserManager{

[WebMethod(...)]

bool Authenticate(string applicationName,string userName, string password);

[WebMethod(...)]

bool IsInRole(string applicationName,string userName, string role);

[WebMethod(...)]

string[] GetRoles(string applicationName,string userName);

}

二、AspNetSqlProviderService Web服务

显示在所附源码中的列表4中的AspNetSqlProviderService类实现了五个Web接口。其过程就象实现任何其它接口一样-你可以隐式或显式地派生并实现方法(见列表4)。我是通过把这些实现简单地代理到提供者的适当的方法来实现该Web接口上的大多数方法的。在每一次使用角色或身份之前,你必须为之作好准备-通过设置要使用的应用程序名。例如,为了实现IRoleManager.CreateRole(),你将需要建立:

void IRoleManager.CreateRole(string application,string role){

Roles.ApplicationName = application;

Roles.CreateRole(role);

}

其中的一些方法在调用该提供者前后还要求一点工作。例如,如果启动口令检索,你只能检索用户口令,而AspNetSqlProviderService则用于判定它。

string IPasswordManager.GetPassword(string application,string userName,

string passwordAnswer){

Membership.ApplicationName = application;

Debug.Assert(Membership.EnablePasswordRetrieval);

MembershipUser membershipUser =Membership.GetUser(userName);

return membershipUser.GetPassword(passwordAnswer);

}

然而,还有一些方法并没有得到提供者的直接支持。有两种可能的解决办法-第一种是尝试并使用提供者的其它方法来完成所希望的操作。第二种是直接执行aspnetdb数据库。两种方法都存在利弊。例如,可以考虑实现MembershipManager.DeleteAllUsers()方法。你可以对该应用程序中的每个用户调用身份提供者的DeleteUser()方法,如列表4所示。首先你要调用IMembershipManager.GetAllUsers()方法来得到应用程序中的所有用户。这就是你通过实现该接口的类来使用该接口方法的显式实现方式。然后,你可以定义一个匿名方法来删除用户,把该匿名方法赋值到一个Action<string>代理,并且使用Array类的静态方法ForEach<T>()删除每个用户。

public delegate void Action<T>(T obj);

public abstract class Array : ...

{

public static void ForEach<T>(T[] array,Action<T> action);

}

第一种方法的优点是任何与删除一个用户相关的内部活动(如也删除所有的角色身份)仍旧被执行。其不足是,你需要对该数据库做更多的调用。

正如刚才提到的,第二种方法是直接对aspnetdb数据库编程。当提供者没有提供任何方式来完成此任务时,这是最有用的。例如,提供者并不支持删除一应用程序,更不说删除所有的应用程序了。尽管你可以编写一个存储过程来做这件事情,但我的另一个目标是不动用aspnetdb,而是使用原始SQL命令来实现IApplicationManager.DeleteApplication()和IApplicationManager.DeleteAllApplications()。我已用一个AspNetDbTablesAdapter助理类(在此没有显示)包装了这些命令。直接访问数据库的优点是你仅执行一个命令;不足之处是,如果要改变数据库模式,你将需要更改你的代码。假定如删除所有的用户或一应用程序等操作是一般不涉及的并且超级用户的数目经常很小,那么我想最好尽可能让AspNetSqlProviderService使用ASP.NET 2.0提供者。

(一) 设置服务

由AspNetSqlProviderService Web服务使用的Web.Config文件中的设置影响它管理的所有应用程序。特别地,如口令策略这样的设置适用于所有的应用程序。该服务使用默认提供者(SQL SERVER),因此如果缺省的连接字符串(在文件machine.config中维护)已经足够的话,就不需要指定一个提供者甚至一个连接字符串。如果你需要一个不同的连接字符串,你需要包括一个connectionStrings标签(见所附源码中的列表5)。另外,为了使用Roles类,你必须通过下列指令来启动基于角色的安全。

<roleManager enabled="true" />

(二) 保护服务

尽管其凭证由AspNetSqlProviderService Web服务来管理的应用程序可能是基于互联网或基于内部网的,但是服务本身是被设计由一个管理员通过本地内部网来存取的。你应该认证和授权到该服务的调用。另外,你还应该通过加密通讯来提供秘密服务。这是要求的,因为该服务要处理如用户名和口令等敏感信息。保证秘密的最容易的方法是使用HTTPS。AspNetSqlProviderService在它的构造器中经由静态VerifySecureConnection()助理方法来进行验证是否使用了一个安全连接。VerifySecureConnection()使用当前请求的IsSecureConnection属性。为了支持开发或该服务的其它类型的非生产性发布,VerifySecureConnection()方法用Conditional属性加以修饰。只有定义编译符号HTTPS时该方法才会起作用。关于认证该服务的用户,既然Web服务是一本地内部网服务,那么使用Windows认证就不会有任何错误了。我选择了使用集成的Windows认证-这将省去了用户必须明确地登录的麻烦。集成的认证的另外一个优点是,它用一种专利方式来散列化发送过去的凭证。

为了配置集成的Windows认证,转到在IIS下的AspNetSqlProviderService Web服务属性,选择目录安全选项卡,并且点击"Edit…"按钮。不选择"Anonymous access"复选框并且保证选中"Integrated Windows authentication"复选框。AspNetSqlProviderService类被配置以要求认证(见列表4)-它使用PrincipalPermission属性并把被认证的属性设计为true。

[PrincipalPermission(SecurityAction.Demand,...,Authenticated=true)]

一旦调用者通过IIS被认证,该服务缺省地将在IIS中以配置的身份仍旧运行。我想以调用者身份运行该服务。为此,Web.Conf

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有