分享
 
 
 

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

王朝asp·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

下载本文源代码

系统的基本架构

我们假设一个系统System包含Service客户服务中心、Shop网上购物中心和Office网上办公中心三个独立的网站。Service管理客户的资料,登录和注销过程。不论客户访问System的任何一个页面,系统都会转到登录界面,在用户登录后,系统会自动转会到客户上次请求的页面。并且用户此后可以在System中无缝切换。不需要再次进行登录。即在System中实现单点登录SSO(Single Sign-On)。

我们知道,用户的即时状态通常是使用Application、Session、Cookie和存储的。而这些都是不能在程序中跨站点访问的。我们必需通过站点间相互通讯来确认用户的即时状态。

简单的实现

如图所示,该图描述了用户访问System的流程。

第一步,假设用户访问了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>

在Project类里进行引用。

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"];

}

}

2、Shop的Global.cs

Shop的Global.cs定义了四个Session变量,UserID用来标识用户身份。Pass标识用户即时状态,Security用于保存往来Service和Shop的通讯不是被仿冒的。Url保存了上次请求的页面,以保证在用户登录后能转到用户请求的页面。

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", "");

}

3、Shop的Any.cs

Shop的Any.cs并没有包含代码,因为Any类从Page继承而来,为了代码分析方便,我们将代码集中到Page.cs中。

using System;

using System.Web;

namespace Amethysture.SSO.Shop

{

public class Any : Amethysture.SSO.Shop.Page

{

}

}

4、Shop的Page.cs

Page类有两个方法,CustomerValidate和Initialize。CustomerValidate用户检查用户的即时状态,而Initialize是页面登录后发送给用户的信息。我们的重点是CustomerValidate。

CustomerValidate是一个非常简单的流程,用条件语句检查Pass的状态,如果Pass为否,则表示用户没有登录,页面跳转到Service的Validate页面中。我们要分析的是其中保存的Url和递交的WebSite和Security几个参数。Url的作用在前面已经讲清楚了,只是为了保证用户登录后能回到原来的页面。而WebSite是为了保证该站点是被Service所接受的,并且保证Service知道是哪个站点请求了用户即时状态。因为这个例子是个简单的例子,在后面的Validate里没有验证WebSite是否是接受的请求站点,但是在实际应用中应该验证这一点,因为Shop和Service等同于服务器和客户端,服务器出于安全考虑必须要检查客户端是否是被允许的。Security是非常重要的一点。Shop对Service发送的是请求,不需要保证该请求没有被篡改,但是在Service应答Shop请求时就必须要保证应答的数据没有被篡改了。Security正是为了保证数据安全而设计的。

在代码中,Security是通过Hash一个随机产生的数字生成的。具有不确定性。和保密性。我们可以看到,Security同时保存在Session中和发送给Service。我们把这个Security当作明文。在后面我们可以看到,Security在Service经过再一次Hash后作为密文发送回Shop。如果我们将Session保存的Security经过同样的Hash方法处理后等到的字符串如果和Service返回的密文相同,我们就能够在一定程度上保证Service应答的数据是没有经过修改的。

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();

}

}

}

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("");

th

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有