知识大全 .NET单点登陆的实现方法及思路

Posted

篇首语:古人已用三冬足,年少今开万卷余。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 .NET单点登陆的实现方法及思路相关的知识,希望对你有一定的参考价值。

.NET单点登陆的实现方法及思路  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

这篇文章介绍了 NET单点登陆的实现方法及思路 有需要的朋友可以参考一下 希望对你有所帮助  

  系统的基本架构 我们假设一个系统System包含Service客户服务中心 Shop网上购物中心和Office网上办公中心三个独立的网站 Service管理客户的资料 登录和注销过程 不论客户访问System的任何一个页面 系统都会转到登录界面 在用户登录后 系统会自动转会到客户上 次请求的页面 并且用户此后可以在System中无缝切换 不需要再次进行登录 即在System中实现单点登录SSO(Single Sign On) 我们知道 用户的即时状态通常是使用Application Session Cookie和存储的 而这些都是不能在程序中跨站点访问的 我们必需通过站点间相互通讯来确认用户的即时状态 简单的实现 第一步 假设用户访问了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的代码 Shop的Web config和Project cs 在Shop的Web config里 我们配置了Service站点和Shop站点 以方便我们在部署时方便修改

复制代码 代码如下: <appsettings> <add key="Service" value="//localhost: " /> <add key="WebSite" value="//localhost: " /> </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"];

   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" ); this Session Add("Pass" false); this Session Add("Security" ""); this Session Add("Url" "");

   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

   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( int MaxValue) ToString(); byte[] Value; UnicodeEncoding Code = new UnicodeEncoding(); byte[] Message = Code GetBytes(Security); SHA Managed Arithmetic = new SHA Managed(); 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("<>"); 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= height= 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("</>"); protected override void OnInit(EventArgs e) base OnInit(e); this CustomerValidate(); this Initialize(); this Response End();

   Service的Global cs 现在我们页面转到了Service的Validate页面 我们转过来看 Service的代码 在Global中我们同样定义了四个Session变量 都和Shop的Session用处类似 WebSite是保存请求用户即 时状态的站点信息 以便能在登录后返回正确的请求站点

复制代码 代码如下: protected void Session_Start(Object sender EventArgs e) this Session Add("UserID" ); this Session Add("Pass" false); this Session Add("WebSite" ""); this Session Add("Security" "");

   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); SHA Managed Arithmetic = new SHA Managed(); 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");

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

   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); SHA Managed Arithmetic = new SHA Managed(); 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("");

   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= height= src= + project service + "/Customer aspx"></iframe>"); cha138/Article/program/net/201311/14479

相关参考

知识大全 小技巧:在ASP.NET 中实现单点登录

小技巧:在ASP.NET中实现单点登录  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  由于某些原

知识大全 理解ASP.NET 2.0中的单点登录

理解ASP.NET2.0中的单点登录  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!摘要 

知识大全 单点登录在ASP.NET上的简单实现[4]

单点登录在ASP.NET上的简单实现[4]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 

知识大全 单点登录在ASP.NET上的简单实现[5]

单点登录在ASP.NET上的简单实现[5]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 

知识大全 单点登录在ASP.NET上的简单实现[3]

单点登录在ASP.NET上的简单实现[3]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 

知识大全 单点登录在ASP.NET上的简单实现[2]

单点登录在ASP.NET上的简单实现[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 

知识大全 单点登录在ASP.NET上的简单实现[1]

单点登录在ASP.NET上的简单实现[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!系统的基本

知识大全 asp.net 回车自动登陆设置

  的登陆页面中之前按回车老是不是自动登陆后来发现只需要修改formDefaultButton属性就可以了设置代码如下  [csharp]  <span>thisformDefaultBu

知识大全 ASP.NET 登陆代码注释

ASP.NET登陆代码注释  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  ///<summ

知识大全 ASP.NET 2.0防止同一用户同时登陆

ASP.NET2.0防止同一用户同时登陆  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  要防止同