REST和认证
我们在设计REST(Representational State Transfer)风格的Web service API,有一个问题经常要考虑,就是如何设计用户认证的体系(Authentication).
比较传统的做法是首先有一个登陆的API,然后服务器返回一个session ID,后续的操作客户端都必须带上这个session ID,但是这样的,服务就变成了有状态了,不符合REST风格的原则。另外,由于负载均衡的存在,必须有公共存储来保存用户的Session,这也增加了系统的复杂度。
所以比较好的做法是每次都传递认证信息,这样系统就是无状态的,当然由于每次都需要认证,必然降低了一些效率,必要的时候要考虑缓存用户信息在服务器端。
有几点要注意:
1.密码不能传播
一个比较低级的错误是通讯时,由客户端传递用户名和密码到服务器端认证,这样很容易被黑客攻击造成密码泄露。
标准的做法是使用HMAC(Hash-based Message Authentication Code),想法就是不传播password,而传播content和password的混合hash值。我们来看看Amazon S3怎么做认证的。
Amazon对每一个用户有一个AWSAccessKeyId和一个AWSSecretAccessKey,每次HTTP请求需要一个Id和一个Autherticantion信息。 比如:
GET /photos/puppy.jpg HTTP/1.1
Host: johnsmith.s3.amazonaws.com
Date: Tue, 27 Mar 2007 19:36:42 +0000 Authorization: AWS 0PN5J17HBGZHT7JJ3X82: xXjDGYUmKxnwqr5KXNPGldn5LbA=
这个Authorization的头是这样产生的: 其中YourSecretAccessKeyID用的就是AWSSecretAccessKey。
Authorization = "AWS" + " " + AWSAccessKeyId + ":" + Signature;
Signature = Base64( HMAC-SHA1( UTF-8-Encoding-Of( YourSecretAccessKeyID, StringToSign ) ) );
StringToSign = HTTP-Verb + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedAmzHeaders +
CanonicalizedResource;
CanonicalizedResource = [ "/" + Bucket ] +
<HTTP-Request-URI, from the protocol name up to the query string> +
[ sub-resource, if present. For example "?acl", "?location", "?logging", or "?torrent"];
CanonicalizedAmzHeaders = <described below>
这样服务端就很容易根据用户信息来验证信息的正确与否。
2. 验证信息的位置
验证信息可以放在HTTP HEADER里面也可以放在HTTP URL里面,象这样:
GET /photos/puppy.jpg
?AWSAccessKeyId=0PN5J17HBGZHT7JJ3X82&Expires=1141889120&Signature=vjbyPxybdZaNmGa%2ByT272YEAiv4%3D HTTP/1.1
Host: johnsmith.s3.amazonaws.com
Date: Mon, 26 Mar 2007 19:37:58 +0000
放在HTTP HEADER里面的好处是URL比较干净整洁,适合放在internet与人分享,而放在URL里面则有利于发布私有的访问权限给第三方。
3. 如何防范重放攻击(Replay attack)?
理论上,黑客可以窃取你的通讯报文,然后重新发送来通过认证。有几种可能的solution.
a. 客户端所以向服务器申请一个随机数,然后这个随机数作为下次通讯的key,一旦使用过后就立即失效,也就是所谓的”一次一密”。这种方法的好处是很安全,但是增加通讯量,而且由于负载均衡的存在,必须有公共存贮保存这个key。
b.服务器端保存使用过的authertication信息,只要是使用过的就拒绝再次使用。这种方法不需要客户端支持,但是需要公共空间来保持历史记录。
c.使用时间戳。做法就是认证信息中含有时间信息,这样服务器端就可以拒绝时间相隔太长的请求,认为其已经过期。这种做法需要服务器端和客户端有某种形式的时间同步。
4.要不要使用HTTPS?
如果安全度要求很高或者是针对internet的API,无疑应该使用HTTPS,来避免内容被窃取的可能。
如果只是在局域网范围或者可信赖的计算环境,则使用HTTP来提高一点效率。
分享到:
相关推荐
仿淘宝其中的一种签名认证方式,可以有效的防止参数网络篡改,实现统一接口调用,代码简单易懂,适合新手学习签名认证,本人接触签名认证的时间也不长,有什么问题可以发私信一起交流
对数据进行HMAC-SHA256或HMAC-SHA1加密的C代码,VC2008工程。加密代码来自网络,进行了适当整合。
SHA256 和 HMAC-SHA256 的C语言实现,只有一个文件,无库依赖。使用方法见源码底部注释说明
支持在eDonkey和 eMule应用程序中使用的自定义哈希算法(基于MD4),支持 2 种计算模式:HASH/CHECKSUM和HMAC,支持 3 种输入数据格式:文件、文本字符串和 十六进制字符串,处理大文件(针对最大 15 GB 的文件进行了测试)...
hmac code in matlab encryption
HMAC-SHA1是一种安全的基于加密hash函数和共享密钥的消息认证协议。
HMAC-SHA256 implementation
C语言版的实现HMAC-SHA1和base64编码,已经对C++做了兼容处理,在VS下运行main.c代码,可以得到经过HMAC-SHA1处理后的结果,并且可以运行里面的base64编码函数得到想要的结果,可以用于连接阿里云MQTT
HMAC加密算法C语言版本,支持EVP_md5(), EVP_sha224, EVP_sha512, etc等
收集了一些RFC2104和hmac-sha1实现的资料,欢迎童鞋们一起学习。
python实现Hash和HMAC算法工程文件 Hash详解博客地址:https://blog.csdn.net/m0_52316372/article/details/125696086 HMAC详解博客地址:https://blog.csdn.net/m0_52316372/article/details/125696187
HMAC是哈希运算消息认证码 (Hash-based Message Authentication Code),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。HMAC-SHA1签名算法是一种常用的签名算法,用于对一段信息进行...
hmac-sha1.js文件下载。通过js给对应字段进行hmac的sha1加密解密的操作。
hmac 报文鉴别 c++实现 报文鉴别 MD5 hmac
针对我国远程电力监控通信系统的安全问题,提出了基于哈希认证码算法(HMAC)的安全方案。充分考虑了实时嵌入 式电网终端设备的局限性,设计和实现了数据来源真实性和数据完整性验证、用户身份认证、基于角色的操作...
sha256_Hmac加密; sha256_Hmac解密;
C#基于Hmac sha256及Hmac sha 512 做的对称加密解密
春天hmac休息 RESTfull Web服务示例的Spring HMAC身份验证过滤器。 ...Accept: application/json, application/*+json Content-Type: application/json Date: Thu, 29 Oct ...User-Agent: RestAPI client v.1.0 Content
java的md5计算,hmac256计算,请参考博客中提及的linux下c语言的md5,hmac256计算,与java运行的结果对比
asp版hmac_sha1加密方式,支持中英文,真正和PHP的hash_hmac加密结果完全一样,与java、php、python、js 一致,附对比。支持中文utf-8编码