某些 Web 页面只想让特定的人浏览,或者干脆仅本人可见。为达到 这个目标,必不可少的就是认证功能。
8.1 何为认证
通常是通过核对一些信息来进行认证的,都是哪些信息呢?
- 密码:只有本人才会知道的字符串信息
- 动态令牌:仅限本人持有的设备内显示的一次性密码
- 数字证书:仅限本人(终端)持有的信息
- 生物认证:指纹和虹膜等本人的生理信息。
- IC 卡等:仅限本人持有的信息。
HTTP/1.1使用的认证方式:
- BASIC 认证(基本认证)
- DIGEST 认证(摘要认证)
- SSL 客户端认证
- FormBase 认证(基于表单认证)
8.2 BASIC 认证
从http/1.0就定义的认证方式,是web服务器和客户端之间的认证方式
- 步骤1:请求的资源需要BASIC认证时,服务器会把401带着WWW—Authenticate响应
- 用户接到响应需要把用户ID和密码以”ID:password”的形式发过去,然后通过base64编码,写入首部字段Authorization
缺点是base64不是加密处理,不需要ren h额附加信息就可以解码,容易被人窃听、被盗,而且没有实现认证注销操作
所以并不常用
8.3 DIGEST 认证
为弥补BASIC的弱点,从HTTP/1.1有了DIGEST认证,通用使用质询/响应的方式,但不会像BASIC认证那样直接发明文
而是通过:一开始一方会先发送认证要求给另一方,接 着使用从另一方那接收到的质询码计算生成响应码。最后将响应码返 回给对方进行认证的方式。
8.4 SSL 客户端认证
从使用用户 ID 和密码的认证方式方面来讲,只要二者的内容正确, 即可认证是本人的行为。但如果用户 ID 和密码被盗,就很有可能被 第三者冒充。利用 SSL 客户端认证则可以避免该情况的发生。
SSL客户端认证时借由HTTPS的客户端证书完成认证的方式,服务器可确认访问的是否是来自已经登陆的客户端
步骤如下:
- 接收到需要认证资源的请求,服务器会发送 Certificate Request 报文,要求客户端提供客户端证书。
- 用户选择将发送的客户端证书,客户端吧证书以Client Certificate发送给服务器
- 服务器验证客户端证书通过后可领取证书内的客户端公钥
8.4.2 SSL 客户端采用双因素认证
一般会和表单认证结合起来
双因素认证是指不仅通过密码这一个因素
换言之,第一个认证因素的 SSL 客户端证书用来认证客户端计算机, 另一个认证因素的密码则用来确定这是用户本人的行为。
8.4.3 SSL客户端认证必要的费用
客户端证书需要支付一定费用才能使用。费用是指,从认证机构购买客户端证书的费用,以及服务 器运营者为保证自己搭建的认证机构安全运营所产生的费用。
8.5 基于表单认证
客户端会向服务器上的 Web 应用程序发送登录信息(Credential),按登录信息的验 证结果认证。
8.5.1 认证多半基于表单认证
由于使用上的便利性及安全性问题,HTTP 协议标准提供的 BASIC 认 证和 DIGEST 认证几乎不怎么使用。另外,SSL 客户端认证虽然具有 高度的安全等级,但因为导入及维持费用等问题,还尚未普及。
比如 SSH 和 FTP 协议,服务器与客户端之间的认证是合乎标准规范 的,并且满足了最基本的功能需求上的安全使用级别,因此这些协议 的认证可以拿来直接使用。但是对于 Web 网站的认证功能,能够满 足其安全使用级别的标准规范并不存在,所以只好使用由 Web 应用 程序各自实现基于表单的认证方式。
8.5.2 Session管理及Cookie应用
基于表单认证的标准规范没有定论,一般采用Cookie管理Session来时心啊状态管理
步骤如下:
- 客户端把ID和密码等信息放入报文主体部分,通常以POST方法把请求发给服务器,这个时候会使用HTTPS通信进行HTML的表单画面显示和用户输入数据的发送
- 服务器会发放用以识别用户的Session ID,通过验证从客户端发送过来的登录信息进行身份验证,然后把SessionID绑定后记录在服务器端,想客户端返回响应时,会在首部字段Set-Cookie写入SessionID(如 PHPSESSID=028a8c…)
(为了防止SessionID被盗,SessionID一般时难以推测的字符串来保证其安全性)
(为了减轻XSS攻击,事先会在Cookie中加上httpOnly属性) - 客户端接受到服务端的SessionID后会把它作为Cookie存在本地,下次发请求时会自动发送Cookie,这样服务器就可以认证状态
另外,不仅基于表单认证的登录信息及认证过程都无标准化的方法, 服务器端应如何保存用户提交的密码等登录信息等也没有标准化。
通常,一种安全的保存方法是,先利用给密码加盐(salt)的方式增 加额外信息,再使用散列(hash)函数计算出散列值后保存。但是我们也经常看到直接保存明文密码的做法,而这样的做法具有导致密码泄露的风险。
salt 其实就是由服务器随机生成的一个字符串,但是要保证长度足够长,并且是 真正随机生成的。然后把它和密码字符串相连接(前后都可以)生成散列值。当 两个用户使用了同一个密码时,由于随机生成的 salt 值不同,对应的散列值也将 是不同的。这样一来,很大程度上减少了密码特征,攻击者也就很难利用自己手 中的密码特征库进行破解。
