2010-08-28 151 views
43

我有一個Restful Web服務API,由不同的第三方使用。該API的一部分受到限制(您需要用戶名/密碼才能訪問它)。我想知道什麼是實現身份驗證的最佳方式?Restful Web服務身份驗證

我使用的是https,因此通信是加密的。我有兩個想法:

  • 在用戶開始使用(受限)服務之前,它使用POST發送用戶名/密碼(因爲正在使用https來加密憑據)。登錄成功後,服務器發回與此用戶名匹配的隨機一次性值(隨機數)。當發出下一個請求時,客戶端發送先前返回的現時值。服務器匹配用戶名和隨機數,並沿請求的數據返回新的隨機數。每個新請求都使用新的隨機數。基本上,這是一個Digest訪問認證的輕量級版本。
  • 由於此API是從第三方使用的,因此每個(受限)請求都可以使用用戶名/密碼。由於正在使用https,它們將被加密。這種方法的崩潰是這樣的事實,這不會是Restful兼容(POST會被永遠使用)。

我更接近選擇第一種方法(它是Restful兼容,相對容易實現,XML,JSON或HTML可以使用而不用改變任何東西),但我想看看你的意見是什麼?你有什麼建議:第一,第二或第三種方法?

順便說一句,我在服務器端使用Python。

回答

6

亞馬遜網絡服務做得很好,請查看一些思路的方法。從本質上講,他們可以讓客戶使用他們的密碼加密一個特殊的http頭。

這裏的鏈接:

我見過的API完成這件事(和方式我目前正在實施的話)

http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html

+0

最好的答覆任何措施。如果你可以在這裏給出一個很好的算法介紹,我相信你很快就會得到大量的票數!我認爲,其中最重要的一點是:「您首先使用您的祕密訪問密鑰來創建簽名密鑰,簽名密鑰的範圍是特定區域和服務,另外,簽名密鑰在創建後七天過期。簽名密鑰的範圍和生命週期是有限的,如果簽名密鑰受到威脅,數據的風險就會降低。「 – Domi 2015-04-22 16:08:42

23

一種方法是創建一個RESTful資源稱爲會議它通過創建一個POST它提供了一個用戶名和密碼。

這裏基本上我是如何實現的吧:

POST /sessions { Username: "User", Password: "Password" } 

創建一個有時間限制的會話,並返回一個包含會話密鑰值和到期的會話資源。您可能還希望將其作爲cookie值返回,以方便實現API客戶端。

DELETE /session/{id} 

立即過期會話,因此不能再使用。這用於顯式註銷。

然後我有用戶通過查詢參數附加會話密鑰,雖然你也可以允許它通過cookie值提交,我建議允許這兩個。

我更喜歡的是它非常簡單。

很顯然,你的場景將決定你的會話應該如何管理,或許它們不受時間限制和無限期限制,也許它們被散列或加密以增加安全性。

如果你在任何地方使用HTTPS,你可能不需要太擔心。但是,如果您要使用HTTP,則需要使用類似散列的密鑰以及密鑰,並說明時間戳以爲每個請求生成安全密鑰。通過這種方式,您可以通過HTTPS共享密鑰,然後切換到HTTP以進一步調用。即使有人設法從請求中嗅出密鑰,它幾乎可以立即過期並且無用。

聲明:我不是安全專家;-)。

+1

如果您在服務器上使用會話,那麼您的API不是RESTful,因爲服務器有一個狀態。每個請求應包含所有必要的數據,服務器不應依賴會話。將會話數據保存在客戶端在每個請求的標頭中發送的JSON Web令牌中。你可以在那裏打包一個序列化的用戶對象(這就是我如何做到這一點)。 – felixfbecker 2015-06-22 08:43:31

+0

這似乎有些迂腐,並且還認爲認證嚴格的「RESTful」很重要。像JWT這樣的方法確實可以解決這個問題,只要它對您的應用程序來說是必要的或重要的就可以這樣做。 – 2015-06-24 18:25:38

4

假設服務在瀏覽器從不消耗,通信被反正加密,我認爲沒有害處在第二方法的變形例:添加X-集管與每個請求發送用戶名/密碼,例如:

GET /foo HTTP/1.1 
Host: www.bar.com 
X-MyUsername: foo 
X-MyPassword: bar 

另一個想法是使用HTTP基本身份驗證,併發送一個Authorization: Basic base64(user:password)-標題。也就是說,如果連接始終是加密的。

+0

在這種情況下,你如何實現'登錄'和'註銷'? – 2013-07-25 09:48:09

+2

我認爲在這種情況下沒有「登錄」和「註銷」,因爲您在每個請求中都發送用戶名/密碼。 – 2013-10-01 20:11:36

+0

由於跨站請求僞造,基本身份驗證仍然不夠好。 – 2014-06-16 18:07:11

8

沒有理由不在這裏使用HTTP身份驗證。

也就是說,發佈POST時間塊隨機數的概念可以很好地工作。但是,這就是爲什麼你需要跳過這個額外的箍環的動機。

由於驗證用戶的實際花費(如果您不知道,可以調整bcrypt以顯着實時執行散列函數),因此在對原始密碼使用bcrypt散列時會考慮此技術。 。做出這樣的選擇是爲了使服務「登錄」一次使用密碼,該密碼將通過bcrypt經歷昂貴的驗證過程,並且然後將獲得時間阻塞的令牌以換取將繞過bcrypt過程的未來請求。

在bcrypt進程的情況下,使用HTTP認證,該服務可以使用正常密碼以及令牌。這樣用戶可以隨時使用密碼進行他們的服務,但這隻會變得昂貴。所以他們可以做到這一點,他們只是不應該。該服務不關心客戶端使用哪種認證技術。

隨機提供nonce服務以提高吞吐量。

除此之外,它是標準的HTTP身份驗證,但是採用了新的方案。

+1

不使用HTTP身份驗證的一個原因是,瀏覽器會隨每個請求自動發送該消息,從而使您受到CSRF攻擊。不過,使用自定義授權方案是可以的。或者使用自定義標題。 – 2014-06-16 18:06:42