安全方面要满足的要求:
1. 只有通过身份验证的用户才能访问资源
2. 信息从收集、到存储、到展现,都要保证机密性和完整性
3. 防止未授权或而已客户滥用资源和数据
安全方面的话题包括但不限于:
身份验证、授权、机密性、完整性
一些常见问题已经成为HTTP的标准并得到实践
- 使用基本身份验证来验证客户端
- 使用摘要身份验证来验证客户端
- 使用三方OAuth (Three-Leged OAuth) 授权过程中的消费方、服务提供方和用户。
- 使用两方OAuth(Two-Legged OAuth) 不需要用户参与
- 处理URI中的敏感信息: 预防URI中信息被篡改
- 维护表述的机密性与完整性
1.基本身份验证
客户端试图访问受保护的资源时,服务器返回响应码401(Authorization Required)以及一个www-authenticate头
WWW-Authenticate:
Basic realm="Some name"
|
在客户端:将客户端标识(比如:用户名)和共享secret(比如:密码)以<identifier>:<secret>的形式连接起来,然后计算出这段文本的Base64编码值,将结果包含在客户端请求的Authorization头中。
Authorization: Basic <Base64编码后的值
|
在服务器端,将文本解码,验证secret是否一致。
类似基本验证和摘要验证这样的身份验证协议都使用了一种质询-应答(challenge-repsonse)协议。
服务器使用WWW-Authenticate头来质询客户端,要求提供一个答案。
如果客户端知道服务器针对某个资源要求基本验证,可以在每个请求里都带上Authorization头。
以免受到带WWW-Authorization头的401(Unauthroized)响应。
基本身份验证可以追述到HTTP1.0,后来由RFC2617来规定。其中客户端用Base64编码共享secret,并通过Authorization请求头将之提供出来。
Base64编码是可逆的,当客户端没有用TLS来连接服务器时,不要使用基本身份验证。
#请求
GET /photos HTTP/1.1 这儿不带身份信息
Host:
www.eaxmple.org
#响应
401 Unauthorized
WWW-Authenticate: Basic realm="Photos App" 一个带有质询的应答,要求提供身份信息
Content-Type: application/xml; charset=UTF-8
|
realm是一个字符串,标识服务器上的一块保护空间。
假设客户端用户标识为photoapp.001,共享secret是basicauth,客户端计算出photoapp.001:basicauth的base64编码,
用Authorization头发送请求:
#请求
GET /photos HTTP/1.1
Host:
www.eaxmple.org
Authorization: Basic
cGhvdG9hcHAuMDAxOmJhc2ljYXV0aA== 带身份信息的请求
#响应
HTTP/1.1 200 OK
Content-Type: application/xml; charset=UTF-8
|
验证的响应中含有敏感信息,因此要保证为该相应设置恰当的Cache-Control和Expires头。
比如,对于某个特定的客户端,使用Cache-Control:private
#响应
HTTP/1.1 200 OK
Cache-Control: max-age:3600, private
Vary: Authorization
Content-Type: application/xml;charset-UTF8
|
Authorization头可扩展。摘要身份验证和OAuth均使用Authorization来向服务器发送身份信息。
还有比如Amazon也使用这个 Authorization: AWS AWSAccessKeyId:Signature
2.摘要身份验证
也是由RFC2617来规定。同基本身份验证相似,不同之处:客户端发送身份信息的摘要给服务器。还提供了防止重放攻击的机制。
客户端发送不到Authorization的头请求来访问受保护资源时,服务器返回401,带有WWW-Authenticate头,Digest身份验证方案,至少还有realm和nonce指令。(nonce是一个数字或者令牌,只能使用一次或者有限次)
在客户端,包含一个Authorization头,其中包含客户端或用户标识符的摘要、realm和共享secret。
#请求
GET /photos HTTP/1.1 这儿不带身份信息
Host:
www.eaxmple.org
#响应
401 Unauthorized
WWW-Authenticate: Digest realm="Sample App" , nonce="6cf...fdfd", qop="auth"
Content-Type: application/xml; charset=UTF-8
<error xmlns:atom="http://www.w3.org/2005/Atom">
<message>Unauthorized</message>
</error>
这儿的Digest,之前是Basic(基本验证方案);包含质询和nonce应答
#请求
GET /photos HTTP/1.1
Host:
www.example.org
Autorization: Digest username="photoapp.001", realm="Sample app", nonce=
"6cf...fdfd",
uri="/photos", response="89fb...34", cnonce="c019...df43", nc=00000001, qop="auth"
带response指令的请求
#响应
HTTP/1.1 200 OK
Content-Type: application/xml; charset-UTF8
|
realm:一个字符串,标识服务器上一个受保护区域
nonce:每个401响应唯一生成的一个字符串,要求客户端在生成摘要的时候使用该值。nonce指令晚于某些nonce值时,服务器可以拒绝此类nonce指令的请求,用以房子重放攻击。
qop:有两个值可选auth和auth-int。auth的意思是服务器只在做客户端身份验证时使用摘要身份验证。auth-init时,客户端在计算摘要时要包含请求的正文,在维护请求完整性的时候也可以使用该验证方案。
这个例子里面:
客户端/用户表示是:photoapp.001
secret(密码):是digestauth
1. 先计算用户名、密码、realm的摘要:<identifier>:<realm>:<secret>,计算MD5,结果为A1
2. 把请求的方法和请求的URI连接<method>:<URI>,计算MD5,结果为A2
3. 把A1, nonce和A2连接为<A1>:<nonce>:<A2>,计算MD5
计算结果作为Authorization头中response的值。
nonce是服务器返回的,因此没有先获得WWW-Authenticate头,是无法发送Authorization头的。
服务器需要维护一个所有已使用令牌的日志。
WWW-Authenticate还可以包含其他指令,如domain,opaque,stale和algorithm。可参考<HTTP Developer's Handbook>
3.使用三方OAuth
http://oauth.net 2007年开发的一种委托身份验证协议。
使用OAuth协议,用户无需提供其身份信息,就可以让客户端去访问服务器上的个人数据。
三方:服务提供方(服务器)、OAuth消费方(客户端)和用户。
略
4.使用两方OAuth
类似于:客户端使用基本或者摘要身份验证,通过Authorization头向服务器提供其身份信息,没有代理介入。
OAuth规范中并没有规定这种身份验证方式,但被广泛使用。
略
5.处理URI中的敏感信息
要监测篡改,可以使用类似HMAC-SHA1和RSA-SHA1这样的算法来计算URI中数据的数字签名,将签名作为查询参数包含在资源URI中。
如果URI中是机密数据,可以先用AES、DES、Blowfish、Twofish等算法加密,然后base64编码。
当不能使用TLS时,服务器可以要求客户端将请求正文包含在签名里。此时,服务器为每个客户端分配一个标识符和共享secret,
用文档说明客户端生成签名的算法。
6. 维护表述的机密性与完整性
可以使用TLS,同时配置服务器,只允许哪些使用HTTPS的请求访问资源。
通过将HTTP至于TLS(RFC5246)协议上,无需再客户端和服务器代码中处理加密和摘要签名,就可以维护请求及相应消息的机密性。
配置TLS的细节是特定于Web服务器和客户端软件的,甚至子在不同语言间可能不同。
比如基于SOAP的web服务器需要依靠WS-Security。其中规定了安全令牌作为SOAP头来发送。
要避免篡改,基于SOAP的Web服务器要在SOAP消息头中加入一个签名。