因最近客户公司一直在讨论单点登录,我个人觉得单点登陆复杂的可以很复杂,简单的可以很简单。
总体来说单点登录,就是提供一个登陆入口,对相关联的系统用户登录进行相关控制,所有的系统登录都有这个入口进入,在使用所有的系统中只要登录一次 就能进入相关系统。(注:我这里所描述的单点登录 只是我个人的理解,不是专业术语 具体请看:点击打开链接)
在演示的demo中 主要分为3个模块:登录服务,客户端系统1,客户端系统2.
主要实现原理:首先用户 打开 客户端系统1 或者客户端系统2 的页面,系统判断用户是否登录,如果没有登录,则指向登录服务的登录界面,和以往的不同之处,是系统在判断没有登录权限之后,是重定向到当前的系统登录界面,而单点登陆不是,必须冲定向到登陆服务登录界面
页面跳转层次:用户输入 WebClientOne 的Index.aspx界面,后台代码进行判断是否有登录权限 没有登录权限 重定向到 WebService的Login.aspx界面 并带上相应参数 WebType。用户在登录界面进行登录,登录完成后 向浏览器中写入 Cookie_UserID和Cookie_Key cookie值,并根据WebType的参数值,重定向到相应客户端系统的登录接口 也就是 WebClientOne 的Login.aspx 并附加相应参数 UserID和Key。WebClientOne 的Login.aspx 后台代码根据获取的参数进行内部系统的权限分配。
整体上 一次登陆完成,在使用其他系统时,请求过程以及原理都一样,不过登录过一次之后就不需要在进行登录,因为 已经写入了 Cookie_UserID和Cookie_Key 这两个cookie值,如果这个两个值删除掉 则需要再次登陆。
相关代码:
WebService Login 登录代码:
public partial class Login : System.Web.UI.Page
{
///
/// md5签名密钥
///
private static string md5Key = "jOeVOwVU4JhgepluTbqMUrSafrkF";
protected void Page_Load(object sender, EventArgs e)
{
/*
定义固定参数:
* Key表示签名后的信息标识
* WebType 表示网站表示
* UserID 表示网站用户信息标识(在使用单点登录时,必须对所有网站的用户统一管理,或者说进行管理,登录系统的用户名和子系统的用户信息进行关联)
* Cookie_Key 表示登录后写入到浏览器的值
* Cookie_UserID 表示登录后的用户ID
*/
//判断 请求网站是否为空 如果请求网站为空则为非法操作
if (Request["WebType"] == null)
{
//我这里对非法操作的进行简单的重定向
Response.Redirect("http://www.baidu.com");
}
//如果Cookie_Key 这个值不为空 则表示可能进行过登录
else if (Request.Cookies["Cookie_Key"] != null && Request.Cookies["Cookie_UserID"] != null)
{
string cookie_Key = Request["Cookie_Key"].ToString();
string cookie_UserID = Request["Cookie_UserID"].ToString();
//验证新是否一致
if (cookie_Key == MD5("UserID=" + cookie_UserID, "UTF-8"))
{
RedirectUrl("UserID=" + cookie_UserID, Request["WebType"].ToString());
}
}
}
protected void btn_Click(object sender, EventArgs e)
{
if (Request["WebType"] == null)
{
Response.Redirect("http://www.baidu.com", true);
return;
}
//对用户名进行验证,因我这里为测试demo系统,所有不做认证处理
if (txtName.Text.Trim().Length >= 1)
{
string str = "UserID=" + txtName.Text.Trim();
string webType = Request["WebType"].ToString();
Response.Cookies.Add(new HttpCookie("Cookie_UserID", txtName.Text.Trim()));
Response.Cookies.Add(new HttpCookie("Cookie_Key", MD5(str, "UTF-8")));
RedirectUrl(str, webType);
}
}
public void RedirectUrl(string str, string webType)
{
string key = MD5(str, "UTF-8");
//这里应该维护一张 WebType对应的网址信息表 这里只是做demo演示 所以简单化
switch (webType)
{
case "1":
Response.Redirect("http://localhost:7909/Login.aspx?" + str + "&Key=" + key);
break;
case "2":
Response.Redirect("http://localhost:8121/Login.aspx?" + str + "&Key=" + key);
break;
}
}
///
/// 字符串MD5加密
///
/// 签名字符串
///
///
public static string MD5(string encypStr, string charset)
{
MD5CryptoServiceProvider md5 = new
System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] bs = Encoding.GetEncoding(charset).GetBytes(encypStr);
bs = md5.ComputeHash(bs);
StringBuilder s = new StringBuilder();
foreach (byte b in bs)
{
s.Append(b.ToString("x2").ToUpper());
}
string password = s.ToString();
return password;
}
}
WebClientOne Index.aspx 后台代码:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (Session["UserState"] == null)
{
//重定向到单点登录口
Response.Redirect("http://localhost:7564/Login.aspx?WebType=1");
}
else
{
labText.Text = "用户名:" + Session["UserState"].ToString();
}
}
}
WebClientOne Login.aspx 后台代码:
///
/// md5签名密钥
///
private static string md5Key = "jOeVOwVU4JhgepluTbqMUrSafrkF";
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (Request["UserID"] != null && Request["Key"] != null)
{
if (MD5("UserID=" + Request["UserID"].ToString(), "UTF-8") == Request["Key"].ToString())
{
Session["UserState"] = Request["UserID"].ToString();
Response.Redirect("~/Index.aspx");
}
}
}
}
///
/// 字符串MD5加密
///
/// 签名字符串
///
///
public static string MD5(string encypStr, string charset)
{
MD5CryptoServiceProvider md5 = new
System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] bs = Encoding.GetEncoding(charset).GetBytes(encypStr);
bs = md5.ComputeHash(bs);
StringBuilder s = new StringBuilder();
foreach (byte b in bs)
{
s.Append(b.ToString("x2").ToUpper());
}
string password = s.ToString();
return password;
}
下载地址: 点击打开链接