单点登录在asp.net中的简单实现
系统的基本架构
我们假设一个系统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 |
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 |
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 protected virtual void Initialize() protected override void OnInit(EventArgs e) |
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 == InSecurity) |
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。
转载自:http://www.cnblogs.com/oec2003/archive/2007/05/18/751016.html
单点登录在asp.net中的简单实现的更多相关文章
- SSO单点登录之Asp.Net实现示例
一.什么是单点登录SSO(Single Sign-On) SSO是一种统一 认知 和授权机制,指访问用同一服务器不同应用中的受保护资源的同一用户,只需登录一次,即通过一个应用中的安全验证 后,再访问其 ...
- BOE系统与BW系统间的单点登录(注:这里先简单写一下,改天有时间再进行详细的描述)
1,在BOE系统内进行配置,将BW系统内的用户信息导入BOE 2,在BOE系统内定义这些导入用户对BOE对象有哪些权限 3,用户使用BW系统的用户名密码登录BOE系统:BOE将登录凭证转发给BW系统让 ...
- 单点登录filter根据redis中的key判断是否退出
package com.ailk.biapp.ci.localization.cntv.filter; import java.io.IOException; import java.util.Has ...
- ASP.NET中最简单的自定义控件
ASP.NET用户控件一般适用于产生相对静态的内容,所以没有builtin的事件支持.本文讨论用户控件返回事件的方法. 假定用户控件(UserControl.ascx)中包含按钮控件 ...
- ASP.NET中Session简单原理图
刚学习Session,对session的理解相当肤浅,按照我的想法画了原理图,麻烦各位大神指正,谢了!
- 点单登录原理和java实现简单的单点登录
引用自:http://blog.csdn.net/zuoluoboy/article/details/12851725 摘要: 单点登录(SSO)的技术被越来越广泛地应用到各个领域的软件系统当中.本文 ...
- java实现简单的单点登录 (转)
摘要:单点登录(SSO)的技术被越来越广泛地运用到各个领域的软件系统当中.本文从业务的角度分析了单点登录的需求和应用领域:从技术本身的角度分析了单点登录技术的内部机制和实现手段,并且给出Web-SSO ...
- SSO 单点登录简单流程(cas)
配置服务端(链接数据库) 第一步: 下载cas-server端,解压开, 将中的解压开,将该包中的内容放入cas文件夹(新建文件夹)中 然后将这个文件夹放入到服务端的服务器(tomcat)中 将解压开 ...
- SSO单点登录解决方案[转载]
1 什么是单点登陆 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互 ...
随机推荐
- BroadcastReceive的使用
一.注册方式 intent.setAction("BC_One"); 1.静态注册 <receiver android:name = "继承BroadcastRe ...
- ubuntu 16.04 安装Tensorflow
ubuntu 16.04 安装Tensorflow(CPU) 安装python ubuntu 16.04自带python2.7,因此可以略过这一步 安装pip sudo apt-get install ...
- docker镜像基本操作一
获取镜像 首先说明一下如何从Docker hub中获取高质量的镜像,从Docker镜像库获取镜像的命令是docker pull .其命令格式为: docker pull [选项] [Docker Re ...
- zookeeper集群环境搭建详细图文教程
zookeeper集群环境搭建详细图文教程 zhoubang @ 2018-01-02 [文档大纲] 友情介绍 软件环境 注意点 环境安装 1. 新建用于存储安装包以及软件安装的目录 2. 下载安装z ...
- WebStorm 最新版本激活方式
WebStorm 最新版本激活方式:今天下载最新版本的WebStorm,发现原来的通过license server激活的方式,网上的已经失效. 找到一种最新的激活码,今天试了下,是有效的.记录下. 注 ...
- iOS----线程之间的通信
当线程的数量大于一个的时候,线程之间可能会产生通信,既一个线程产生的结果要被另一个线程用到. 比如常用的图片的加载就是这个样子.图片的加载是在子线程进行的,当图片加载完毕,就会回到主线程中刷新UI,展 ...
- (原创)定时线程池中scheduleWithFixedDelay和scheduleAtFixedRate的区别
scheduleAtFixedRate 没有什么歧义,很容易理解,就是每隔多少时间,固定执行任务. scheduleWithFixedDelay 比较容易有歧义 貌似也是推迟一段时间执行任务,但Ora ...
- js05
继续学习js,在这里我们主要讲述一下js的BOM(浏览器对象模型)以及一些js库和应用这些js库的方法. 1.浏览器对象模型(BOM): window对象: 表示浏览器窗口,所有的 ...
- vue 中使用 screenfull.js 全屏插件
参考网址: https://blog.csdn.net/houyibing930920/article/details/89214200 https://www.jianshu.com/p/cfbb1 ...
- IIS 8 配置错误
1) ProtocolException: The remote server returned an unexpected response: (405) Method Not Allowed Th ...
