2009-06-25 56 views
34

我在不同領域的幾個網站:example.comexample.orgmail.example.compassport.example.org。所有這些網站都有共同的外觀和感覺,並且 應該共享相同的用戶羣。透明的用戶會話(單點登錄+單簽收)

,在這種極端情況下我還是希望所有的網站透明(儘可能) 共享用戶會話具有以下關鍵特性:

  1. 單點登錄。當在passport.example.org用戶登錄和訪問 任何其他網站 - 他應該被視爲登錄

    登錄用戶得到「你好,$username「問候在網站標題和不同 導航菜單,列出的服務,他們有機會獲得。 。如果他沒有登錄,而是 的問候有「登錄」鏈接,指向passport.example.org/signon

    已知可信域列表,因此使用OpenID或使用一些自制輕量級協議實現 相當簡單。當用戶第一次點擊 網站時,我將他重定向到特殊的身份驗證端點passport.example.org, ,然後悄悄地將他重定向回來,其中包含身份信息(或「未簽名」 匿名身份)。對於大多數瀏覽器,這是完全透明的。 顯然,我使用nonce值來對抗重定向循環。

  2. 單次簽收。當用戶在下次訪問任何網站時在任何網站 的標題中單擊「簽出」時,應將其視爲「未登錄」。

    OpenID不是爲此設計的。我目前的想法(我已經有一個部分工作的實現) 實施)是發送不是用戶身份,而是發送「全局」會話令牌並在DB中共享全局會話表(global_session_token↔用戶關係)。

  3. 機器人和無Cookie用戶支持。網站有公共區域,用戶代理應該可以訪問 ,而不需要任何cookie支持。因爲這個原因,我在(1)中提到的重定向成爲一個問題,因爲對於每個單頁請求的 ,我最終會將user-agent引發到auth端點並返回。 這不僅會讓機器人感到困惑,而且會非常迅速地污染我的會話數據庫,其中包含 死亡會話。我絕對不想顯示「嘿, 你沒有啓用cookies,走開!」頁面,這是非常粗魯和 令人失望。雖然我需要Cookie支持才能登錄,但我希望用戶可以自由閱讀 網站的內容,等等 - 沒有任何限制。

    而且我明確地要求不要想要將會話ID放在URL中,除了我提到的一些透明的 跨域重定向。我相信這樣做是一個安全問題 ,通常只是一件壞事。

    在這裏,我幾乎沒有想法。

好吧,我知道這很難,但谷歌實際上這是否在某種程度上(google.comgoogle.批次的-gTLD的gmail.com等),對不對?所以這應該是 可能的。

我會爲任一協議描述的想法感激(這會是最好的),或者鏈接到 系統(或者代碼來讀取或只是住的網站觀看和學習時)已經 成功地實施這樣的事情。

總結:幾個域沒有共同的根,共享的用戶羣,單點登錄,單點登錄,沒有cookie需要匿名瀏覽。

所有的站點都在同一個網絡上(但在不同的服務器上),部分共享相同的PostgreSQL數據庫(在同一數據庫的不同方案中)。 大多數站點都是用Python/Django編寫的,但其中一些站點使用PHP和Ruby on Rails。當我想到框架和語言不可知的東西時,我很感激指向任何實現。即使我不能使用它們,如果我能夠明白它是如何完成的,那麼我可能會實現類似的東西。

+0

不,這並不難。這只是一個竅門,就像卡牌一樣。一旦你知道如何,這很容易。 :-) – 2009-06-25 11:21:18

回答

30

那麼,讓我進一步解釋一下。 (所有網址都是虛構的!)正如我所說的,訪問者去http://www.yourwebpage.com,並表示他想登錄。他被重定向到http://your.loginpage.org?return=http://www.yourwebpage.com/Authenticated,他將不得不提供他的用戶名和密碼。
當他的帳戶信息有效時,他將返回到登錄URL中提供的頁面,但帶有一個將用作ID的附加參數。因此,他轉到http://www.yourwebpage.com/Authenticated?ID=SharedSecret,其中SharedSecret是一個臨時ID,有效期爲30秒或更短。
當您的身份驗證頁面被調用時,頁面會調用yourwebpage.com和loginpage.org之間共享的方法來查找SharedSecret的帳戶信息以檢索更永久的ID。該永久ID存儲在yourwebpage.com的網絡會話中,不應向用戶顯示。
共享方法可以是任何東西。如果兩臺服務器位於同一臺計算機上,則它們都可以訪問同一個數據庫。否則,他們可能會通過Web服務與另一臺服務器通信。這將是服務器到服務器的通信,因此,如果用戶是機器人或沒有Cookie支持,則無關緊要。這部分不會被用戶注意到。
您唯一需要處理的是用戶的會話。通常,用戶將被髮送一個存儲在cookie中的會話ID,但它也可以作爲GET請求的一部分加入到URL中。不過,通過在表單中​​添加一個隱藏的輸入字段,將會話ID放在POST請求中會更安全一些。

幸運的是,一些Web開發語言已經提供了會話支持,所以您甚至不必擔心維護會話和發送會話ID。不過,這項技術很有趣。而且你需要意識到會話應該始終是臨時的,因爲存在會話ID被劫持的風險。

