序:前几天不小心吃饭咬到舌头,发炎,话讲不清楚,吃饭吃不下,,也不想弄其他东西,博文也好几天没有更新,买了点中药,吃了几天舌头好多,想想赶紧把博文补上。这是毕业设计的一篇论文。目的是要实现单点登录的功能。个人理解和实现的单点登录:两个业务系统(业务系统是已经存在的,需要将业务系统融入到当中,如何修改业务系统的代码,下面会有说)A、B,一个认证服务中心SSO。
一开始拿到手,几乎什么思路都没有,然后就上网各种搜索资料,看Demo,看他们说的头头是道,但是到自己实现的时候,却不能达到功能。一次偶然,看到了惠普的一个Demo。链接http://www.ssodemo.com/。用户名和密码都是ssodemo。登录进去看了之后,看到了这个页面,顿时来了点灵感。
这个是某一个用户的对应的表单,我将这个表进行改进
其中IDNum是用来标识用户的唯一ID,SystemID是业务系统的编号。
看一下我的测试数据:第一个Record的涵义就是:IDNum为3200..00的人,在业务系统1里面的用户名是jiwei,密码是1,他在此业务系统中的状态是不在线的。SSO中,需要对用户能够进入某一个业务系统找一个权限进行管理,至于进入业务系统之后的跳转和SSO无关。
这个是单点登录中不同用户的登录和注销的过程。对于普通用户,如果从业务系统A登录,那么将Username和Password在SSO进行认证,成功之后,返回到原来的业务系统A中,然后实现具体的操作,当然,用户也可以直接从SSO登录,这个时候,则返回用户的一个业务系统的列表。
在BizSystem表中,记录着业务系统的相关信息。
下面是各个字段的字段名、字段类型、说明。
下面是具体的一个流程图。
用户访问业务系统,检查用户的状态(Session),如果用户已经登录,那么则进行访问,如果尚未登录,那么就跳转到业务系统的登录界面。(这边我实现了一个额外的功能,那就是如果用户某一段时间已经登录过其他的业务系统,即用户在SSO中进行过了验证,那么这个时候,就把登录界面的Username和Password进行自动的填写)将Username和Password递交到SSO进行验证,同时递交的还有EncryKey密钥,当时是出于安全性的考虑,在业务系统和SSO中都记录了某一个业务系统的一个密钥或者叫KEY,就是标识业务系统的唯一ID。然后按照流程图一步一步的走。
差不多逻辑想好,就要开始Coding了。
将刚刚说到的各表都设计成实体类,其中涉及到外键约束的可以看我的另外一个帖子。数据库文件设计了SQL-Server、XML(主要是一些配置信息的存放)、Excel(用户的导入导出等)。
这个里面最核心的就是跨域的传值了,网络上也有好多方法,这边我讲一个我自己的方法。
首先说一下为什么要跨域传值,比方说这个时候,用户【张三】登录了业务系统【A】,那么这个时候用户的部分信息是用Cookie存放的,虽然Cookie技术是一个浏览器端的技术,但是Cookie是有自己的作用范围的。具体可以看看博客园的几篇帖子。
地址1:http://www.cnblogs.com/lingyi/archive/2012/03/01/2375581.html
地址2:http://www.cnblogs.com/youring2/archive/2012/03/25/2416954.html
说白了就是,如果【张三】这个时候需要登录业务系统【B】,但是【A】和【B】又不在同一个域或者是顶级域和子域名的关系,那么这个时候,Cookie是不能实现共享的。那我想到的是,利用SSO这个系统来进行一个过渡,【张三】在SSO中设置的Cookie,再从SSO中读出来那是可以的。
第二:利用Iframe来实现跨域的传值。下面分别是RedCookie和WriteCookie的代码。
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.UI;
- using System.Web.UI.WebControls;
- namespace SSO.Web
- {
- public partial class RedCookie : System.Web.UI.Page
- {
- private static string url = "";
- protected void Page_Load(object sender, EventArgs e)
- {
- if (Request.QueryString["URL"] != null)
- {
- url = Request.QueryString["URL"].ToString();
- }
- else
- {
- url = "";
- }
- }
- protected string GetIDNum()
- {
- //Request.Cookies["IDNum"].Value = "320000000000000000";
- if (Request.Cookies["IDNum"] != null)
- {
- return Server.HtmlEncode(Request.Cookies["IDNum"].Value);
- }
- else {
- return "0";
- }
- }
- protected string GetURL()
- {
- return url;
- }
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.UI;
- using System.Web.UI.WebControls;
- namespace SSO.Web
- {
- public partial class WriteCookie : System.Web.UI.Page
- {
- protected void Page_Load(object sender, EventArgs e)
- {
- }
- protected void SetCookie(string idnum) {
- }
- /// <summary>
- /// 得到用户的身份证号码,当业务系统在SSO中验证通过之后
- /// 同时,SSO中,讲用户的IDNum写入到Cookie当中
- /// 这个Cookie是写在SSO当中的,则避免了Cookie的跨域访问。
- /// </summary>
- /// <returns></returns>
- protected string GetIDNum()
- {
- string idnum = "";
- if (Request.QueryString["IDNum"] == null)
- {
- return idnum;
- }
- else
- {
- idnum = Request.QueryString["IDNum"].ToString();
- return idnum;
- }
- }
- /// <summary>
- /// 根据请求的URI来判断是否是来自于合法的业务系统的合法请求
- /// </summary>
- /// <param name="uri"></param>
- /// <returns></returns>
- protected bool ValidateBizSystem(string uri)
- {
- return true;
- }
- }
- }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace SSO.Web
{
public partial class RedCookie : System.Web.UI.Page
{
private static string url = "";
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["URL"] != null)
{
url = Request.QueryString["URL"].ToString();
}
else
{
url = "";
}
}
protected string GetIDNum()
{
//Request.Cookies["IDNum"].Value = "320000000000000000";
if (Request.Cookies["IDNum"] != null)
{
return Server.HtmlEncode(Request.Cookies["IDNum"].Value);
}
else {
return "0";
}
}
protected string GetURL()
{
return url;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace SSO.Web
{
public partial class WriteCookie : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void SetCookie(string idnum) {
}
/// <summary>
/// 得到用户的身份证号码,当业务系统在SSO中验证通过之后
/// 同时,SSO中,讲用户的IDNum写入到Cookie当中
/// 这个Cookie是写在SSO当中的,则避免了Cookie的跨域访问。
/// </summary>
/// <returns></returns>
protected string GetIDNum()
{
string idnum = "";
if (Request.QueryString["IDNum"] == null)
{
return idnum;
}
else
{
idnum = Request.QueryString["IDNum"].ToString();
return idnum;
}
}
/// <summary>
/// 根据请求的URI来判断是否是来自于合法的业务系统的合法请求
/// </summary>
/// <param name="uri"></param>
/// <returns></returns>
protected bool ValidateBizSystem(string uri)
{
return true;
}
}
}
系统我已经测试通过。
新手上路,希望多多指教。