2010-01-31 97 views
11

我有一個應用程序與多個子域subone.parent.com,subtwo.parent.com。ASP.NET子域Cookie(父和一個子域)

我在parent.com/login上有一個登錄頁面。當用戶登錄時,我將它們重定向到基於他們所屬的適當域。這工作正常。

FormsAuthenticationTicket ticket = new FormsAuth... 
string encTicket = FormsAuthentication.Encrypt(ticket); 
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket); 
cookie.Domain = subone.parent.com 
Response.Cookies.Add(cookie) 

這正確地認證用戶subone.parent.com而不是subtwo.parent.com。但是我想要做以下事情。

如果用戶返回到parent.com,我想知道他們已登錄並將其重定向回subone.parent.com。

是否有完成此操作的最佳做​​法?或者我必須爲parent.com設置另一個cookie?

我在asp.net mvc工作,如果它很重要。

謝謝!

回答

5

您可以像跨越域一樣共享Cookie,但它不是直截了當的,例如here

另一種選擇是將cookie設置爲「.parent.com」,而不是明確指定子域,並使用cookie存儲子域的詳細信息。然後,您可以從任何子域訪問cookie(並且父母假設它的www.parent.com)。

如果你使用MVC,你可以很容易地創建一個自定義過濾器,並添加到www.parent.com控制器來檢查cookie的存在,如果是這樣重定向到cookie指定的子域。過濾器的進一步細節here

+0

我想你第二這裏的選項可能工作。我將域設置爲父級。我已將該子域添加到FormsAuthTicket用戶數據。我創建了一個CustomIdentity,它將在IsAuthenticated中根據用戶數據檢查當前域。你怎麼看? – Paul 2010-02-01 16:24:22

+0

15秒的鏈接似乎不應該去它應該在的地方.. – 2017-04-25 15:31:40

0

我會爲您顯示的域設置cookie,因爲它會在該特定域的Cookie中維護任何安全信息。您還可以在* .parent.com級別添加未加密的cookie,該cookie包含有關哪些域已通過身份驗證的信息。沒有真正的方法可以將它們聯繫在一起,但不使用可能的時間戳和應用程序之間的邏輯連接(即 - sub2的會話超時時間爲20分鐘,所以如果域+有效時間戳發生在父cookie中,它將是有效的,然而這是商業邏輯)。

我不確定域之間斷開連接的原因,但實際上您可能更喜歡使用加密文本後加密文本的單個cookie。 EG:

1)Sub1登錄,將parent.com cookie設置爲有效。將一段用戶數據發送到認證Web服務。

2)身份驗證服務將sub1識別爲發件人,對用戶數據進行加密並將其添加到自定義cookie對象。

3)自定義cookie對象在唯一分割字符(或序列)上構造一個複合字符串,並使其可用於服務方法。

4)使用表單加密的服務對整個票證進行加密並將其發送回原始登錄。

這樣每個服務器將能夠解密全局票證,但是每個數據片段將使用通用算法加密,但是基於服務器的鹽被加密。所以如果sub2嘗試從sub1讀取cookie數據,它會得到加密版本而不是原始數據。

+0

謝謝,如果我在.parent級別添加未加密的用戶cookie不能被更改/欺騙以允許訪問其他子域? – Paul 2010-02-01 15:48:23

+0

@Paul:分類。我建議2級加密。第一種是默認的FormsAuthentication加密,它可以將整個Cookie保密爲* .parent.com域。第二種是應用於Cookie的每個私有部分的內部加密,其中鹽只有在主服務器和個人服務器之間才知道。每個子域都可以訪問整個cookie,但他們將無法解密屬於不同子域的部分。 FormsAuthentication.IsAuthenticated會導致一個「true」值。 – 2010-02-01 16:09:53

+0

@Paul:繼續 - 考慮到這一點,您需要用驗證實際cookie本身數據的東西來增強此檢查。 IsAuthenticated && MyCookieData.IsValid(票)或類似的東西。 – 2010-02-01 16:10:45

0

您可以在所有子域上共享相同的會話。這是我們用來完成Page_Load方法裏面那個:-)

void MasterPage_Unload(object sender, EventArgs e) 
{ 
    ///ASP.NET uses one cookie per subdomain/domain, 
    ///we need one cookie for _all_ subdomains. 
    if (Context.Response.Cookies["ASP.NET_SessionId"] == null) 
     return; 

    var sessionCookie = new HttpCookie("ASP.NET_SessionId", Context.Session.SessionID); 
    sessionCookie.Domain = ".yourdomain.com" ; 
    Context.Response.SetCookie(sessionCookie); 
} 

代碼:

Unload += MasterPage_Unload; 

它的偉大工程:-)

羅伯特

+0

感謝Robert,但我不希望用戶在所有子域上進行身份驗證,只有一個和根。 – Paul 2010-02-01 15:45:54

+0

我們遇到了這個解決方案的一個嚴重問題:它保持'OutputCache'在所有使用該代碼的MasterPage的頁面上工作。 [此解決方案](http://stackoverflow.com/a/2088853/177710)使OutputCache像一個魅力一樣工作。 – Oliver 2012-01-24 22:44:07