如果您必須處理不同域上的多個站點,那麼您需要先處理一些服務器到服務器的通信。最簡單的方法是讓他們共享相同的數據庫,但最好在此數據庫周圍構建Web服務,以獲得額外的保護。確保此Web服務僅接受來自您自己的域的請求,以添加更多保護。
當您有服務器到服務器的連接時,用戶將能夠在您的域之間切換,並且只要您將會話ID傳遞到新域,用戶就會登錄。如果用戶使用cookies,則會話不太可能丟失,這將需要重新登錄。沒有cookie,如果會話ID在瀏覽頁面之間丟失,用戶將不得不再次登錄以獲取新的cookie。 (例如,訪問者訪問Google,然後返回到您的網站,使用cookie,可以從cookie中讀取會話,如果沒有cookie,會話會丟失,因爲Google不會向前傳遞會話ID。

請記住,在不同域之間傳遞會話ID是一種安全風險,會話ID可能被劫持,從而使其他人冒充訪問者成爲可能,因此會話ID應該是短暫的並且是混淆的。但即使黑客獲得了會話ID的訪問權限,他仍然不能完全訪問該帳戶本身,他將無法攔截服務器到服務器的通信,因此他無法訪問數據庫用戶信息,除非他直接進入登錄頁面。

0

您使用的是ASP.NET嗎?如果是這樣,你可能想看看enableCrossAppRedirects屬性。

+0

嗯,我沒有使用ASP.NET。網站是用Python/Django(大部分),PHP和Ruby on Rails編寫的,但感謝您的建議!我會看看,如果這是我正在尋找的東西,我會盡力看到每當我可以找到或創建類似的東西。 – drdaeman 2009-06-25 10:51:35

5

AFAIK,Google只爲「Google.com」域使用Cookie。但谷歌也使用OpenID,它允許通用的登錄機制。基本上,這是通過將您重定向到特殊的登錄頁面來實現的。此登錄頁面會檢測您是否已登錄,如果您未登錄,則會要求您登錄。否則,它會將您直接重定向到下一頁。

因此,在您的情況下,用戶將打開somepage.example.com,該應用程序的會話沒有登錄ID。因此,它會將用戶重定向到用戶登錄的logon.example.biz。此頁面後面也將是一個會話,該會話將告知用戶已經登錄。(或者,在這種情況下,用戶必須)然後重定向用戶somepage.example.com?sessionid=something,其中sessionid將存儲在somepage.example.com的會話中。然後這個會話也會知道用戶已經登錄並且對於用戶來說它幾乎看起來是透明的。

實際上,用戶被重定向兩次。

+0

謝謝!唯一的問題仍然是如何處理機器人和用戶的Cookie支持被禁用或不可用。網站(somepage.example.com)有一個公開的部分,應該可以通過不使用的用戶和機器人訪問。重新定向它們,並創建新的永不使用的會話是一個問題。 – drdaeman 2009-06-25 11:38:26

+1

即使沒有cookie,谷歌也會投訴,並建議用戶打開cookie。否則,您的Google帳戶將無法使用。基本上,Web服務器需要在客戶端記住會話。有時候,你可以通過將會話作爲HTML頁面的一部分發送回postdata來解決這個問題,但Google的人只是告訴每個人打開cookie。 – 2009-06-25 13:40:25

+1

關於重定向,您不必在每個頁面上重定向用戶,只需在需要額外保護的頁面上重定向。在你的會話數據中,如果用戶登錄,你將存儲用戶ID,或者匿名訪問者和機器人。所有頁面都可以檢查會話中是否有用戶標識。但受保護的頁面會將用戶重定向到登錄頁面(如果它們未知),而所有其他頁面只保留匿名。 – 2009-06-25 13:43:34

1

如果您的所有應用程序都位於同一個域中,則不會太困難,因爲您可以使用域級Cookie來處理會話控制。 (無Cookie會話管理很困難,但可以完成,但很困難。)

但是,您在example.com域中指出了一些站點,而在example.org域中則指出了一些站點。

在我的google sigh-in和他們的orkut.com網站的其他網站上玩了一下,它看起來像當你點擊一個需要憑證的頁面時,它會將你重定向到一個通用的賬戶登錄站點,然後重定向你回到原來的網站,可能會在URL中傳遞某種會話令牌。據此,orkut.com服務器可能會直接與google.com服務器進行協商,以驗證令牌並獲取所需的任何其他用戶信息。

更多信息在域級別的Cookie作爲Reqeusted

如果你有兩個網站,說foo.example.combar.example.com,可以設置具體到主機的餅乾,但你也可以設置域將一個cookie被域中的所有主機看到。

所以,foo.example.com可以設置cookie爲foo.example.com具體而言,它會只把自己看到的,但它也可以設置cookie域example.com,當用戶進入bar.example.com他們也將看到這第二個cookie。

但是,如果你也有一個網站,snafu.example.org,不能看到這個域級別的Cookie是foo集,因爲example.orgexample.com是兩個完全不同的領域。

您可以使用域級cookie來維護同一個域中各站點的會話信息。

如何設置域級cookie取決於您的開發環境(我沒有使用rails的經驗,對不起)。

1

對於此解決方案,不需要passpor t服務器。

簽到

  1. 登錄
  2. 從你的域上的設置Cookie創建加密的會話ID和其他信息
  3. 顯示IMG與令牌令牌。

授權由餅乾

  1. 你已經對所有域的cookie。

登出

  1. 清除cookie的
  2. 銷燬會話
  3. 在DB最後的會話ID(我想你保存會話ID在用戶表通過cookie的上升會
  4. 關係明確的用戶ID )

我無法嘗試此解決方案。但是現在我和你有同樣的問題(SSO),明天我會試試這個。

0

我已經使用shibboleth,SSO方案和聯合身份驗證,但我認爲你需要更簡單的解決方案,上面提到的。

-4

一個跨域的rails插件來做到這一點很棒。

我想這樣做,我能想到的唯一方法是強制用戶下載工具欄或一些小型的空氣應用程序,它會自動爲我處理日誌記錄。

我很想知道另一種方式,因爲這種打擊