一、方案架构
本方案架构很简单——它用一个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);