Windows Communication Foundation (WCF) 是 Microsoft 为构建面向服务的应用程序而提供的统一编程模型(摘自MSDN),在分布式环境下的安全问题尤为重要,如果你觉得使用了WCF默认的安全措施可以让你高枕无忧,那明天你可就以回家种田了,当然,对于学习来说,足够了~,但我们讲的是真正的项目应用,WCF在各种协议下的安全提供和保证是不尽相同的。
背景
在上一篇X509证书介绍后,相信大家对怎么使用X509证书在WCF的安全策略中有一定的了解,本章主要讲述在WCF的消息安全模式下的服务器对客户端基于自定义用户名和密码的身份验证模式。当所有内置 UserNamePassword 验证模式均不符合应用程序的要求时,你可以能过继承 System.IdentityModel.Selectors.UserNamePasswordValidator 抽象类,并重写其Validate方法来实现自己的用户名密码验证程序,实际上,内置的用户名密码验证方式比自定义的用户名密码验证方式要可靠得多,因为自定义的用户名密码验证程序任何人都可以构造,但是标准的用户名密码验证方式刚是将用户提供的用户名密码映射到windows账户,所以,如果映射失败,意味着验证不通过,以下示例在服务器端启用自定义的用户名密码验证程序,客户端在调用服务前需要提供访问服务所需要的用户名密码,并在EndpointIdenty中向服务器标识自己是合法用户,具体标识参见本系列第二章:WCF安全之EndPointIdentity。如果服务器验证通过,将向客户端返回一个从数据库查询到的xml列(xElement对象),并将内容打印到控制台。
开始吧
1、实现自定义用户名密码方式有哪些要求?
如上面的所讲,首先,我们需要建立一个类,来继承自System.IdentityModel.Selectors.UserNamePasswordValidator抽象类,并重其validate方法,代码比较简单,当然,这只是用于演示作用,如果是在实际的项目中,你完全可以将用户名密码存储在持久化介质上,请看实现:
以下为引用的内容: public class CustomUserPassword : UserNamePasswordValidator { public override void Validate(string userName, string password) { if (userName != "admin" || password != "admin") { throw new SecurityNegotiationException("验证用户名和密码时,未通过检测"); } } } |
你可以在代码或者在配置文件中完成此安全策略实现过程,但是如果你是以代码方式实现,做之前请参考Artech的文章:[原创]WCF技术剖析之八:ClientBase中对ChannelFactory的缓存机制 (请原谅我引用),配置文件实现如下:
以下为引用的内容: //绑定配置 //服务配置 |
在上面的过程中,我们的绑定配置中的安全策略必须是消息级别的安全,因为在传输级别中,是不提供用户名密码验证方式的。两种级别的的选择比较主要体现在安全和效率上,如果你的传输效率上没有什么问题,建议你选择第四种安全策略:TransportWithMessageCredential,TransportWithMessageCredential的好处是既提供安全传输,又保证消息加密,多好!相对来说还是比较简单的吧