http://blog.csdn.net/htjoy1202/article/details/7067287
其认证的基本框架为挑战认证的结构,如下图所示:
1.客户端希望取到服务器上的某个资源,向服务器发送Get请求。
2.服务器收到客户端的请求后,发现这个资源需要认证信息,判断请求报文中是否带有Authorization头,如果没有,返回一个401(Unauthorized)给客户端。在这个401的回复中,同时服务器会加入一个WWW-Authenticate的头,其中有如下信息(各个字段的详细解释见RFC2617):
challenge = "Digest" digest-challenge
digest-challenge = 1#( realm | [ domain ] | nonce |
[ opaque ] |[ stale ] | [ algorithm ] |
[ qop-options ] | [auth-param] )
domain = "domain" "=" <"> URI ( 1*SP URI ) <">
URI = absoluteURI | abs_path
nonce = "nonce" "=" nonce-value
nonce-value = quoted-string
opaque = "opaque" "=" quoted-string
stale = "stale" "=" ( "true" | "false" )
algorithm = "algorithm" "=" ( "MD5" | "MD5-sess" |
token )
qop-options = "qop" "=" <"> 1#qop-value <">
qop-value = "auth" | "auth-int" | token
3.客户端收到服务器的401(Unauthorized)回复后,使用服务器回复报文中的nonce值,加上username,password利用MD5(或者服务器指定的其他算法)计算request-digest。并重新发送请求,请求报文中包含Authorization 头,其中有如下信息:
credentials = "Digest" digest-response
digest-response = 1#( username | realm | nonce | digest-uri
| response | [ algorithm ] | [cnonce] |
[opaque] | [message-qop] |
[nonce-count] | [auth-param] )
username = "username" "=" username-value
username-value = quoted-string
digest-uri = "uri" "=" digest-uri-value
digest-uri-value = request-uri ; As specified by HTTP/1.1
message-qop = "qop" "=" qop-value
cnonce = "cnonce" "=" cnonce-value
cnonce-value = nonce-value
nonce-count = "nc" "=" nc-value
nc-value = 8LHEX
response = "response" "=" request-digest
request-digest = <"> 32LHEX <">
LHEX = "0" | "1" | "2" | "3" |
"4" | "5" | "6" | "7" |
"8" | "9" | "a" | "b" |
"c" | "d" | "e" | "f"
4.服务器收到客户端发来的请求后,根据username,查找出用户的password,用和客户端同样的方法计算出request-digest。然后和收到的request-digest进行对比,如果一致,则接受客户端的请求,成功返回结果。