当前位置:编程学习 > C#/ASP.NET >>

单点登录在ASP.NET上的简单实现(3)

答案:     5、Service的Global.cs
  
    现在我们页面转到了Service的Validate页面,我们转过来看Service的代码。在Global中我们同样定义了四个Session变量,都和Shop的Session用处类似。WebSite是保存请求用户即时状态的站点信息。以便能在登录后返回正确的请求站点。
  
  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", "");
  }
  
    6、Service的Validate.cs
  
    首先,将Shop传递过来的参数保存到Session中。如果用户没有登录,则转到Customer页面进行登录。如果用户已经登录了。则将用户即时状态传回给Shop站点。如上所述,这里将Security重新Hash了一次传回给Shop,以保证数据不被纂改。
  
  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");
   }
  }
  
    7、Service的Customer.cs和Login.cs
  
    Customer主要的是一个用于登录的表单,这里就不贴出代码了。这里分析一下Login的一段代码,这段代码是当登录是直接在Service完成的(WebSite为空值),则页面不会转到Shop或Office站点。所以应该暂停在Service站点。系统如果比较完美,这里应该显示一组字系统的转向链接。下面我们看到,当Pass为真时,页面转回到Validate页面,通过上面的分析,我们知道,页面会转向Shop的Synchronous页面,进行用户状态的同步。
  
  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");
  }
  
    8、Shop的Synchronous.cs
  
    好了,我们在Service中完成了登录,并把用户状态传递回Shop站点。我们接着看用户状态是怎么同步的。首先,如果Session里的Security是空字符串,则表示Shop站点没有向Service发送过请求,而Service向Shop发回了请求,这显然是错误的。这次访问是由客户端伪造进行的访问,于是访问被拒绝了。同样Security和InSecurity不相同,则表示请求和应答是不匹配的。可能应答被纂改过了,所以应答同样被拒绝了。当检验Security通过后,我们保证Serive完成了应答,并且返回了确切的参数,下面就是读出参数同步Shop站点和Service站点的用户即时状态。
  
  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("");
  }
  
    9、Shop的Page.cs
  
    我们知道,页面在一段时间不刷新后,Session会超时失效,在我们一直访问Shop的时候怎么才能保证Service的Session不会失效呢?很简单,我们返回来看Shop的Page.cs。通过在所有Shop的页面内都用<iframe>嵌套Service的某个页面,就能保证Service能和Shop的页面同时刷新。需要注意的一点是Service的Session必须保证不小于所有Shop和Office的Session超时时间。这个在Web.config里可以进行配置。
  
  this.Response.Write("<iframe width=\"0\" height=\"0\" src=\"" + project.service + "/Customer.aspx\"></iframe>");
  
    总结
  
    一次完整的登录完成了。我们接着假设一下现在要跳到Office的Any页面,系统会进行怎样的操作呢?Any(用户没有登录)->Validate(用户已经登录)->Synchronous(同步)->Any。也就是说这次,用户没有进行登录的过程。我们通过一次登录,使得Service的用户状态为登录,并且不管有多少个网站应用,只要这些网站都保证符合Shop的特性,这些网站就都能保持Service的用户状态,同时能通过Service获得用户的状态。也就是说我们实现了SSO。
  
  
  

上一个:在VS.NET 2005中体验clickonce技术(1)
下一个:单点登录在ASP.NET上的简单实现(2)

CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,