2012-12-26 60 views
26

以下答案來自this問題;HTTP基本驗證代替TLS客戶端認證

獲獎答案根本沒有解決問題。它僅在數據傳輸的上下文中提及SSL,實際上並不包括身份驗證。

您確實在詢問有關安全認證REST API客戶端的問題。除非您使用TLS客戶端身份驗證,否則SSL本身不適用於REST API的可行身份驗證機制。沒有客戶端身份驗證的SSL僅對服務器進行身份驗證,這與大多數REST API無關。

如果您不使用TLS客戶端身份驗證,則需要使用類似基於摘要的身份驗證方案(如Amazon Web Service的自定義方案)或OAuth甚至HTTP基本身份驗證(但僅限於SSL)。

因此,考慮我會用HTTPS無客戶端認證 我這裏的問題是海報說,如果我們不使用客戶端SSL認證服務器並不知道它的人交談。我在這裏理解的是,如果我使用身份驗證令牌進行訪問,以根據服務器對客戶端進行身份驗證。然後服務器不知道誰發送令牌甚至如果該令牌與我的服務器數據庫中的用戶ID配對。

首先

1-這是一個真正的問題嗎?如果我特別使用Https?(沒有TLS客戶端認證)

2-和最重要的假設是一個重要的安全缺陷; Http基本認證如何在這裏提供海報幫助? Http基本身份驗證只是在頭中發送編碼的用戶名密碼。所以當客戶端收到一個令牌時(在他發送用戶名密碼後返回)那麼對於其餘的請求,他將在這個頭中使用這個令牌而不是密碼,並且突然間一切都好?

Still Server不知道請求來自哪裏,也許服務器有一個有效的令牌,在其數據庫中有一個匹配的用戶,但不知道誰真的是發送它。 (雖然我仍然很難看到這個令牌會被通過https盜取並被其他人使用!)

每當我提出這個問題時,我會得到回覆..「好吧..你發送一個令牌,但服務器不知道誰發送令牌,不是很安全「,所以我明白這一點,因爲瀏覽器保持一種認證,服務器知道請求來自正確的地方,那麼我可以確定帶有該令牌的配對用戶從我的DB)是「真正正確」

或者,也許我是什麼在這裏講是不正確的

回答

71

海報說如果我們不使用客戶端SSL認證服務器並不真正知道它與誰通話。

這不是我說的:)這就是我說的:

除非你使用TLS客戶端認證,SSL孤獨不是一個REST API一個可行的認證機制。

單獨是這裏的關鍵詞。另外:

如果不使用TLS客戶端身份驗證,則需要使用像一個基於摘要驗證方案(如亞馬遜Web服務的定製方案)或OAuth的,甚至HTTP基本身份驗證(但在僅限SSL)。

換句話說,TLS客戶端認證是一個認證REST API客戶端的方式。因爲最初的SO問題是關於SSL的具體問題,所以我提到TLS客戶端身份驗證是唯一的「內置」身份驗證形式,如果您僅依賴於TLS。因此,如果您使用的是TLS,並且您不使用TLS客戶端身份驗證,則您必須使用其他形式的身份驗證來驗證您的客戶端。

認證REST客戶端有很多方法。 TLS客戶端認證只是其中的一個(TLS唯一的「內置」,通常非常安全)。但是,TLS是網絡級別的協議,大多數人認爲對於許多最終用戶來說配置過於複雜。因此,大多數REST API產品選擇易於使用的應用程序-像HTTP一樣的級別協議,因爲它最容易使用(例如只設置HTTP標頭)。

因此,如果您要使用HTTP標頭路由,則必須使用標頭值來認證REST客戶端。

在HTTP身份驗證中,您有一個標頭Authorization及其值(標頭名稱相當不幸,因爲它通常用於身份驗證,而不是經常用於訪問控制,也稱爲授權)。所述Authorization頭值是什麼是由服務器使用以執行認證,並且它的三個令牌

  1. 一個HTTP認證方案名組成(通常),接着
  2. 空白(幾乎總是空格字符),然後是
  3. 特定於計劃的文本值。

一個常見的HTTP認證方案是Basic方案,這是非常......呃......基本:)。具體的方案文本值就是以下計算值:

String concatenated = username + ":" + raw_password; 
String schemeSpecificTextValue = base_64_encode(concatenated.toCharArray()); 

