本文转自:http://tech.e800.com.cn/articles/2009/814/1250212319986_1.html
单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。 asp.net跨域单点登录分为: 1、跨子域单点登录。如 blog.a.com 和 info.a.com 这2个站点同属一个主域.a.com,实现跨子域单点登录很简单,可以利用cookie,设置Domain为”.a.com'即可,这里就不再赘叙。 2、完成跨域单点登录。如 www.a.com www.b.com 这2个站点之间实现共享一个身份验证系统,只需在一处地方登录,下面主要谈下这种方式的实现方法。 asp.net 跨域单点登录实现原理: 当用户第一次访问web应用系统1的时候,因为还没有登录,会被引导到认证中心进行登录;根据用户提供的登录信息,认证系统进行身份效验,如果通过效验,返回给用户一个认证的凭据;用户再访问别的web应用的时候就会将这个Token带上,作为自己认证的凭据,应用系统接受到请求之后会把Token送到认证中心进行效验,检查Token的合法性。如果通过效验,用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了。所有应用系统共享一个身份认证系统。认证系统的主要功能是将用户的登录信息和用户信息库相比较,对用户进行登录认证;认证成功后,认证系统应该生成统一的认证标志,返还给用户。另外,认证系统还应该对Token进行效验,判断其有效性。 所有应用系统能够识别和提取Token信息要实现SSO的功能,让用户只登录一次,就必须让应用系统能够识别已经登录过的用户。应用系统应该能对Token进行识别和提取,通过与认证系统的通讯,能自动判断当前用户是否登录过,从而完成单点登录的功能。 比如说,我现在有3个分站点和1个认证中心(总站)。当用户访问分站点的时候,分站点会发Token到验证中心进行验证。验证中心判断用户是否已经登录。如果未登录,则返回到验证中心登录入口进行登录,否之则返回Token验证到分站点,直接进入分站点。 如图所示: 上面是实现单点登录的原理图,下面介绍下如何用asp.net实现跨域单点登录: 一、新建网站 MasterSite,作为总站认证中心。配置web.config,采用form登录验证。 配置如下: <authentication mode=”Forms”> <forms name=”.AspxFormAuth” loginUrl=”Default.aspx” defaultUrl=”center.html” protection=”All” path=”/” timeout=”120”> </forms> </authentication> <authorization> <!--拒绝所有匿名用户--> <deny users=”?”/> </authorization> <authentication mode=”Forms”> <forms name=”.AspxFormAuth” loginUrl=”Default.aspx” defaultUrl=”center.html” protection=”All” path=”/” timeout=”120”> </forms> </authentication> <authorization> <!--拒绝所有匿名用户--> <deny users=”?”/> </authorization> 添加Default.aspx页面,用来进行登录。代码如下: HTML Code: <%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %> <!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN” ”http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> <html xmlns=”http://www.w3.org/1999/xhtml” > <head runat=”server”> <title>总站登录</title> </head> <body> <form id=”form1” runat=”server”> <div> <asp:Login ID=”Login1” runat=”server” OnAuthenticate=”Login1_Authenticate” UserName=”test”> </asp:Login> </div> </form> </body> </html> <%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %> <!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN” ”http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> <html xmlns=”http://www.w3.org/1999/xhtml” > <head runat=”server”> <title>总站登录</title> </head> <body> <form id=”form1” runat=”server”> <div> <asp:Login ID=”Login1” runat=”server” OnAuthenticate=”Login1_Authenticate” UserName=”test”> </asp:Login> </div> </form> </body> </html> Default.cs Code: using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Text; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { SSORequest ssoRequest = new SSORequest(); #region 验证 Post 过来的参数 //-------------------------------- // 请求注销 if (!string.IsNullOrEmpty(Request[”Logout”])) { Authentication.Logout(); return; } //-------------------------------- // 各独立站点标识 if (string.IsNullOrEmpty(Request[”IASID”])) { return; } else { ssoRequest.IASID = Request[”IASID”]; } //-------------------------------- // 时间戳 if (string.IsNullOrEmpty(Request[”TimeStamp”])) { return; } else { ssoRequest.TimeStamp = Request[”TimeStamp”]; } //-------------------------------- // 各独立站点的访问地址 if (string.IsNullOrEmpty(Request[”AppUrl”])) { return; } else { ssoRequest.AppUrl = Request[”AppUrl”]; } //-------------------------------- // 各独立站点的 Token if (string.IsNullOrEmpty(Request[”Authenticator”])) { return; } else { ssoRequest.Authenticator = Request[”Authenticator”]; } ViewState[”SSORequest”] = ssoRequest; #endregion //验证从分站发过来的Token if (Authentication.ValidateAppToken(ssoRequest)) { string userAccount = null; // 验证用户之前是否登录过 //验证 EAC 认证中心的 Cookie,验证通过时获取用户登录账号 if (Authentication.ValidateEACCookie(out userAccount)) { ssoRequest.UserAccount = userAccount; //创建认证中心发往各分站的 Token if (Authentication.CreateEACToken(ssoRequest)) { Post(ssoRequest); } } else { return; } } else { return; } } } //post请求 void Post(SSORequest ssoRequest) { PostService ps = new PostService(); ps.Url = ssoRequest.AppUrl; ps.Add(”UserAccount”, ssoRequest.UserAccount); ps.Add(”IASID”, ssoRequest.IASID); ps.Add(”TimeStamp”, ssoRequest.TimeStamp); ps.Add(”AppUrl”, ssoRequest.AppUrl); ps.Add(”Authenticator”, ssoRequest.Authenticator); ps.Post(); } /// <summary> /// 验证登录账号和密码是否正确 /// </summary> /// <param name=”userName”>登录账号</param> /// <param name=”userPwd”>登录密码</param> /// <returns></returns> private bool ValidateUserInfo(string userName, string userPwd) { //从数据库中读取,验证登录账号和密码 //略... return true; } protected void Login1_Authenticate(object sender, AuthenticateEventArgs e) { if (string.IsNullOrEmpty(Login1.UserName) || string.IsNullOrEmpty(Login1.Password)) { Page.RegisterClientScriptBlock(”Add”, ”<mce:script lanuage=”javascript”><!-- alert('用户名密码不能为空!'); // --></mce:script>”); return; } else if (ValidateUserInfo(Login1.UserName, Login1.Password) == false) { Page.RegisterClientScriptBlock(”Add”, ”<mce:script lanuage=”javascript”><!-- alert('用户名密码错误!'); // --></mce:script>”); return; } else { Session[”CurrUserName”] = Login1.UserName; Session.Timeout = 120; SSORequest ssoRequest = ViewState[”SSORequest”] as SSORequest; // 如果不是从各分站 Post 过来的请求,则默认登录主站 if (ssoRequest == null) { FormsAuthentication.SetAuthCookie(Login1.UserName, false); ssoRequest = new SSORequest(); //主站标识ID ssoRequest.IASID = ”00”; ssoRequest.AppUrl = ”SiteList.aspx”; ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”); ssoRequest.Authenticator = string.Empty; Response.Redirect(”SiteList.aspx”); } ssoRequest.UserAccount = Login1.UserName; //创建Token if (Authentication.CreateEACToken(ssoRequest)) { string expireTime = DateTime.Now.AddHours(3).ToString(”yyyy-MM-dd HH:mm”); Authentication.CreatEACCookie(ssoRequest.UserAccount, ssoRequest.TimeStamp, expireTime); Post(ssoRequest); } } } } using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Text; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { SSORequest ssoRequest = new SSORequest(); #region 验证 Post 过来的参数 //-------------------------------- // 请求注销 if (!string.IsNullOrEmpty(Request[”Logout”])) { Authentication.Logout(); return; } //-------------------------------- // 各独立站点标识 if (string.IsNullOrEmpty(Request[”IASID”])) { return; } else { ssoRequest.IASID = Request[”IASID”]; } //-------------------------------- // 时间戳 if (string.IsNullOrEmpty(Request[”TimeStamp”])) { return; } else { ssoRequest.TimeStamp = Request[”TimeStamp”]; } //-------------------------------- // 各独立站点的访问地址 if (string.IsNullOrEmpty(Request[”AppUrl”])) { return; } else { ssoRequest.AppUrl = Request[”AppUrl”]; } //-------------------------------- // 各独立站点的 Token if (string.IsNullOrEmpty(Request[”Authenticator”])) { return; } else { ssoRequest.Authenticator = Request[”Authenticator”]; } ViewState[”SSORequest”] = ssoRequest; #endregion //验证从分站发过来的Token if (Authentication.ValidateAppToken(ssoRequest)) { string userAccount = null; // 验证用户之前是否登录过 //验证 EAC 认证中心的 Cookie,验证通过时获取用户登录账号 if (Authentication.ValidateEACCookie(out userAccount)) { ssoRequest.UserAccount = userAccount; //创建认证中心发往各分站的 Token if (Authentication.CreateEACToken(ssoRequest)) { Post(ssoRequest); } } else { return; } } else { return; } } } //post请求 void Post(SSORequest ssoRequest) { PostService ps = new PostService(); ps.Url = ssoRequest.AppUrl; ps.Add(”UserAccount”, ssoRequest.UserAccount); ps.Add(”IASID”, ssoRequest.IASID); ps.Add(”TimeStamp”, ssoRequest.TimeStamp); ps.Add(”AppUrl”, ssoRequest.AppUrl); ps.Add(”Authenticator”, ssoRequest.Authenticator); ps.Post(); } /// <summary> /// 验证登录账号和密码是否正确 /// </summary> /// <param name=”userName”>登录账号</param> /// <param name=”userPwd”>登录密码</param> /// <returns></returns> private bool ValidateUserInfo(string userName, string userPwd) { //从数据库中读取,验证登录账号和密码 //略... return true; } protected void Login1_Authenticate(object sender, AuthenticateEventArgs e) { if (string.IsNullOrEmpty(Login1.UserName) || string.IsNullOrEmpty(Login1.Password)) { Page.RegisterClientScriptBlock(”Add”, ”<mce:script lanuage=”javascript”><!-- alert('用户名密码不能为空!'); // --></mce:script>”); return; } else if (ValidateUserInfo(Login1.UserName, Login1.Password) == false) { Page.RegisterClientScriptBlock(”Add”, ”<mce:script lanuage=”javascript”><!-- alert('用户名密码错误!'); // --></mce:script>”); return; } else { Session[”CurrUserName”] = Login1.UserName; Session.Timeout = 120; SSORequest ssoRequest = ViewState[”SSORequest”] as SSORequest; // 如果不是从各分站 Post 过来的请求,则默认登录主站 if (ssoRequest == null) { FormsAuthentication.SetAuthCookie(Login1.UserName, false); ssoRequest = new SSORequest(); //主站标识ID ssoRequest.IASID = ”00”; ssoRequest.AppUrl = ”SiteList.aspx”; ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”); ssoRequest.Authenticator = string.Empty; Response.Redirect(”SiteList.aspx”); } ssoRequest.UserAccount = Login1.UserName; //创建Token if (Authentication.CreateEACToken(ssoRequest)) { string expireTime = DateTime.Now.AddHours(3).ToString(”yyyy-MM-dd HH:mm”); Authentication.CreatEACCookie(ssoRequest.UserAccount, ssoRequest.TimeStamp, expireTime); Post(ssoRequest); } } } } 代码说明:验证分站post过来的Token请求,如果用户已经登录,则创建认证中心发往各分站的 Token验证,转向分站,否之则返回登录。若是直接登录主站则转向站点选择页面sitelist.aspx,选择你要登录的分站点。 如图: 二、新建站点1,代码如下: HTML Code: <%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %> <!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN” ”http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> <html xmlns=”http://www.w3.org/1999/xhtml” > <head runat=”server”> <title> 站点一</title> </head> <body> <form id=”form1” runat=”server”> <div> <br /> <br /> <asp:LinkButton ID=”LinkButton1” runat=”server” OnClick=”LinkButton1_Click”>返回主站</asp:LinkButton> <asp:LinkButton ID=”LinkButton2” runat=”server” OnClick=”LinkButton2_Click”>注销登录</asp:LinkButton></div> </form> </body> </html> <%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %> <!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN” ”http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> <html xmlns=”http://www.w3.org/1999/xhtml” > <head runat=”server”> <title> 站点一</title> </head> <body> <form id=”form1” runat=”server”> <div> <br /> <br /> <asp:LinkButton ID=”LinkButton1” runat=”server” OnClick=”LinkButton1_Click”>返回主站</asp:LinkButton> <asp:LinkButton ID=”LinkButton2” runat=”server” OnClick=”LinkButton2_Click”>注销登录</asp:LinkButton></div> </form> </body> </html> Default.cs code: using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Text; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { #region SSO 部分代码 SSORequest ssoRequest = new SSORequest(); if (string.IsNullOrEmpty(Request[”IASID”])) { ssoRequest.IASID = ”01”; ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”); ssoRequest.AppUrl = Request.Url.ToString(); Authentication.CreateAppToken(ssoRequest); Post(ssoRequest); } else if (!string.IsNullOrEmpty(Request[”IASID”]) && !string.IsNullOrEmpty(Request[”TimeStamp”]) && !string.IsNullOrEmpty(Request[”AppUrl”]) && !string.IsNullOrEmpty(Request[”UserAccount”]) && !string.IsNullOrEmpty(Request[”Authenticator”])) { ssoRequest.IASID = Request[”IASID”]; ssoRequest.TimeStamp = Request[”TimeStamp”]; ssoRequest.AppUrl = Request[”AppUrl”]; ssoRequest.UserAccount = Request[”UserAccount”]; ssoRequest.Authenticator = Request[”Authenticator”]; if (Authentication.ValidateEACToken(ssoRequest)) { //从数据库中获取UserId Session[”CurrUserName”] = Request[”UserAccount”]; Session.Timeout = 120; FormsAuthentication.SetAuthCookie(Request[”UserAccount”], false); Response.Write(string.Format(”{0},您好!欢迎来到site1, >> 访问<a href=”” mce_href=”””http://localhost/Site2/Default.aspx”>site2</a>”,ssoRequest.UserAccount)); } } ViewState[”SSORequest”] = ssoRequest; #endregion } } void Post(SSORequest ssoRequest) { PostService ps = new PostService(); //认证中心(主站)地址 string EACUrl = ”http://localhost/MasterSite/Default.aspx”; ps.Url = EACUrl; //ps.Add(”UserAccount”, ssoRequest.UserAccount); ps.Add(”IASID”, ssoRequest.IASID); ps.Add(”TimeStamp”, ssoRequest.TimeStamp); ps.Add(”AppUrl”, ssoRequest.AppUrl); ps.Add(”Authenticator”, ssoRequest.Authenticator); ps.Post(); } //注销登录 protected void LinkButton2_Click(object sender, EventArgs e) { FormsAuthentication.SignOut(); SSORequest ssoRequest = new SSORequest(); ssoRequest.IASID = ”01”; ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”); ssoRequest.AppUrl = Request.Url.ToString(); Authentication.CreateAppToken(ssoRequest); PostService ps = new PostService(); //认证中心(主站)地址 string EACUrl = ”http://localhost/MasterSite/Default.aspx”; ps.Url = EACUrl; ps.Add(”IASID”, ssoRequest.IASID); ps.Add(”TimeStamp”, ssoRequest.TimeStamp); ps.Add(”AppUrl”, ssoRequest.AppUrl); ps.Add(”Authenticator”, ssoRequest.Authenticator); ps.Add(”Logout”, ”true”); ps.Post(); } //返回主站 protected void LinkButton1_Click(object sender, EventArgs e) { if (Session[”CurrUserName”] != null) { Response.Redirect(”http://localhost/MasterSite/SiteList.aspx”); } } } using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Text; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { #region SSO 部分代码 SSORequest ssoRequest = new SSORequest(); if (string.IsNullOrEmpty(Request[”IASID”])) { ssoRequest.IASID = ”01”; ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”); ssoRequest.AppUrl = Request.Url.ToString(); Authentication.CreateAppToken(ssoRequest); Post(ssoRequest); } else if (!string.IsNullOrEmpty(Request[”IASID”]) && !string.IsNullOrEmpty(Request[”TimeStamp”]) && !string.IsNullOrEmpty(Request[”AppUrl”]) && !string.IsNullOrEmpty(Request[”UserAccount”]) && !string.IsNullOrEmpty(Request[”Authenticator”])) { ssoRequest.IASID = Request[”IASID”]; ssoRequest.TimeStamp = Request[”TimeStamp”]; ssoRequest.AppUrl = Request[”AppUrl”]; ssoRequest.UserAccount = Request[”UserAccount”]; ssoRequest.Authenticator = Request[”Authenticator”]; if (Authentication.ValidateEACToken(ssoRequest)) { //从数据库中获取UserId Session[”CurrUserName”] = Request[”UserAccount”]; Session.Timeout = 120; FormsAuthentication.SetAuthCookie(Request[”UserAccount”], false); Response.Write(string.Format(”{0},您好!欢迎来到site1, >> 访问<a href=”” mce_href=”””http://localhost/Site2/Default.aspx”>site2</a>”,ssoRequest.UserAccount)); } } ViewState[”SSORequest”] = ssoRequest; #endregion } } void Post(SSORequest ssoRequest) { PostService ps = new PostService(); //认证中心(主站)地址 string EACUrl = ”http://localhost/MasterSite/Default.aspx”; ps.Url = EACUrl; //ps.Add(”UserAccount”, ssoRequest.UserAccount); ps.Add(”IASID”, ssoRequest.IASID); ps.Add(”TimeStamp”, ssoRequest.TimeStamp); ps.Add(”AppUrl”, ssoRequest.AppUrl); ps.Add(”Authenticator”, ssoRequest.Authenticator); ps.Post(); } //注销登录 protected void LinkButton2_Click(object sender, EventArgs e) { FormsAuthentication.SignOut(); SSORequest ssoRequest = new SSORequest(); ssoRequest.IASID = ”01”; ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”); ssoRequest.AppUrl = Request.Url.ToString(); Authentication.CreateAppToken(ssoRequest); PostService ps = new PostService(); //认证中心(主站)地址 string EACUrl = ”http://localhost/MasterSite/Default.aspx”; ps.Url = EACUrl; ps.Add(”IASID”, ssoRequest.IASID); ps.Add(”TimeStamp”, ssoRequest.TimeStamp); ps.Add(”AppUrl”, ssoRequest.AppUrl); ps.Add(”Authenticator”, ssoRequest.Authenticator); ps.Add(”Logout”, ”true”); ps.Post(); } //返回主站 protected void LinkButton1_Click(object sender, EventArgs e) { if (Session[”CurrUserName”] != null) { Response.Redirect(”http://localhost/MasterSite/SiteList.aspx”); } } } 配置web.config <authentication mode=”Forms”> <forms name=”.AspxFormAuth” loginUrl=”Default.aspx” defaultUrl=”center.html” protection=”All” path=”/” timeout=”60”> </forms> </authentication> <authorization> <!--拒绝所有匿名用户--> <deny users=”?”/> </authorization> <authentication mode=”Forms”> <forms name=”.AspxFormAuth” loginUrl=”Default.aspx” defaultUrl=”center.html” protection=”All” path=”/” timeout=”60”> </forms> </authentication> <authorization> <!--拒绝所有匿名用户--> <deny users=”?”/> </authorization> 三、同二一样,新建站点Site2,代码如下: using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { #region SSO 部分代码 SSORequest ssoRequest = new SSORequest(); if (string.IsNullOrEmpty(Request[”IASID”])) { ssoRequest.IASID = ”02”; ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”); ssoRequest.AppUrl = Request.Url.ToString(); Authentication.CreateAppToken(ssoRequest); Post(ssoRequest); } else if (!string.IsNullOrEmpty(Request[”IASID”]) && !string.IsNullOrEmpty(Request[”TimeStamp”]) && !string.IsNullOrEmpty(Request[”AppUrl”]) && !string.IsNullOrEmpty(Request[”UserAccount”]) && !string.IsNullOrEmpty(Request[”Authenticator”])) { ssoRequest.IASID = Request[”IASID”]; ssoRequest.TimeStamp = Request[”TimeStamp”]; ssoRequest.AppUrl = Request[”AppUrl”]; ssoRequest.UserAccount = Request[”UserAccount”]; ssoRequest.Authenticator = Request[”Authenticator”]; if (Authentication.ValidateEACToken(ssoRequest)) { Session[”CurrUserName”] = Request[”UserAccount”]; Session.Timeout = 120; FormsAuthentication.SetAuthCookie(Request[”UserAccount”], false); Response.Write(string.Format(”{0},您好!欢迎来到site2, >> 访问<a href=”” mce_href=”””http://localhost/Site1/Default.aspx”>site1</a>”, ssoRequest.UserAccount)); } } ViewState[”SSORequest”] = ssoRequest; #endregion } } void Post(SSORequest ssoRequest) { PostService ps = new PostService(); //认证中心(主站)地址 string EACUrl = ”http://localhost/MasterSite/Default.aspx”; ps.Url = EACUrl; //ps.Add(”UserAccount”, ssoRequest.UserAccount); ps.Add(”IASID”, ssoRequest.IASID); ps.Add(”TimeStamp”, ssoRequest.TimeStamp); ps.Add(”AppUrl”, ssoRequest.AppUrl); ps.Add(”Authenticator”, ssoRequest.Authenticator); ps.Post(); } //注销登录 protected void LinkButton2_Click(object sender, EventArgs e) { FormsAuthentication.SignOut(); SSORequest ssoRequest = new SSORequest(); ssoRequest.IASID = ”02”; ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”); ssoRequest.AppUrl = Request.Url.ToString(); Authentication.CreateAppToken(ssoRequest); PostService ps = new PostService(); //认证中心(主站)地址 string EACUrl = ”http://localhost/MasterSite/Default.aspx”; ps.Url = EACUrl; ps.Add(”IASID”, ssoRequest.IASID); ps.Add(”TimeStamp”, ssoRequest.TimeStamp); ps.Add(”AppUrl”, ssoRequest.AppUrl); ps.Add(”Authenticator”, ssoRequest.Authenticator); ps.Add(”Logout”, ”true”); ps.Post(); } //返回主站 protected void LinkButton1_Click(object sender, EventArgs e) { if (Session[”CurrUserName”] != null) { Response.Redirect(”http://localhost/MasterSite/SiteList.aspx”); } } } using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { #region SSO 部分代码 SSORequest ssoRequest = new SSORequest(); if (string.IsNullOrEmpty(Request[”IASID”])) { ssoRequest.IASID = ”02”; ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”); ssoRequest.AppUrl = Request.Url.ToString(); Authentication.CreateAppToken(ssoRequest); Post(ssoRequest); } else if (!string.IsNullOrEmpty(Request[”IASID”]) && !string.IsNullOrEmpty(Request[”TimeStamp”]) && !string.IsNullOrEmpty(Request[”AppUrl”]) && !string.IsNullOrEmpty(Request[”UserAccount”]) && !string.IsNullOrEmpty(Request[”Authenticator”])) { ssoRequest.IASID = Request[”IASID”]; ssoRequest.TimeStamp = Request[”TimeStamp”]; ssoRequest.AppUrl = Request[”AppUrl”]; ssoRequest.UserAccount = Request[”UserAccount”]; ssoRequest.Authenticator = Request[”Authenticator”]; if (Authentication.ValidateEACToken(ssoRequest)) { Session[”CurrUserName”] = Request[”UserAccount”]; Session.Timeout = 120; FormsAuthentication.SetAuthCookie(Request[”UserAccount”], false); Response.Write(string.Format(”{0},您好!欢迎来到site2, >> 访问<a href=”” mce_href=”””http://localhost/Site1/Default.aspx”>site1</a>”, ssoRequest.UserAccount)); } } ViewState[”SSORequest”] = ssoRequest; #endregion } } void Post(SSORequest ssoRequest) { PostService ps = new PostService(); //认证中心(主站)地址 string EACUrl = ”http://localhost/MasterSite/Default.aspx”; ps.Url = EACUrl; //ps.Add(”UserAccount”, ssoRequest.UserAccount); ps.Add(”IASID”, ssoRequest.IASID); ps.Add(”TimeStamp”, ssoRequest.TimeStamp); ps.Add(”AppUrl”, ssoRequest.AppUrl); ps.Add(”Authenticator”, ssoRequest.Authenticator); ps.Post(); } //注销登录 protected void LinkButton2_Click(object sender, EventArgs e) { FormsAuthentication.SignOut(); SSORequest ssoRequest = new SSORequest(); ssoRequest.IASID = ”02”; ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”); ssoRequest.AppUrl = Request.Url.ToString(); Authentication.CreateAppToken(ssoRequest); PostService ps = new PostService(); //认证中心(主站)地址 string EACUrl = ”http://localhost/MasterSite/Default.aspx”; ps.Url = EACUrl; ps.Add(”IASID”, ssoRequest.IASID); ps.Add(”TimeStamp”, ssoRequest.TimeStamp); ps.Add(”AppUrl”, ssoRequest.AppUrl); ps.Add(”Authenticator”, ssoRequest.Authenticator); ps.Add(”Logout”, ”true”); ps.Post(); } //返回主站 protected void LinkButton1_Click(object sender, EventArgs e) { if (Session[”CurrUserName”] != null) { Response.Redirect(”http://localhost/MasterSite/SiteList.aspx”); } } } 对于tokent请求,tokent验证,需要对它进行加密、解密。 其它代码: Authentication.cs using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Collections.Generic; using System.Text; /// <summary> /// 安全验证类 /// </summary> public class Authentication { static readonly string cookieName = ”EACToken”; static readonly string hashSplitter = ”|”; public Authentication() { } public static string GetAppKey(int appID) { //string cmdText = @”select * from ”; return string.Empty; } public static string GetAppKey() { return ”22362E7A9285DD53A0BBC2932F9733C505DC04EDBFE00D70”; } public static string GetAppIV() { return ”1E7FA9231E7FA923”; } /// <summary> /// 取得加密服务 /// </summary> /// <returns></returns> static CryptoService GetCryptoService() { string key = GetAppKey(); string IV = GetAppIV(); CryptoService cs = new CryptoService(key, IV); return cs; } /// <summary> /// 创建各分站发往认证中心的 Token /// </summary> /// <param name=”ssoRequest”></param> /// <returns></returns> public static bool CreateAppToken(SSORequest ssoRequest) { string OriginalAuthenticator = ssoRequest.IASID + ssoRequest.TimeStamp + ssoRequest.AppUrl; string AuthenticatorDigest = CryptoHelper.ComputeHashString(OriginalAuthenticator); string sToEncrypt = OriginalAuthenticator + AuthenticatorDigest; byte[] bToEncrypt = CryptoHelper.ConvertStringToByteArray(sToEncrypt); CryptoService cs = GetCryptoService(); byte[] encrypted; if (cs.Encrypt(bToEncrypt, out encrypted)) { ssoRequest.Authenticator = CryptoHelper.ToBase64String(encrypted); return true; } else { return false; } } /// <summary> /// 验证从各分站发送过来的 Token /// </summary> /// <param name=”ssoRequest”></param> /// <returns></returns> public static bool ValidateAppToken(SSORequest ssoRequest) { string Authenticator = ssoRequest.Authenticator; string OriginalAuthenticator = ssoRequest.IASID + ssoRequest.TimeStamp + ssoRequest.AppUrl; string AuthenticatorDigest = CryptoHelper.ComputeHashString(OriginalAuthenticator); string sToEncrypt = OriginalAuthenticator + AuthenticatorDigest; byte[] bToEncrypt = CryptoHelper.ConvertStringToByteArray(sToEncrypt); CryptoService cs = GetCryptoService(); byte[] encrypted; if (cs.Encrypt(bToEncrypt, out encrypted)) { return Authenticator == CryptoHelper.ToBase64String(encrypted); } else { return false; } } /// <summary> /// 创建认证中心发往各分站的 Token /// </summary> /// <param name=”ssoRequest”></param> /// <returns></returns> public static bool CreateEACToken(SSORequest ssoRequest) { string OriginalAuthenticator = ssoRequest.UserAccount + ssoRequest.IASID + ssoRequest.TimeStamp + ssoRequest.AppUrl; string AuthenticatorDigest = CryptoHelper.ComputeHashString(OriginalAuthenticator); string sToEncrypt = OriginalAuthenticator + AuthenticatorDigest; byte[] bToEncrypt = CryptoHelper.ConvertStringToByteArray(sToEncrypt); CryptoService cs = GetCryptoService(); byte[] encrypted; if (cs.Encrypt(bToEncrypt, out encrypted)) { ssoRequest.Authenticator = CryptoHelper.ToBase64String(encrypted); return true; } else { return false; } } /// <summary> /// 验证从认证中心发送过来的 Token /// </summary> /// <param name=”ssoRequest”></param> /// <returns></returns> public static bool ValidateEACToken(SSORequest ssoRequest) { string Authenticator = ssoRequest.Authenticator; string OriginalAuthenticator = ssoRequest.UserAccount + ssoRequest.IASID + ssoRequest.TimeStamp + ssoRequest.AppUrl; string AuthenticatorDigest = CryptoHelper.ComputeHashString(OriginalAuthenticator); string sToEncrypt = OriginalAuthenticator + AuthenticatorDigest; byte[] bToEncrypt = CryptoHelper.ConvertStringToByteArray(sToEncrypt); string EncryCurrentAuthenticator = string.Empty; CryptoService cs = GetCryptoService(); byte[] encrypted; if (cs.Encrypt(bToEncrypt, out encrypted)) { EncryCurrentAuthenticator = CryptoHelper.ToBase64String(encrypted); return Authenticator == EncryCurrentAuthenticator; } else { return false; } } /// <summary> /// 创建 EAC 认证中心的 Cookie /// </summary> /// <param name=”userAccount”></param> /// <param name=”timeStamp”></param> /// <param name=”expireTime”></param> /// <param name=”cookieValue”></param> /// <returns></returns> public static bool CreatEACCookie(string userAccount, string timeStamp, string expireTime) { string plainText = ”UserAccount=” + userAccount + ”;TimeStamp=” + timeStamp + ”;ExpireTime=” + expireTime; plainText += hashSplitter + CryptoHelper.ComputeHashString(plainText); CryptoService cs = GetCryptoService(); byte[] encrypted; if (cs.Encrypt(CryptoHelper.ConvertStringToByteArray(plainText), out encrypted)) { string cookieValue = CryptoHelper.ToBase64String(encrypted); SetCookie(cookieValue); return true; } else { return false; } } /// <summary> /// 验证 EAC 认证中心的 Cookie,验证通过时获取用户登录账号 /// </summary> /// <param name=”userAccount”>输出用户登录账号</param> /// <returns></returns> public static bool ValidateEACCookie(out string userAccount) { userAccount = string.Empty; try { string cookieValue = GetCookie().Value; byte[] toDecrypt = CryptoHelper.FromBase64String(cookieValue); CryptoService cs = GetCryptoService(); string decrypted = string.Empty; if (cs.Decrypt(toDecrypt, out decrypted)) { string[] arrTemp = decrypted.Split(Convert.ToChar(hashSplitter)); string plainText = arrTemp[0]; string hashedText = arrTemp[1]; userAccount = plainText.Split(Convert.ToChar(”;”))[0].Split(Convert.ToChar(”=”))[1]; return hashedText.Replace(”