Restful HMAC认证
我們在設計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>?這樣服務端就很容易根據用戶信息來驗證信息的正確與否。?
驗證信息的位置?
驗證信息可以放在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里面則有利于發布私有的訪問權限給第三方。?
如何防范重放攻擊(Replay attack)??
理論上,黑客可以竊取你的通訊報文,然后重新發送來通過認證。有幾種可能的solution.?
客戶端所以向服務器申請一個隨機數,然后這個隨機數作為下次通訊的key,一旦使用過后就立即失效,也就是所謂的”一次一密”。這種方法的好處是很安全,但是增加通訊量,而且由于負載均衡的存在,必須有公共存貯保存這個key。?
b.服務器端保存使用過的authertication信息,只要是使用過的就拒絕再次使用。這種方法不需要客戶端支持,但是需要公共空間來保持歷史記錄。?
c.使用時間戳。做法就是認證信息中含有時間信息,這樣服務器端就可以拒絕時間相隔太長的請求,認為其已經過期。這種做法需要服務器端和客戶端有某種形式的時間同步。?
4.要不要使用HTTPS??
如果安全度要求很高或者是針對internet的API,無疑應該使用HTTPS,來避免內容被竊取的可能。?
如果只是在局域網范圍或者可信賴的計算環境,則使用HTTP來提高一點效率。?
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Restful HMAC认证的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构与算法总结(完结)
- 下一篇: 软件过程