如果要给认证下一个定义,我个人的倾向这样的定义:认证是确定被认证方的真实身份和他或她申明(Claim)的身份是否相符的行为。认证方需要被认证方提供相应的身份证明材料,以鉴定本身的身份是否与声称的身份相符。在计算机的语言中,这里的身份证明有一个专有的名称,即“凭证(Credential)”,或者用户凭证(User Credential)、认证凭证(Authentication Credential)。
一、凭证的属性
最好的设计就是能够尽可能的模拟现实的设计。对于安全认证来说,在现实生活中有无数现成的例子。比如我对一个不认识的人说:“我是张三”,对方如何才能相信我真的是张三而非李四呢?虽然我们未必全都是有身份的人,但无疑我们都是有身份证的人,身份证可以证明我们的真实身份。而这里的身份证就是一种典型的凭证。认证方能够根据被认证方提供的身份证识别对方的真实身份,必须满足三个条件:
- 被认证人声称是身份证上注明的那个人;
- 身份证的持有者就是身份证的拥有者;
- 身份证本身是合法有效的,即是通过公安机关颁发的,而不是通过拨打“办证”电话办理的。
第一个问题一般不是问题,因为对于一个神经稍微正常的人来说,他不会拿着李四的身份证去证明自己是张三;第二个问题可以根据身份证上面的照片来判断;第三个问题就依赖于身份证本身的防伪标识和认证方的鉴别能力了。
上述的三个条件本质上也反映了认证过程中用户凭证本身应该具有的属性,以及用户凭证和被认证人之间的关系。即:凭证与声明的一致性,被认证人对凭证的拥有性,以及凭证的合法性。为了简单,我们不妨简称为用户凭证的三个属性。用户凭证的类型决定了认证的方式,WCF支持一系列不同类型的用户凭证,以满足不同认证需求。接下来,我们来简单介绍几种使用比较普遍的凭证以及相应的认证方式。
二、用户名/密码认证
我们最常使用的认证方式莫过于采用验证用户名和密码的形式,以致于我们提到身份验证,很多人会想到密码。我们不妨通过上面我们讲到的用户凭证的三属性来分析用户名/密码凭证。
用户名表示被认证方声明的身份(Identity),密码是持有人是凭证合法拥有者的证据。对于认证方来说,由于账号对应的密码属于账号拥有者的私密信息,如果被认证方能够提供与他声明身份相匹配的密码,就能够证明对方确实与他声明的是同一个人。首先,用户名代表身份(Identify),凭证与声明的一致性意味着被认证方声明的身份与用户名一致。被认证人对凭证的拥有性通过密码证明,密码属于绝对隐私信息,被认证人如果能够提供与所声明的身份相匹配的密码,就能够证明他是凭证的真正拥有者;由于用户名/密码凭证不属于证书型凭证,不需要合法机构颁发,对于合法性则无从说起。
在采用用户名/密码认证方式的应用中,认证方一般具有所有用户帐号和密码的列表。当然,由于密码对属于持有人的绝对隐私,原则上仅限于持有人本人知晓,其他人任何人(当然也包括认证方)不应该采用技术手段获知该密码。如果认证方维护者他负责认证的所有帐户的用户名和密码的列表,被存储的一般是原始密码的哈希值以及进行哈希运算采用的Key。由于哈希算法是不可逆的,所以无法通过后哈希的值和相应的Key得到原始的值,从而确保了密码的安全性。在进行认证的时候,只需要根据用户名找到相应的Key,然后利用该Key采用相同的算法对用户提供的密码进行哈希算法,最终将最终的运算结果和本地存储的值进行比较即可验证密码的真伪。
虽然在我们进行项目开发的时候,我们也会选择对用户注册时提供的密码进行加密存储,这样可以让用户忘记原来的密码的时候,通过向认证方证明其真实身份的前提下,让认证方通过通过解密返回其原来的密码。对于密码的加密存储问题,无论是采用对称加密还是非对称加密,我们都可以通过相应的解密算法得到其原始密码,所以从理论上讲具有安全问题。不过,具体应用在选择密码存储策略的时候,可以根据自身所需的安全级别以及是否需要返回原始密码,选择对原始密码进行哈希或者加密。但是,无论如何对密码进行明文存储是不被允许的。
如果你选择了用户名/密码凭证,WCF为你提供了三种认证模式:
- 将用户名映射为Windows帐号,采用Windows认证;
- 采用ASP.NET的成员资格(Membership)模块
- 通过继承UserNamePasswordValidator,实现自定义认证。
三、Windows认证
应该说就采用的频率程度,集成Windows认证(IWA:Integrated Windows Authentication)是仅次于用户名/密码的认证方式。尤其是在基于Windows活动目录(AD:Active Directory)的Intranet应用来说,Windows认证更是成为首选。微软几乎所有需要进行认证的产品或者开发平台都集成了Windows认证,比如IIS,SQL Server,ASP.NET等,当然,WCF也不可能例外。
Windows是实现单点登录(SSO:Single Sign-On)最理想的方式。无论是采用域(Domain)模式还是工作组(Workgroup)模式,只要你以Windows帐号和密码登录到某一台机器,你就会得到一个凭证。在当前会话超时之前,你就可以携带该Windows凭证,自动登录到集成了Windows认证方式的所有应用,而无须频繁地输入相同的Windows帐号和密码。如果登录帐号不具有操作目标应用的权限,在一般情况下,你好可以通过重新输入Windows帐号和相应的密码(如果当前用户具有多个Windows帐号)以另外一个身份(该身份具有对目标应用进行操作的访问权限)对目标应用进行操作。
就其实现来说,Windows具有两种不同的认证协议,即NTLM(NT LAN Manager)和Kerberos。关于这两种认证机制大体上的原理,可以参考我写的两篇文章:
Windows安全认证是如何进行的?[Kerberos篇]
Windows安全认证是如何进行的?[NTLM篇]
在《下篇》中,我们着重讨论基于X.509数字证书的凭证。