所以,你可能會看到對應首是這樣的:

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== 

服務器知道如何解析值。它說:「嘿,我知道Basic方案,所以我要採取尾隨的文本值,base64 解碼它,然後我會有用戶名和提交的密碼。然後我可以看到這些值是否匹配我儲存了。「

而這基本上是Basic身份驗證。因爲這個方案特別包含了提交的原始密碼base64編碼,所以它不被認爲是安全的除非你使用TLS連接。 TLS保證(大部分)窺探者的眼睛不能攔截標題(例如,通過數據包檢查)並查看密碼是什麼。這就是爲什麼你應該從來沒有使用HTTP基本認證,除非它是通過TLS連接。 總是 - 即使在公司內部網環境中。

當然還有其他更安全的HTTP身份驗證方案。一個示例是使用基於摘要的身份驗證的任何方案。

基於摘要的身份驗證方案更好,因爲它們的方案文本值爲而不是包含提交的密碼。相反,計算某些數據(通常是其他標題字段和值)的基於密碼的散列值,並將結果存入標頭值Authorization。服務器使用它本地存儲的密碼計算相同的基於密碼的哈希。如果服務器的計算值與請求的標頭值匹配,則服務器可以認爲請求已通過驗證。

這就是爲什麼這種技術更安全:只傳輸散列 - 不是原始密碼本身。這意味着即使通過明文(非TLS)連接,也可以使用這種技術來驗證請求(但如果請求數據本身並不敏感,那麼您只需要這樣做)。

一些基於摘要身份驗證方案:

Stormpath的和Amazon的是REST比OAuth的1.0A更安全,因爲他們總是驗證請求實體的有效載荷。 OAuth 1.0a僅對application/x-www-form-urlencoded內容執行此操作,這與使用application/xmlapplication/json有效內容(目前看來是大多數REST API)的REST API無關。

有趣的是,的OAuth2是摘要基於 - 它使用的東西,我認爲不太安全的,被稱爲「承載令牌」,這在我看來是有症狀的OAuth 2的various problems的。

最後,是的,這是一個無恥的插件,但如果你不想擔心這個東西,只需使用Stormpath(許多用例都是免費的)。我們自動化這些東西,所以你的應用程序不需要。

+0

謝謝!當你說「服務器知道如何解析這個值,它說」嗨,我知道基本方案,所以我要取文本值,base64解碼它,然後我將擁有用戶名和提交的密碼。然後我可以看到這些值是否與我存儲的值相匹配。「 – Spring

+0

這就是說,我的代碼實際上是在解析這個http頭部,而不是web服務器 – Spring

+0

使用摘要我以爲我必須使用」共享密鑰「客戶端和它會使事情變得複雜,但我看到我可以使用用戶密碼作爲密鑰,所以沒有額外的工作要做。更正@ – Spring

6

也許我誤解的問題。

您引用的答案對我說,如果您不使用某種認證形式,無論是客戶端證書,HTTP BASICAUTH還是其他內容,服務器都不知道與誰進行通信。

(也許這對你的應用程序沒問題,也許它不是,只有你可以回答。)

換句話說,如果你使用某種形式的認證,服務器確實知道它與誰進行通信;它正在與經過身份驗證的憑證所屬的「人員」進行通信。

在這種情況下,身份驗證是通過某些憑證建立身份的過程。

身份驗證不能保證憑證沒有被盜用。 SSL保證(我不會說它「保證」)證書在客戶端和服務器之間傳輸時是安全的。

當您使用GMail時,您使用的是SSL,Google如何知道它正在與對話

+0

tnx我更新了問題 – Spring

10

當我們談論「驗證用戶」時,我們真正的意思是「檢查用戶知道別人應該知道的東西」。這個「東西」可能是密碼,證書,硬件安全令牌,甚至用戶的視網膜模式,但是在所有情況下,我們真正檢查的信息是訪問,而不是用戶的身份(無論是真的手段)本身。

重點是,原則上,全部這些認證可能被盜用並用於模仿用戶。一個密碼可以被記錄下來,一張證書可以從存儲在其上的磁盤複製,一個硬件令牌可能被盜(可能被反向設計和克隆),甚至用戶的視網膜圖案原則上可以被掃描,記錄和僞造。我們所能做的最好的就是在每種情況下儘可能地使這個「非常困難」。