web 中的认证方式

在Web中包括了四种认证方式:Basic, Form, Digest, SSL。下面进行一一阐述。

1. Basic (HTTP 1.0 提出) 客户端请求某个资源后,服务器会发送一个401(未授权)的响应,在响应中带了Realm信息表示使用Basic认证。 浏览器接收到这个响应后会弹出一个框,输入用户名和密码。点取消表示取消认证,点确定会提交用户名、密码到服务器。 提交的方式是在HTTP头中加入: WWW-Authorization:Basic XXXXXXX Basic后面是用户名、密码的BASE64编码。在客户端编程中,这段内容的构造为:

Java代码 复制代码 收藏代码
  1. a. String cre = userName + ":" + password  
  2. b. Base64 encode(cre);  
  3. c. add to request header with "WWW-Authroization"  
a. String cre = userName + ":" + password
b. Base64 encode(cre);
c. add to request header with "WWW-Authroization"

2. Form Form就是在页面上以Form的形式提交数据,GET或POST. 也可以使用AJAX来提交认证信息。


3. Digest (HTTP 1.1最基本) 为了防止重放攻击,采用摘要访问认证。客户发送一个请求后,收到一个401消息,消息中还包括一个唯一的字符串:nonce,每次请求都不一样。如,

Java代码 复制代码 收藏代码
  1. HTTP/1.1 401 Unauthorized  
  2. WWW-Authenticate: Digest  
  3. realm="xxxxxxx",  
  4. qop="auth,auth-int",  
  5. nonce="--base code--",  
  6. opaque="--base code--"  
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest
realm="xxxxxxx",
qop="auth,auth-int",
nonce="--base code--",
opaque="--base code--"

此时客户端将用户名、密码、nonce、HTTP Method和URI为校验值基础进行散列(默认为MD5)的摘要返回给服务器。响应头必须包括的5个部分:

  • realm:领域,不同领域可能密码不一样
  • nonce: 挑战值
  • username:用户名
  • digest-uri:请求URI
  • response:摘要部分

服务器端则根据收到的信息加上存储的密码算出一个新的摘要与请求中的摘要比较,因为每次nonce都会变,就很难做到重放攻击了。
4. SSL SSL协议位于TCP/IP和应用协议之间,基于公钥体制保证数据通讯的安全性。SSL协议可分为两层: SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。 SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。
SSL协议提供的服务主要有: 1)认证用户和服务器,确保数据发送到正确的客户机和服务器; 2)加密数据以防止数据中途被窃取; 3)维护数据的完整性,确保数据在传输过程中不被改变。
SSL协议的工作流程: 服务器认证阶段: 1)客户端向服务器发送一个开始信息"Hello"以便开始一个新的会话连接; 2)服务器根据客户的信息确定是否需要生成新的主密钥,即会话密钥,如需要则服务器在响应客户的"Hello”信息时将包含生成主密钥所需的信息; 3)客户根据收到的服务器响应信息,产生一个主密钥,并用服务器的公开密钥加密后传给服务器; 4)服务器恢复该主密钥,并返回给客户一个用主密钥认证的信息,以此让客户认证服务器。 用户认证阶段:在此之前,服务器已经通过了客户认证,这一阶段主要完成对客户的认证。经认证的服务器发送一个提问给客户(往往是一张登录页面),客户则返回(数字)签名后的提问和其公开密钥,从而向服务器提供认证。

 

       Basic认证和Digest认证,RFC2617中有更详细的说明。这两种认证方式都是一种无状态的认证方式,就是不需要服务器端保存必要的session,所以也没有session失效期。客户端每次都需要将密码和用户名发送给服务器来完成认证,而且用户名和密码是保存在浏览器进程的内存中的,也就是只有当浏览器关闭的时候,用户名和密码也随之删除,才表示这次服务和认证结束,下一次请求需要重新输入用户名和密码。

      这两种方式都是浏览器产生输入用户名和密码的登录框。Basic认证采用了Base64编码,攻击者很容易获取http请求,然后解码请求就可以获取用户名和密码,没有安全性可言;而Digest认证采用一中NONCE随机字符串,用户的每次认证都需要哈希和MD5(用户名和密码),并加入这个盐值,客户端和服务器端每次的NONCE都是不一样的,这样就保证了认证的安全性和不可重放性。这里的NONCE并不是Session保存的一个字符串,这样就违背了无状态性特性。服务器端需要为产生的NONCE建一个表记录每个NONCE使用的次数,当然每个只能使用一次,一旦使用两次或多次就认证不通过,Nonce的产生和判断有很多技巧,见前面一片文章中有谈到。

      虽然Digest认证可以保证足够的安全,但对于项目来说是不可行的,还有一种认证方式那就是Form认证,我觉得Form表单认证和Http认证有几分相似,对于HTTP认证的Basic认证,相当于Form表单使用简单的用户名和密码一样;而对于HTTP认证的Digest认证,可以这样认为,NONCE可以相当于验证码,可以保证随即字符串每次基本上是不一样的,而表单的密码可以采用MD5(混合机制(MD5(用户名+密码)+验证码)),这样就比较像Digest认证了,这也正是我对于学生和散户登录将要采用的一个认证方法,相信这种方法已经足够安全了,而数据库中保存的密码应该是MD5(用户名+密码),也可以随便混入几个字符串,从而保证数据库文件丢失造成的损失。

      防止同一账号的重复登录可以采用Spring Security技术实现,或许还有简单的方法,但当session还存在,而用户不小心退出了浏览器,此时可以判断用户的IP与前一个session的IP是否一致来判断用户的合法性,此类文章有好像有收藏。

 

 


References: [1] Basic 验证的Domain处理     http://blog.csdn.net/zfive5/archive/2006/11/01/1361138.aspx [2] HTTP 认证方式     http://blog.csdn.net/hotnet522/archive/2010/08/19/5824716.aspx [3] 什么是SSL连接     http://zhidao.baidu.com/question/39307683.html?fr=ala0

posted @ 2015-04-07 23:33  zhh  阅读(2227)  评论(0编辑  收藏  举报