2015-02-11 18 views
1

我想討論一個常見的場景:一個應用想要授權使用多個OAUTH提供商的用戶,例如Facebook,Google +或Twitter。如何使用多個OAUTH提供程序在App Engine上安全地註冊用戶?

基本上這個問題已經在兩年前在這裏問過Mobile API Authentication Using Existing Web App with Multiple OAuth Providers並且沒有答案,所以我會詳細說明一下。 (我將使用Facebook作爲OAUTH2提供程序的示例,因此這不會變得過於通用。)

本質上,用戶註冊的工作方式如下:OAUTH/OAUTH2提供程序通常會提供一個工作流程,其中一個(通常是短期的)令牌是通過移動設備上的AccountManager或登錄對話框(如「使用Facebook登錄」按鈕)從提供商處獲得的。然後通過調用REST端點(在主體中或作爲附加頭,從不在URL中)將令牌傳送到App Engine。

提供商的AppId和AppSecret(這裏是:Facebook)存儲在App Engine上,App Engine將這些添加到令牌中,然後將其發送回Facebook以換取(長期)令牌。

此時,客戶端應用程序和App Engine應用程序都確信用戶之前已通過Facebook進行過身份驗證。另外,如果使用端點身份驗證來驗證呼叫,則App Engine可能具有該用戶的Google憑據和/或該應用程序的ClientId,Google會保證該請求是來自正確的客戶端應用程序。

此時,我們可以嘗試在我們的數據存儲中找到用戶,並讓註冊失敗(或者在用戶靜默登錄),如果它已經存在,或者創建記錄。

直到這裏,我很確定我走在正確的軌道上。現在問題來了:

讓我們來看看這個數據存儲。假設我們有兩個實體:

  1. 用戶實體,其中我們自己的系統中的每個用戶都在唯一的用戶標識下注冊。
  2. 賬戶實體,其中每個賬戶都被註冊並且userId字段指向用戶實體。

在關係數據庫術語中,我們會說我們在用戶和帳戶之間有1:n的關係。

對於我們系統中的每個用戶,我們保留用戶記錄。在上面的例子中,我們可能有兩個帳戶:Facebook和Google,這兩個帳戶都指向用戶,以及唯一的Facebook或Google ID /電子郵件用作帳戶標識符。

從技術上講,現在應用程序可能會在後續請求中使用Facebook或Google帳戶。但是我們必須在每個請求中存儲和查找第三方標記,因爲我們無法自己解密。我們可以要求提供者這樣做,但這也沒有多大意義。另外,我們必須在每次請求時將提供商的帳戶ID轉換爲我們自己的用戶ID。

爲了解決這個問題,我最可能要麼創建自己的令牌,要麼設置我們自己的OAUTH提供程序,它創建一個由我們自己的系統簽名的令牌,並且唯一的用戶ID用作標識符,並且只使用該令牌在隨後的請求中。

  • 這是一個很好的方法嗎?有人使用不同的更好的工作流程嗎?有人看到這種設計的安全缺陷嗎?

本質上,它的工作原理圍繞谷歌的端點系統,但谷歌只能對自己的系統進行身份驗證,所以如果我們想要提供的登錄使用進一步提供商,我們需要解決這個問題,如果有人知道一個除工作流,我們可以保留兩者,但是我們有問題,我們可以/應該只在「授權」標頭中添加一個令牌,而REST原則阻止我們使用自定義標頭來發送更多的令牌。

回答

1

當您的應用程序對用戶進行身份驗證時,會將對象存儲在包含已用於訪問應用程序的oauth提供程序的會話中,並且還可以選擇使用用於後續請求的令牌。

現在,您可以在每次調用服務器時檢查此對象。如果該對象不存在 - 用戶未通過身份驗證,則重定向到登錄頁面。如果有物體存在,拿一個令牌並使用它。

我使用類似的方法進行多個身份驗證選項,而不僅僅是oauth。除了我不需要在用戶通過身份驗證之後存儲令牌 - 我在應用程序中沒有用處。

+0

我同意,將oauth提供程序信息和我自己的令牌包裝到會話中非常明智。這允許來回發送多個身份片段。我假設你用只有服務器知道的服務器端密鑰加密會話,否則oauth提供程序和我自己的用戶id/token可能被黑客分隔並重新組合,如果我不做交叉檢查(這將需要數據存儲讀取)錯誤的FB令牌可能與錯誤的用戶ID匹配,我的服務器可能會接受它。我能看到這個嗎? – 2015-02-11 20:14:39

+0

我一直在閱讀,並決定使用智威湯遜。如果我將不同的身份部分作爲索賠放置,簽名將確保所有索賠的完整性。 @AndreiVolgin,感謝您指引我朝着正確的方向發展。 – 2015-02-12 01:11:07

相關問題