單點登入:A B C三個網站登入其中任何一個網站,其他網站就無需登入。
我的實現思路:
使用cookie,因為cookie是存在用戶端的,A B C三個網站都可以對它進行存取。
架構如下:
AddCookie:儲存Cookie
LoginOutGo:刪除 Cookie
defualt:首頁
login:登入頁
loginOut:登出
wegconfig配置如下:
<appSettings> <!--帳號密碼--> <add key="acc" value="51aspx"/> <add key="pas" value="51aspx"/> <!--服務端憑證到期時間(分鐘)--> <add key="timeout" value="30"/> <add key="SignSite" value="http://localhost:49840/Public/AddCookie.aspx;http://localhost:50043/Public/AddCookie.aspx;http://localhost:50274/Public/AddCookie.aspx;"/> <add key="SignSiteOut" value="http://localhost:49840/Public/LoginOutGo.aspx;http://localhost:50043/Public/LoginOutGo.aspx;http://localhost:50274/Public/LoginOutGo.aspx;"/> </appSettings>
<authentication mode="Forms"> <forms loginUrl="/Login.aspx" name=".WebSite" protection="All" slidingExpiration="true" timeout="4320" path="/" defaultUrl="/default.aspx"></forms> </authentication>
登入過程:
輸入帳號和密碼:都是51aspx
點擊提交按鈕,提交按鈕點擊事件被觸發:
protected void btnSubmit_Click(object sender, EventArgs e) { Uri baseUri = new Uri(Request.Url.AbsoluteUri.ToString()); Uri absoluteUri = new Uri(baseUri, "/default.aspx"); //Response.Write(absoluteUri.ToString()); string fromurl = new Uri(baseUri,FormsAuthentication.DefaultUrl).ToString(); //起始 URL 路徑 if (string.IsNullOrEmpty(fromurl)) fromurl = absoluteUri.ToString(); string next = allLoginUrl; //摸擬使用者登入驗證(帳號、密碼於web.config中) //真實環境此處應通過資料庫進行驗證 if (this.txtAccount.Text == System.Configuration.ConfigurationManager.AppSettings["acc"] && this.txtPassport.Text == System.Configuration.ConfigurationManager.AppSettings["pas"]) { FormsAuthenticationTicket tk = new FormsAuthenticationTicket(1, this.txtAccount.Text, System.DateTime.Now, DateTime.Now.AddMinutes(double.Parse(System.Configuration.ConfigurationManager.AppSettings["timeout"])), false, "測試使用者資料"); string key = FormsAuthentication.Encrypt(tk); //得到加密後的身分識別驗證票字串 string url = next.Split(';')[0]; //從 URL 中拆分出將要跳轉的下一張頁面 next = next.Replace(url + ";", ""); //帶入下一輪跳轉的字串 //Response.Redirect(from); Response.Redirect(url + "?CookieTicket=" + key + "&FromUrl=" + fromurl + "&NextUrl=" + next); //跳至下一頁面 ////產生令牌 //string tokenValue = this.getGuidString(); //HttpCookie tokenCookie = new HttpCookie("Token"); //tokenCookie.Values.Add("Value", tokenValue); ////tokenCookie.Domain = "passport.com"; //Response.AppendCookie(tokenCookie); ////產生主站憑證 //object info = true; ////CacheManager.TokenInsert(tokenValue, info, DateTime.Now.AddMinutes(double.Parse(System.Configuration.ConfigurationManager.AppSettings["timeout"]))); ////跳回分站 //if (Request.QueryString["BackURL"] != null) // Response.Redirect(Server.UrlDecode(Request.QueryString["BackURL"])); } else { Response.Write("抱歉,帳號或密碼有誤!請在Web.config中配置帳號密碼!"); } }
跳轉連結URL為:http://localhost:49840/Public/AddCookie.aspx,參數略,AddCookie的Page_Load事件被觸發。
public partial class AddCookie : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { string from = Request["FromUrl"]; //起始 URL 路徑 string next = Request["NextUrl"]; //還需要跳轉的 URL string key = Request["CookieTicket"]; //已加密的 Cookie 文本 if(string.IsNullOrEmpty(from)) Response.Redirect(FormsAuthentication.DefaultUrl); if (key != null && key != "") { System.Web.HttpCookie ck = new HttpCookie(FormsAuthentication.FormsCookieName, key); ck.Path = FormsAuthentication.FormsCookiePath; ck.Expires = System.DateTime.Now.AddYears(10); Response.Cookies.Add(ck); //將傳過來的已加密的身分識別驗證票添加至客房端 Session["UserName"] = FormsAuthentication.Decrypt(ck.Value.ToString()).Name; string url = next.Split(';')[0]; //從 URL 中拆分出將要跳轉的下一張頁面 next = next.Replace(url + ";", ""); //帶入下一輪跳轉的字串 if (url != "") { Response.Redirect(url+"?CookieTicket="+key+"&FromUrl="+from+"&NextUrl="+next); } else //已沒有下一頁面可供跳轉 { Response.Redirect(from); //回到起始頁面 } } } }
跳轉連結URL為:http://localhost:50043/Public/AddCookie.aspx
就這樣跳轉到第三個網站的AddCookie,當url為空白時,參數略,跳到原始,即第一個網站的default頁。
登出過程:
直接清除cookie.
關於:AuthBase.cs【驗證是否登入】
namespace SSO.Public{ public class AuthBase { public bool CheckLogin() { bool flg = true; HttpCookie cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName.ToString()]; //FormsAuthenticationTicket tk = (FormsAuthenticationTicket)(cookie.Value); if (cookie == null) flg= false; else { string name = FormsAuthentication.Decrypt(cookie.Value.ToString()).Name; if (name != "51aspx") flg= false; } return flg; } }
原始碼下載:http://pan.baidu.com/netdisk/singlepublic?fid=1079743_1871944408