解決辦法:
設置cookie的domain屬性。
詳細介紹:
把保存用戶登陸信息的cookie的域設置成一樣即可。usercookie.Domain=".xxx.com"; 要注意,在域名前必須要加一個"."。這個設置在登陸和退出的時候都需要。
比較普遍的做法自然是用一個專門負責用戶登陸的類來管理這些事務。這樣其他登陸頁面只要調用這個類就可以,一通百通。而如果你使用asp.net 2.0 和forms驗證,則有更簡單的辦法來完成這個設置。
web.config中添加了對域的支持,只要按照如下的設置即可:
<authentication mode="Forms">
<forms loginUrl="Login.aspx" domain=".xxx.com" name=".AutoLinkEduSiteCookie"/>
</authentication>
domain:可選的屬性。
指定在傳出 Forms 身份驗證 Cookie 中設置的可選域。此設置的優先級高於 httpCookies 元素中使用的域。 此屬性是 .NET Framework 2.0 版中的新屬性。默認值為空字符串 ("")。
注意
無論是哪一種辦法,cookie的name一定要相同。
引用內容
所謂的單一登錄是指用戶在一個站點如www.studyez.com登錄后切換到另一個站點communty.studyez.com時也自動 被community的Server判斷為已經登錄,反過來,只要用戶在community.studyez.com登出后,切換到 www.studyez.com時后www的Server也會判斷到這一用戶已經登出。
限制條件:
1.所有要求單點登錄的站點間共享同一用戶數據庫,這點應該不需要任何解釋的吧。
2. 要求所有站點在同一父域名之下。這里所說的單點登錄是指在同一個域名下不同子域名之間的單點登錄,直接的例子就是像這樣的站點之間的跨站單點登 錄: www.studyez.com, community.studyez.com, serach.studyez.com, mail.studyez.com, mms.studyez.com 等, 他們屬於一個共同的父域名studyez.com, 之所以有這么多子域名,是因為有很多子系統的時候用不同的子域名對於開發、部署和管理都能方便很多, 而且對於用戶訪問量很大的站點,可能每個子域名都會有很多的服務器來伺服。這是比較符合目前很多站點的模式和需求的。
對於非同一父域名下的域名間跨站登錄,最好的方式是采用Passport的原理來實現,具體實現可以參考Passport文檔,因此不在本文討論范圍之內。
原理:
在不同的子域名之間實現單點登錄的最佳途徑是采用Cookie的Forms認證。他的原理簡單的來說,就是讓Forms Authentication生成的Cookie能夠跨域名訪問。
先談一下Cookie的限制,對於一個任何Http Request來說,提交給Server端的時候,它能夠安全訪問的Cookie的域名必須在這個HTTP Reuqest的域名路徑中。舉例來說,發出一個http://communiy.corp.studyez.com/的 請求時,隨着這個http request一塊發送到server端的cookies會自動包括所有 以 community.corp.studyez.com, .corp.studyez.com, corp.studyez.com, .studyez.com, studyez.com 為域名的Cookies,這是由Cookie本身的規范所限制的,瀏覽器如果不是按照這個規范實現,那么就會存在嚴重安全漏洞,因為那樣的話意味着任何一 個服務器都可以讀到同一個用戶訪問別的網站時留下的Cookie。
根據上面所述Cookie的限制性,可以得出,對於前面 www.studyez.com, community.studyez.com等站點的例子來說,就是想辦法如何讓 Forms Authentication生成的Cookie的域名限定為.studyez.com或者studyez.com,而不是默認的 www.studyez.com 和 communty.studyez.com,這樣就使得單一登錄需求的實現成為可能。
今天先寫這么多,接下來幾天會繼續寫實現和局限性。
程序代碼// 用戶 Cookie 存儲鍵
public const string CookieUser = "devin_cn_user";
// 用戶Cookie名稱鍵
public const string CookieUserName= "UserName";
/// <summary>
/// 設置用戶 Cookie 信息
/// </summary>
/// <param name="UserName">用戶名稱</param>
/// <param name="CookieSave">Cookie有效時間選擇值</param>
private void SetCookie(string UserName,int CookieSave)
{
//設置Cookie值
HttpCookie cookie = new HttpCookie(CookieUser);
//設置域Cookie
cookie.Domain = ".devin.cn";
//設置用戶名稱
cookie.Values.Add(CookieUserName, UserName);
//設置Cookie身份驗證碼
cookie.Values.Add(CookieUserCode, this.CookieCode().ToString());
//根據選擇,設置Cookie有效時間
switch (CookieSave)
{
case 0:
cookie.Expires = DateTime.Now; //即時
break;
case 1:
cookie.Expires = DateTime.Now.AddDays(1); //一天
break;
case 2:
cookie.Expires = DateTime.Now.AddDays(7); //七天,一周
break;
case 3:
cookie.Expires = DateTime.Now.AddMonths(1); //一月
break;
case 4:
cookie.Expires = DateTime.Now.AddYears(1); //一年
break;
}
//在保存 Cookie 信息之前,刪除原有Cookie信息以避免重復
HttpContext.Current.Response.Cookies.Remove(CookieUser);
//保存Cookie信息
HttpContext.Current.Response.SetCookie(cookie);
//登陸認證
FormsAuthentication.RedirectFromLoginPage(UserName,false);
}
就是這一句吧
//設置域Cookie
cookie.Domain = ".devin.cn";