2016-02-25 153 views
1

問題微服務架構

問題怎麼可能創造一個微服務應用程序內的認證服務,並有其他服務覈對該令牌(JWT)和檢索用戶中智威湯遜認證?

可能的解決方案

我現在的想法是根據各地的權威性服務將{ token, user }成的Redis一旦用戶通過驗證。所有其他服務都可以在Redis中檢查用戶的Authorization: Bearer kdI8$dj$nD&...標頭令牌。

  • 如果token存在於Redis的,用戶被認證。
  • 如果在Redis中不存在token,則用戶未通過身份驗證。

enter image description here

  1. 用戶發送{ username, password }要權威性服務
  2. 驗證服務認證憑證,並檢索{ token, user }
  3. 驗證服務插入{ token, user }成Redis的
  4. 用戶使得請求Service-1{ token }
  5. 在Redis的3210個
  6. Service-1 loooks爲{ token }和檢索{ token, user }
  7. Service-1就執行併發送回{ data }

是否有任何可能的安全,邏輯或建築問題,這種做法?

+0

你不明確你的用戶在哪裏與服務有關,以及服務在哪裏與Redis的關係?特別是,我想知道你怎麼知道它在Redis中的檢查之間是同一個用戶。 (即不是用戶的jwt點,以證明他是誰) – akc42

+0

我已經清理了該圖並添加了一些流程步驟:-) – AndrewMcLagan

回答

2

你不明白爲什麼你想在Redis中存儲令牌。安全令牌通常包含有關用戶(聲明數據)的信息。如果您需要有關未存儲在令牌中的用戶信息,則應該能夠通過對用戶ID聲明的簡單數據庫查詢來查看該信息。

每個服務都可以通過檢查傳入的令牌digital signature(只需要簽名證書的公鑰),生存期(何時令牌到期),受衆(誰是令牌)等等來驗證傳入令牌。如果調用者呈現一個有效的令牌,該用戶被認證。

+0

儘管每個服務都必須具有身份驗證邏輯,國際海事組織非常不好的做法,因爲代碼將被複制,或在相同的情況下再次用不同的語言編寫。所以我真的想要避免這種方法? – AndrewMcLagan

+0

當然,每項服務都需要驗證碼。你通常會使用一個庫(通過一個NuGet包)來驗證令牌,但是如果你的服務是用不同的語言編寫的,那麼代碼確實會被複制。我沒有看到如何使用共享緩存確實改善了這一點。 – MvdD

+0

,因爲只有一個auth服務將認證用戶+令牌插入商店。該商店成爲認證的權威機構,其分佈式,集羣化和所有其他服務都可以訪問。在任何時候,我都可以更改auth服務中auth的執行方式。你描述你的方式堅持你的最初決定。 ? – AndrewMcLagan

0

使用這種方法,你將不得不在你所有的服務中驗證令牌,如果你沒有問題,那麼你可能沒問題。

訪問令牌可以有到期時間,這將使使用一個刷新令牌來獲取從身份驗證服務新的訪問令牌,有必要:

  • 當訪問令牌到期後你會返回一個401客戶端,您正在嘗試與之交談的服務X.
  • 客戶將不得不調用驗證服務提供一個刷新令牌,獲得新的訪問令牌
    • Finaly客戶端將再次與這個新的訪問令牌擊中X服務,有它驗證,並得到預期的從服務十

在我recent assignment響應我寫了一個微服務,代理所有請求驗證他們的標識,代理處理一切從登錄/ AUTH給角色和發送401的過期令牌和撤銷刷新令牌等我認爲這給了我不必處理所有服務中的令牌,而是將問題分離出來。然而,它當然會使代理成爲瓶頸,auth服務的自動縮放就是爲了解決這個問題。

另外,我沒有使用redis,但在accesstoken中存儲了散列鍵(由散列的accesstoken屬性+ salt組成),我可以通過重新篩查accesstoken + salt的其他屬性進行驗證。

重要提示:在上面我的代理刷新令牌的情況不僅會遇到負載無效/過期的accessToken,而在方案中的任何服務可以用無效的令牌來達到的,我不知道這是在你的特定情況下的任何關注,但它可能是值得一提的...

另一種方法是讓服務-A和服務-B調用驗證服務來驗證令牌,但這會推斷更多的流量因爲每個具有令牌的HTTP請求都必須經過驗證。在這種情況下,一個無效的令牌請求將到達您的服務X,並因此推斷它的一些負載...