2008-09-30 65 views
5

我們有一個基於用戶名和密碼處理授權的服務。我們不把用戶名和密碼作爲調用的一部分,而是放在SOAP頭中。這個WebService安全方案有哪些潛在的問題?

在典型的情況下,Web服務在執行開始時調用授權服務,以檢查是否允許調用者調用它。問題在於這些Web服務中的一些互相調用,這意味着在每個子調用中都會檢查用戶的權限,而且這可能非常昂貴。

我想要做的是讓授權服務在第一次調用後返回一個安全令牌。然後,Web服務不必每次都調用授權服務,而是可以在本地驗證安全標頭。

安全頭看起來像這樣(C#代碼 - 修剪來說明基本概念):

public sealed class SecurityHeader : SoapHeader 
{ 
    public string UserId;  // Encrypted 
    public string Password; // Encrypted; Just realized this field isn't necessary [thanks CJP] 

    public DateTime TimeStamp; // Used for calculating header Expiry 
    public string SecurityToken; 
} 

總的想法是,SecurityHeader獲取與每個呼叫檢查。如果它存在,尚未過期,且SecurityToken有效,則Web方法正常進行。否則,它將返回一個錯誤,或者它將嘗試重新授權並生成一個新的SecurityHeader SecurityToken基於UserId,Password和TimeStamp的鹽味散列。每天更換鹽以防止重放。

我所看到的一個問題是,用戶可能有權訪問Web服務A,但不能訪問Web服務B.如果他調用A並收到安全令牌,就像現在這樣,這意味着B會讓他如果他使用相同的標記。我必須對其進行更改,以便安全令牌僅從Web服務到Web服務而不是Web服務即用戶有效。如果用戶調用A調用B,應該是可以的,但如果用戶調用服務A然後調用服務D,則不是OK。解決此問題的方法是將一個公用密鑰(或一組密鑰)分配給邏輯上相關的服務。 (即,如果客戶可以做A,那麼他在邏輯上也可以做B)。

或者,我必須將用戶的整個權限集編碼爲安全性頭的一部分。我將不得不調查開銷是多少。

編輯:

幾個人都提到尋找其他安全方案,例如WS-Security和SAML等我已經有了。事實上,我從WS-Security獲得了這個想法。問題是其他方案不提供我需要的功能(緩存授權信息並防止沒有中間數據庫的重放)。如果有人知道一個方案,那麼我會反過來使用它。此外,這是關於認證的而不是。這是由我無法控制的另一種機制處理的。

如果事實證明無法緩存授權數據,那麼這意味着我只需承擔每個級別的授權開銷。

+0

SAML聲明如下所示: 「客戶端X具有角色A和B.此聲明在時間T有效,簽名,AuthService」。 這不是你所需要的? – ykaganovich 2008-10-05 22:18:31

+0

今天我將重新訪問SAML和XACML。 – ilitirit 2008-10-08 12:16:24

回答

1

就我個人而言,只要您有一個集中的底層框架來支持SecurityToken值的驗證,我不會看到您有任何問題。

2

好的,用我希望更好的替換舊的答案。

如果您有辦法在您的服務之間安全地共享數據,您所描述的內容應該可以工作。例如,如果您的服務與授權服務共享密鑰,則可以使用此密鑰來獲取鹽。順便說一句,我不知道足夠多的密碼來說明是否足夠安全地添加祕密鹽+散列(雖然看起來很好);但是,我很確定,使用祕密密鑰或私鑰對HMAC是安全的。旋轉鍵是一個好主意,所以你仍然有一個主密鑰並傳播一個新的簽名密鑰。 (a)你在每個服務中硬編碼散列邏輯,(b)服務可能希望從授權服務獲取更詳細的數據,而不僅僅是一個是/否的答案。例如,您可能希望授權服務將標頭中插入此用戶屬於角色A和B但不屬於C.

作爲一種替代方法,您可以讓授權服務創建一個包含任何有趣信息的新標頭有,並簽署該塊。

此時,我們正在討論單點登錄實施。您已經瞭解WS-Security規格。我描述的這個頭文件聽起來很像一個SAML斷言。

Here's an article關於使用WS-Security和SAML進行單點登錄。

現在,我不知道你是否需要所有這些...也有中間解決方案。例如,授權服務可以簽署原始用戶名塊;如果您擔心公/私密碼性能,並且您可以共享密鑰,您還可以使用密鑰來簽名而不是公鑰/私鑰。

4

您的方案的根本問題是您沒有使用標準框架或實施。這與您的方案本身的任何特殊優點無關。

原因很簡單,安全性(尤其是密碼學)非常非常複雜,幾乎不可能正確。使用一個強大,易於理解和證明的通用工具。

有關WS-Security的更多信息,請參閱:http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wss。大多數框架(.NET/JavaEE等)都會爲WS-Security提供內置支持(某種程度上)。

如果您認爲您的方案在某些方面比標準更好,我建議您將它寫成論文並提交給同行評審(以及參考實施),但不要用它來保護一個應用程序。在 我想你混淆身份驗證和授權一點,這是很容易做到的角色......

安全令牌(或類似)的卷:

編輯迴應OP編輯方案是驗證消息的發送者 - 基本上,他們應該是發件人。正如您正確地指出的那樣,身份驗證並不意味着發件人將授予訪問哪些底層資源。

授權是您通過認證的發件人並應用一些權限集以便限制訪問範圍的過程。通常,框架默認不會執行授權,您必須通過創建某種形式的ACL來啓用它,或者通過擴展某種「安全管理器」類型的界面來啓用它。

事實上,這個想法是,認證層會告訴你誰是試圖訪問頁,並離開它你來決定,如果該人被授權訪問頁面A.

你永遠不應該商店有關消息本身的權限和權限的信息 - 接收方應驗證針對每條消息的ACL(或數據庫或其他)的權限。如果有人想知道如何修改信息,這會限制你的曝光。

+0

你是否看到任何潛在的問題? – ilitirit 2008-10-02 10:55:38

0

首先,閱讀@CJP的帖子,他提出了一個很好的和有效的觀點。
如果你想繼續前進,把它卷反正自己(也許你有一個很好的理由),我會做以下幾點:

  • 你在談論的身份驗證服務,而不是授權服務。只是爲了確保你知道你在說什麼......?
  • 其次,你需要分開鹽(這不是祕密)和關鍵(是)之間。你應該有一個密鑰散列(例如HMAC)和salt(或者一個帶鍵的鹽味散列,聽起來像三明治一樣)。正如所指出的那樣,鹽不是祕密的,但應該爲每個標記而改變,並且可以包含在標題中;鑰匙必須是祕密的,每天更換都是好的。當然,請確保您使用強散列(如SHA-256),適當的密鑰管理技術,等等等等

同樣,我希望你重新考慮滾動你自己的,但如果你必須走出去在你自己的...

相關問題