
第一步,假设用户访问了Shop或Office的任何一个页面Any。该页面所在的网站将会检查用户的即时状态。如果用户已经登录了,则将Any页面的信息返回给用户。如果用户还没有登录,则自动转到Service的Validate页面,验证用户在Service状态。即Shop或Office向Service发出请求,要求Service返回用户的即时状态。
第二步,Validate验证用户的即时状态,如果用户已经登录了,则Service将用户的即时状态返回给Shop或Office的同步页面Synchronous,通知Shop或Office同步用户状态。如果用户没有登录,则自动转向Customer页面,提示用户登录。
第三步,用户完成登录过程,当用户成功登录后,自动转回Validate页面,通知Shop或Office的Synchronous进行用户状态的同步。
第四步,在用户状态同步完成后,在本地站点,用户状态成为在线状态,即可访问Any页面。
在上面的流程中。我们知道,不管用户访问哪个站点,用户只需要一次登录,就保证用户在Service的即时状态都是在线的,不会再需要进行第二次登录的过程。
现在我们的思路已经清楚,具体的实现我们将在代码分析中完成。
代码分析
从上面的流程中我们可以看出,系统中Shop和Office的代码是完全类似的。只要Shop可以实现,Office也可以同样的克隆。所以我们的重点分析的对象是Shop和Service的代码。
1、Shop的Web.config和Project.cs
在Shop的Web.config里,我们配置了Service站点和Shop站点,以方便我们在部署时方便修改。
<appsettings>
<add key="Service" value="http://localhost:8001" />
<add key="WebSite" value="http://localhost:8002" />
</appsettings>
using System;
using System.Configuration;
namespace Amethysture.SSO.Shop
{
public class Project
{
public static string Service = ConfigurationSettings.AppSettings["Service"];
public static string WebSite = ConfigurationSettings.AppSettings["WebSite"];
}
}
protected void Session_Start(Object sender, EventArgs e)
{
this.Session.Add("UserID", 0);
this.Session.Add("Pass", false);
this.Session.Add("Security", "");
this.Session.Add("Url", "");
}
using System;
using System.Web;
namespace Amethysture.SSO.Shop
{
public class Any : Amethysture.SSO.Shop.Page
{
}
}
using System;
using System.Web;
using System.Security.Cryptography;
using System.Text;
namespace Amethysture.SSO.Shop
{
public class Page : System.Web.UI.Page
{
private void CustomerValidate()
{
bool Pass = (bool) this.Session["Pass"];
if (!Pass)
{
string Security = "";
Random Seed = new Random();
Security = Seed.Next(1, int.MaxValue).ToString();
byte[] Value;
UnicodeEncoding Code = new UnicodeEncoding();
byte[] Message = Code.GetBytes(Security);
SHA512Managed Arithmetic = new SHA512Managed();
Value = Arithmetic.ComputeHash(Message);
Security = "";
foreach(byte o in Value)
{
Security += (int) o + "O";
}
this.Session["Security"] = Security;
this.Session["Url"] = this.Request.RawUrl;
this.Response.Redirect(Project.Service + "/Validate.aspx?WebSite=" + Project.WebSite + "&Security=" + Security);
}
}
protected virtual void Initialize()
{
this.Response.Write("<html>");
this.Response.Write("<head>");
this.Response.Write("<title>Amethysture SSO Project</title>");
this.Response.Write("<link rel=stylesheet type=\"text/css\" href=\"" + project.website + "/Default.css\">");
this.Response.Write("</head>");
this.Response.Write("<body>");
this.Response.Write("<iframe width=\"0\" height=\"0\" src=\"" + project.service + "/Customer.aspx\"></iframe>");
this.Response.Write("<div align=\"center\">");
this.Response.Write("Amethysture SSO Shop Any Page");
this.Response.Write("</div>");
this.Response.Write("</body>");
this.Response.Write("</html>");
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
this.CustomerValidate();
this.Initialize();
this.Response.End();
}
}
}
protected void Session_Start(Object sender, EventArgs e)
{
this.Session.Add("UserID", 0);
this.Session.Add("Pass", false);
this.Session.Add("WebSite", "");
this.Session.Add("Security", "");
}
private void CustomerValidate()
{
bool Pass = (bool) this.Session["Pass"];
if ((this.Request.QueryString["WebSite"] != null) && (this.Request.QueryString["WebSite"] != ""))
{
this.Session["WebSite"] = this.Request.QueryString["WebSite"];
}
if ((this.Request.QueryString["Security"] != null) && (this.Request.QueryString["Security"] != ""))
{
this.Session["Security"] = this.Request.QueryString["Security"];
}
if (Pass)
{
string UserID = this.Session["UserID"].ToString();
string WebSite = this.Session["WebSite"].ToString();
string Security = this.Session["Security"].ToString();
byte[] Value;
UnicodeEncoding Code = new UnicodeEncoding();
byte[] Message = Code.GetBytes(Security);
SHA512Managed Arithmetic = new SHA512Managed();
Value = Arithmetic.ComputeHash(Message);
Security = "";
foreach(byte o in Value)
{
Security += (int) o + "O";
}
this.Response.Redirect(WebSite + "/Synchronous.aspx?UserID=" + UserID + "&Pass=True&Security=" + Security);
}
else
{
this.Response.Redirect("Customer.aspx");
}
}
if (Pass)
{
if ((this.Session["WebSite"].ToString() != "") && (this.Session["Security"].ToString() != ""))
{
this.Response.Redirect("Validate.aspx");
}
else
{
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("Pass");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
}
}
else
{
this.Response.Redirect("Customer.aspx");
}
string InUserID = this.Request.QueryString["UserID"];
string InPass = this.Request.QueryString["Pass"];
string InSecurity = this.Request.QueryString["Security"];
string Security = this.Session["Security"].ToString();
if (Security != "")
{
byte[] Value;
UnicodeEncoding Code = new UnicodeEncoding();
byte[] Message = Code.GetBytes(Security);
SHA512Managed Arithmetic = new SHA512Managed();
Value = Arithmetic.ComputeHash(Message);
Security = "";
foreach(byte o in Value)
{
Security += (int) o + "O";
}
if (Security == InSecurity)
{
if (InPass == "True")
{
this.Session["UserID"] = int.Parse(InUserID);
this.Session["Pass"] = true;
this.Response.Redirect(this.Session["Url"].ToString());
}
}
else
{
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("数据错误");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
}
}
else
{
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("访问错误");
this.Response.Write("");
this.Response.Write("");
this.Response.Write("");
}
this.Response.Write("<iframe width=\"0\" height=\"0\" src=\"" + project.service + "/Customer.aspx\"></iframe>");