1 授权鉴别(Access Authentication)
1.1对HTTP/1.1规范的依赖(Reliance on the HTTP/1.1 Specification)
本规范和HTTP/1.1规范[2]一起使用,它使用HTTP/1.1文档2.1节的补充反馈方式(Augmented BNF),并依赖于该文档对非终端(non-terminals)的定义及对其它方面的描述。
1.2 访问鉴别框架(Access Authentication Framework)
HTTP提供了简单的挑战-回应鉴别机制,它可能被服务器用来质询客户端请求,也可能被客户端用来提供鉴别信息。授权方案用可扩展的、大小写敏感的符号来标识,后跟获取证明所需要的以逗号分隔的‘属性-值’对。
auth-scheme = token
auth-param = token "=" ( token | quoted-string )
401(未授权)回应消息被原始服务器端用来质询用户代理的授权。该回应必须包括含有至少一个被请求资源质询(challenge)的WWW-鉴别标题域。407(需要鉴别代理)回应消息被代理用来质询客户端的授权,它的代理鉴别标题域(Proxy-Authenticate header field)必须包括至少一个代理方(proxy)对被请求资源的质询。
challenge = auth-scheme 1*SP 1#auth-param
注意:用户代理(agent)解析WWW-鉴别(WWW-Authenticate)或代理-鉴别(Proxy-Authenticate)的标题域,在碰到含有多个质询()或多个WWW-鉴别标题域时,要特别小心,因为这些质询本身可能就包含了以逗号分隔的鉴别参数对。
鉴别参数realm的定义在所有的鉴别方案中使用:
realm = "realm" "=" realm-value
realm-value = quoted-string
Franks, et al. Standards Track [Page 3]
Realm指示(大小写敏感)在所有涉及质询(challenge)的鉴别方案中都要用到。Realm值(大小写敏感)要与被访问服务器的‘根’URL的规范用法(即绝对路径为空的服务器的绝对URI-absoluteURI,见5.1.2节[2])联合使用,以定义受保护的区间。这些realm参数允许将服务器上受保护资源分成若干个区间,每个区间都有其自己的鉴别方案和(或)授权数据库。Realm值是字符串,通常由原始服务器分配,针对某些鉴别方案可能还有附加的语法问题。注意,可能存在多个质询(challenge),auth-scheme相同,而realm不同的情况。
通常,用户代理(agent)在收到401(未授权)回应时,可能(也可能不会)希望服务器对其授权。如果希望授权,用户代理将在请求中加入授权请求标题(Authorization request-header)域。授权域值由信任证书组成,其中有对用户代理所请求资源领域的授权信息。客户端在收到407(需要代理鉴别)回应时,如希望通过代理进行自身的鉴别,可在请求中加入代理授权请求标题域(Proxy-Authorization request-header)。授权域值和代理授权域值都是由信任组成,这些信任包括被请求资源的客户端鉴别信息realm的值。用户代理(user agent)必须选用它所能理解的最强的auth-scheme及用户回应质询(challenge)的请求信任。
credentials = auth-scheme #auth-param
注意,许多浏览器只支持基本方案,要求它在auth-scheme中排在第一位。如果提供最低程度的满意度,服务器端应只支持基本方案。
受保护区间定义了将要自动使用信任的区域。如果早先的请求已经通过认证,在由授权方案,参数和(或)用户选择等所指定的时间间隔内,其它的请求可通过相同的信任来访问该保护区域。除非鉴别方案有特别指定,否则单个保护区域不能扩展到该服务器以外的范围。
如果原始服务器不希望通过发送的请求来接受信任,它应当返回401(未授权)回应。该回应必须包括一个WWW-鉴别标题域,而该域要包含至少一个(可能是新的)对被请求资源的质询(challenge)。如果代理(proxy)不接受用请求方式发送信任,它应当返回407(需要代理鉴别)回应。该回应必须包括一个代理鉴别(Proxy-Authenticate)标题域,而该域要包含至少一个(可能是新的),代理可用的,对被请求资源的质询。
Franks, et al. Standards Track [Page 4]
HTTP协议的访问鉴别并不限于这种简单的质询回应(challenge-response)机制,还可以使用其它的方法,比如传输级加密或消息封装及通过附加标题域来指定鉴别信息等等。但是,这些方法不在本文档的讨论范围。
代理(proxy)必须完全透明地处理原始服务器对用户代理(user agent)的鉴别,也就是说,它们必须在不做任何改动的前提下将WWW-鉴别和授权标题向前推送,这方面的规定见[2]的14.8节。代理-鉴别(WWW-Authenticate)和代理-授权(Proxy-Authorization)标题域都是hop-by-hop标题(见[2]的13.5.1节)。
2 基本鉴别方案(Basic Authentication Scheme)
用户代理必须对于每个领域(realm)通过用户标识(user-ID)及口令来对自身进行授权,这是基本授权方案的工作模式。Realm值应当被看作不透明的字符串,该值将用于同服务器端其它的realm值相比较。只有用户标识及口令通过受保护资源的认证,服务器才会给请求授权。授权参数没有可选项。
对于基本方案,上面所述框架的应用形式如下:
challenge = "Basic" realm
credentials = "Basic" basic-credentials
在接收到对受保护区域的未经认证的资源请求时,服务器应当回应一个质询(challenge),如下:
WWW-Authenticate: Basic realm="WallyWorld"
“WallyWorld”是由服务器分配的字符串,用于对请求URI所指定的受保护资源进行标识。代理也应使用使用Proxy-Authenticate标题域来回应同样的质询。
为了接收授权,客户端需要在基于64位(base64 [5])的证书中发送用户标识及口令,中间用冒号’:’分隔。
basic-credentials = base64-user-pass
base64-user-pass = <base64 [4] encoding of user-pass,
except not limited to 76 char/line>
Franks, et al. Standards Track [Page 5]
user-pass = userid ":" password
userid = *<TEXT excluding ":">
password = *TEXT
Userids可能是大小写敏感的。
如果用户代理希望发送用户标识”Aladdin”和口令“open sesame”,应当遵循下面的标题域形式:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
客户端应当假定请求URI中所涉及的所有其它路径都在由当前质询的基本realm值所指定的保护空间中。客户端在未收到服务器的其它质询时,可能会优先发送对应于该空间资源的授权标题。同样,当客户向代理(proxy)发送请求,它也可能在未收到代理服务器的其它质询之前,在代理授权(Proxy-Authorization)标题域中还使用原来的uerid和password。详情参见[安全考虑]的第4节中与基本鉴别相关的内容。
3 分类访问鉴别方案(Digest Access Authentication Scheme)
3.1 介绍(Introduction)
3.1.1 目的(Purpose)
“HTTP/1.0”中包括基本访问鉴别方案(Basic Access Authentication scheme[1])。该方案不是安全的用户鉴别方法,因为其用户名和口令在网络上是以明文方式传送的。本节提供不以明文方式发送口令的方案规范,参见”分类访问鉴别”。
分类访问鉴别(Digest Access Authentication)方案不是WWW安全问题的最终解决方案。该方案不提供消息内容的加密,其目的只是创建一个简单的鉴别方法,以弥补基本鉴别方案中存在的大部分严重漏洞。
3.1.2 操作概述(Overall Operation)
和基本访问鉴别相似,分类方案基于简单的挑战-回应范例。分类方案使用nonce值来质询(challenge)。合法的回应包含对用户名、口令、给定nonce值、HTTP方法、请求URI的校验和(checksum,缺省是MD5的校验和),因此,口令不会以明文方式传送。有些基本方案要求将用户名及口令预先排成一定的格式(不在本文范围)后再行使用。
Franks, et al. Standards Track [Page 6]
3.1.3 分类值的表示(Representation of digest values)
可选的标题,允许服务器指定用来创建校验和或分类的算法。MD5是缺省的方法,而且也是本文唯一提及的算法。
在本文中,128位的MD5分类由32个可打印的ASCII码字符表示。128位分类中的位按其重要性由高到低转换,在某个时刻每4位可用下面的ASCII表示。每4位都可用16进制字符‘0123456789abcdef’表示,也就是说,二进制0000由字符‘0’表示;0001由字符‘1’表示,以后如此类推,1111用‘f’表示。
3.1.4 局限性(Limitations)
本文中描述的分类鉴别方案存在许多已知的局限性,它只是对基本鉴别方案的替代,除此外,别无他用。它是基于口令认证的系统,在服务器端也要面对任何其它口令系统同样存在的问题。本协议并没有为最初用户和服务器间的口令建立提供安全做法。
用户和开发者都应注意,该协议并不象Kerberos或任何客户端的私钥方案那样安全。但是,即便它一无是处,总还比在telnet、ftp用的机制好一些,当然,也比基本方案安全。
3.2 分类标题的规范(Specification of Digest Headers)
分类访问鉴别方案在概念上与基本方案相似。更改的WWW-鉴别标题行和授权标题行的格式在下面给出。另外,还有个新的标题,即Authentication-Info,也在下面指定。
Franks, et al. Standards Track [Page 7]
3.2.1 WWW-鉴别回应标题(The WWW-Authenticate Response Header)
服务器在收到对受保护对象未经认证的访问请求时,会回应401(未授权)状态码。在分类方案中,WWW-鉴别标题应遵循如下写法:
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
上面表示值的意思如下:
realm
显示给用户看的字符串,这样他们就知道使用哪个用户名和口令了。该字符串应当包括至少一个执行鉴别的主机名和对可能访问用户群体的附加指示。例如:
registered_users@gotham.news.com
domain
指在引号中用空格分隔的URI列表(见RFC XURI[7]中定义的保护区间)。如果URI是采用绝对路径,它是相对于被访问服务器‘根’的URL(见上面1.2节)。该列表中的绝对URI被用来访问另外一个不同的服务器。客户端可发送同样的鉴别信息来访问由此列表确定的URI集合:任何URI,只要其做为前缀出现在列表中,就可以认为它指向同样的受保护区域。如果表示被忽略或是空值,客户端应这样理解,即,该保护区域由回应服务器的全部URI组成。
Franks, et al. Standards Track [Page 8]
该表示对代理-鉴别(Proxy-Authenticate)标题没有意义,因为对它们来说,受保护区域总是整个代理(proxy),如果出现,也会被忽略。
nonce
服务器端指定的数据字符,它应在每个401回应产生时,被唯一地创建。建议该字符以base64方式或16进制方式出现。另外,该字符在标题行中传递时是在引号内的,因此允许使用双引号字符。
其内容与实现无关,而其实现的质量取决于良好的选择。例如,nonce可能以基于64位编码来构造,如下例:
time-stamp H(time-stamp ":" ETag ":" private-key)
如上,时间戳(time-stamp)是由服务器产生的时间值或其它非重复值;Etag是HTTP 与请求实体相关的ETag标题的值;private-key是只有服务器才知道的值。在碰到这种形式的nonce时,服务器在收到客户鉴别标题后,会对哈希部分进行重新计算,并在nonce值与标题不符或其time-stamp值不够新时拒绝该请求。通过这种方式,服务器端可以限制nonce合法的时间范围。Etag中的内容将防止对资源的更新版本进行重复请求。(注意:在nonce中包括客户端的IP地址将向服务器提出要求,即不要再重用同样客户发出的nonce值。实际上,单个用户发出的请求会穿越多个代理,这样做可能导致该过程的中断。另外,IP地址也是可以假冒的)
有的实现可能会选择不接受先前先用的nonce或先前使用的分类,以防止回放式攻击(replay attack)。或者,实现在回应POST|PUT请求时,也可以选择以前的nonce或分类(digest)和GET请求的time-stamp。更详细的信息,见本文第4节。
nonce是客户端的opaque。
opaque
由服务器指定的字符串,客户端不能改动它,如果并发请求的URI也指向同一个受保护区间,则该信息将被加在这些请求的授权标题域中返给服务器。建议采用base64或16进制的字符串。
Franks, et al. Standards Track [Page 9]
stale
一个标志,用来指示客户端先前的请求因其nonce值过期而被拒绝。如果stale是TRUE(大小写敏感),客户端可能希望用新的加密回应重新进行请求,而不用麻烦用户提供新的用户名和口令。服务器端只有在收到的请求nonce值不合法,而该nonce对应的分类(digest)是合法的情况下(即客户端知道正确的用户名/口令),才能将stale置成TRUE值。如果stale是FALSE或其它非TRUE值,或者其stale域不存在,说明用户名、口令非法,要求输入新的值。
algorithm
是个字符串,用来指示用来产生分类及校验和的算法对。如果该域没指定,则认为是“MD5“算法。如果该域指定的算法无法理解,该质询(challenge)将被忽略。
在本文中,用KD(secret,data)来表示分类算法,其中data指数据,secret表示采用的方法.如果表示校验和算法时,data要写成H(data);而unq(X)表示将带引号字符串的引号去掉。
对于"MD5" 和"MD5-sess" 算法:
H(data) = MD5(data)
和
KD(secret, data) = H(concat(secret, ":", data))
也就是说,分类(digest)就是对secret与data通过冒号连接一起的结果进行MD5运算。而"MD5-sess"算法则允许其它第三方服务器参与鉴别。具体用法的区别,参见3.2.2.2节的描述。
qop-options
该表示是可选的,用于RFC2069[6]的向后兼容。它应当被与该分类方案版本兼容的任何实现所使用。如果存在,它是带引号的一个或多个字符组成的字符串,用来指示服务器支持的保护水平(quality of protection)值。”auth”值表示鉴别方式;”auth-int”表示鉴别保护的完整性;见后面为有该项选择的应用程序重新计算回应指示值。不能识别的选项必须被忽略。
Franks, et al. Standards Track [Page 10]