2013-03-23 243 views
3

我正在創建一個網站.NET,它將爲其用戶提供特定的服務。讓我們稱之爲service1.com。將來,將有service2.com,他們將共享數據庫。我還希望通過提供Google,Facebook,Twitter +自定義註冊登錄(以防用戶不在Google中)等方式進行用戶友好認證,以便他們可以註冊。我將使用DotNetOpenAuth庫。所以場景與SO類似。OpenID提供商身份驗證代理

現在Google存在即時問題:它提供different claimed identifier for different realm - 這意味着我不能將其用作用戶的ID,但必須將電子郵件添加到圖片以解析用戶(like SO is doing)。

除此之外,它意味着我必須支持Facebook連接,Twitter和每個服務站點每增加登錄選項。

於是我想出了OpenID的代理的想法:

  • 我創建OpenID提供商openid.service.com有自己單獨的數據庫
  • service1.com和service2.com是其依賴方和份額自己的數據庫
  • openid.service.com可以在各種不同的方式驗證用戶:與openid.service.com (basic sign up like SO
    • 新帳戶)
    • 的OpenID(如Gmail,雅虎,...)
    • Facebook連接
    • Twitter的
    • ...
  • 登錄選項,並簽署了形式將顯示在iframe中每個服務的網站上(如SO註冊是)
  • 一次openid.service.com通過任何選項驗證用戶它提供權利標識符依賴方回調

所以最終的結果會是這個樣子:enter image description here

優點:

  • 服務可以使用從openid.service.com提供確定哪些用戶登錄聲稱標識符
  • 服務可以只需添加到所需的域
  • 添加更多的登錄選項是微不足道的,因爲openid.service.com處理它
  • 谷歌聲稱標識符不會改變,因爲openid.service.com處理認證

缺點:

  • 認證的鏈較長(服務不與谷歌直接進行身份驗證等)
  • ???

這是一個體面的方式來實現這樣一個系統,是否還有其他缺點呢?

回答

2

是的,這是一個合理的方法來解決這個問題。其實我認爲 StackOverflow做同樣的事情。不使用OpenID的人們的自定義用戶數據庫也將在openid.service.com上,所以實際上他們也會在這種情況下使用OpenID,儘管他們不知道它。

有一點要注意的是在您的例子openid.service.com將能夠斷言,從谷歌和其他原聲明的標識符,因爲二級的RP將不會從你的中介接受的說法,因爲它有對那些聲稱的ID沒有權力。相反,你可以做的是在你的openid.service.com和你的每個輔助RP之間進行一次no-authentication OpenID。是的,OpenID實際上有一個流程,其中沒有聲明標識符從OP傳遞到僅限RP的擴展。因此,您可以使用DotNetOpenAuth FetchRequestFetchResponse分機來請求您的輔助RP和您的中央服務之間用戶的實際claims_id。而輔助RP必須小心謹慎地接受來自中央RP的斷言。

這裏的輔助RP之間的代碼的草圖和您的中心之一:從openid.service.com

OpenIdRelyingParty rp; 
var request = rp.CreateRequest("https://openid.service.com/"); 
request.IsExtensionOnly = true; 
var fetchRequest = new FetchRequest(); 
fetchRequest.Attributes.AddRequired("http://openid.service.com/useridentity"); 
request.AddExtension(fetchRequest); 
request.RedirectToProvider(); 

步驟2的用戶RP請求認證:openid.service

步驟1。 COM,作爲OP,接收請求(作爲一個OP是一個巨大的repsonsibility ......這是由所有帳戶的一個非常不完整的樣本。您應該參考OpenIdProvider samples that are available。)

OpenIdProvider op; 
IRequest request = op.GetRequest(); 
/// ... 
IAnonymousRequest anonRequest = request as IAnonymousRequest; 
if (anonRequest != null) { 
    // The key part for this sample snippet is that you make sure the RP asking 
    // is one of your own, since you're not following the typical OpenID flow. 
    if (!IsWhiteListedRealm(hostRequest.Realm)) { 
     anonRequest.IsApproved = false; // reject all RPs that aren't in the whitelist 
    } else { 
     // Perhaps here is where you'll start your double role as an RP 
     // to authenticate the user if there isn't already a FormsAuth cookie. 
    } 
} 

return op.PrepareResponse(request).AsActionResult() 

步驟3:輔助RP收到來自您的代理OpenID服務的響應。

OpenIdRelyingParty rp; 
var response = rp.GetResponse(); 
if (response != null) { 
    if (response.Provider.Uri.Authority != "openid.service.com") { 
     throw new Exception(); // only assertions from our own OP are trusted. 
    } 

    if (response.Status == AuthenticationStatus.ExtensionsOnly) { 
     var fetchResponse = response.GetExtension<FetchResponse>(); 
     string claimedId = fetchResponse.GetAttributeValue("http://openid.service.com/useridentity"); 
     FormsAuthentication.RedirectFromLoginPage(claimedId); 
    } 
} 

這些樣品無法完成。上述內容並不適用於填補這些角色的網站的許多常規安全緩解措施。這僅僅是一個草圖,概述了您的應用在特定情況下應採取的一些額外步驟。

+0

非常感謝您對我的問題和輸入的檢查!你的片段會非常方便! – 2013-03-24 21:36:16

+0

還有一件事情我不完全清楚 - 所以我將使用OpenID作爲協議,它通過擴展將某種用戶標識傳遞給RP。我必須爲此實施全面的OP嗎? (有發現機制等,就像在樣本中...) – 2013-03-26 23:15:44

+1

好問題。由於你的OP永遠不會聲明一個聲明的ID,你不需要從樣本中設置user.aspx。但是您確實需要一個OP標識符,它是樣本中OP主頁返回的XRDS文檔。 – 2013-03-27 02:26:52