三、凭证管理器应用程序
本文相应的源代码包含了这个凭证管理器应用程序-一个具有丰富的用户接口的Windows表单应用程序,它使用在上一步描述的Web服务接口来为任何数目的应用程序管理安全凭证存储。
该应用程序导入五个Web接口定义,并且它独占地使用那些接口。该应用程序有一个称为AspNetSqlProviderService的Web服务代理类-它用于定位该服务。你需要从导入的接口手工地把它添加到该服务上。
图4.Applications选项卡:这个选项卡让你选择要配置的应用程序。 |
partial class AspNetSqlProviderService : SoapHttpClientProtocol,IMembershipManager, IUserManager,IPasswordManager, IApplicationManager,IRoleManager { public AspNetSqlProviderService (){ Credentials = CredentialCache.DefaultCredentials; Url = Settings.Default.AspNetSqlProviderService ; } //其它的执行 } |
为了支持集成的Windows认证,这个代理类的构造器使用CredentialCache的静态属性DefaultCredentials设置凭证属性-它只是简单地读取当前线程的安全标志。另外,这个构造器还使用设计器生成的Settings类从应用程序配置类中读取Web服务地址。
图5.Users选项卡:该选项卡列出在选定的应用程序中的所有用户。 |
这个应用程序的使用相当直观,所以我只介绍一下主要屏幕和选项。Applications选项卡(见图4)允许你选择要配置的应用程序。
在此,选择一应用程序将影响所有其它的选项卡。你可以创建和删除一个应用程序或删除所有应用程序。Users选项卡列举出在选择的应用程序中的所有用户。
你可以创建或删除一用户。如果你删除一用户但是不选择"All Data"复选框的话,它将删除该用户但是维持它的角色身份信息。你可以更新一用户帐户或删除所有用户。根据从AspNetSqlProviderService Web服务返回的口令策略的不同,你能够或不能够改变或重置口令,而且可以或不可以需要回答该口令。在Users选项卡的按钮和它所显示的对话框也相应地启动或禁止。
在Users选项卡的右边是统计信息,如当前用户的在线数。Roles选项卡允许你把角色添加到应用程序。
图6:Roles选项卡:这个选项卡让你把角色添加到应用程序。 |
当删除一个角色时,如果你选择了"Fail if populated"复选框,那么如果它有任何成员的话,就不会让你删掉该角色。左边的列表视图显示在该应用程序中的所有用户。你可以从一个角色添加或删除一用户,或从所有角色中删除一用户。在底部,"Users in role"列表框显示了在上面选定的角色中的所有用户,而"Roles for User"列表框显示了在上面选定的用户中的所有角色(见《
理论篇》之图3)。
Passwords选项卡显示在图7中,它列出已配置的口令策略并且允许你生成一与指定的口令强度策略相匹配的新口令。
图7.Passwords选项卡:你可以使用这个选项卡生成一口令。 |
图8.Credentials Service选项卡:使用这个选项卡来选择使用的Web服务。 |
该选项卡让你选择要使用的Web服务。一旦启动,凭证管理器应用程序即从应用程序配置文件中读取这个地址。这个选项卡显示被选择的Web服务。如果地址是无效的,也就是说,该服务不支持所有要求的功能,那么在应用程序中的所有控件都将为空且是禁止的。你可以提供一个不同的地址,而下面的Web浏览器控件将会显示这一服务。然而,如果该服务支持要求的Web方法(一有效的Web服务)的话,你可以只选择一个Web服务地址(通过点击Select按钮)。如果该服务是无效的,那么将禁止Select按钮。
不幸的是,在.NET 2.0中没有提供校验某服务是否支持一特别绑定或Web接口的内置支持,因此我不得不手工实现。所附源码中的列表6显示出RefreshSelectButton()和ContainsInterface()助理方法。RefreshSelectButton()首先禁止Select按钮和相匹配的菜单项。然后,验证指定的地址是一个.NET Web服务的地址。然后,它存取显示在Web浏览器控件中的页面的内容并且验证它包含支持所有的接口的方法。为此,它要调用ContainsInterface()方法并把页面的内容和要验证的接口类型提供给它。ContainsInterface()验证该类型是一个接口的类型并且获得一个MethodInfo对象数组-标记在该接口上的每个方法。然后,它定义一个接收单个实例MethodInfo的匿名方法并且使用字符串类的Contains()方法来验证该内容包含那个方法。ContainsInterface()使用该数组类的静态TrueForAll<T>()方法。
public delegate bool Predicate<T>(T obj); public abstract class Array : ... { public static bool TrueForAll< T>(T[] array,Predicate< T> match); } |
ContainsInterface()提供给TrueForAll()一个MethodInfo对象数组和匿名方法形式的Predicate。只有在该内容中找到所有的方法时,TrueForAll<T>()才返回true。
查看本文来源