SSO的基本概念

SSO英文全称Single Sign On(单点登录)。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制。它是目前比较流行的企业业务整合的解决方案之一。(本段内容来自百度百科)

今天这篇文章将介绍SSO的一种实现方式,代码超简单,仅用来验证我的思路是否可行,具体细节请大家来完善!

二级域名的单点登录

什么是二级域名呢?例如:

  • site1.domain.com
  • site2.domain.com

对于二级域名的单点登录,我们可以非常方便的通过共享cookie来实现,简单的说,就是在设置Form票据的时候,将cookie的domain设置为顶级域名即可,例如:

HttpCookie cookie = new HttpCookie(FormsAuthCookieName, encryptedTicket);
cookie.Expires = rememberMe ? expirationDate : DateTime.MinValue;
cookie.HttpOnly = true;
cookie.Path = "/";
cookie.Domain = "domain.com";
context.Response.Cookies.Set(cookie);

这种方式不涉及跨域,当cookie的domain属性设置为顶级域名之后,所有的二级域名都可以访问到身份验证的cookie,在服务器端只要验证了这个cookie就可以实现身份的验证。

但是,当跨域的时候,例如:

  • site1.com
  • site2.com

这个时候就不能共享cookie了,所以上面的解决方案就会失效。那么,要实现跨域的单点登录该如何做呢?请继续往下看。

跨域的单点登录

关于跨域的SSO的设计思路,我画了一个简单的流程图:

首先,我将跨域的SSO分为SSO-Server和SSO-Client两个部分,SSO-Client可以是多个的。

SSO-Server

SSO-Server主要负责用户登录、注销、为SSO-Client分配taken、验证taken的工作。

登录和注销采用的是Form认证方式,很多地方都有详细的介绍,我之前也写过一篇文章,想了解的可以去看看:asp.net Forms身份验证详解

SSO-Server分配Token

为SSO-Client分配Token的部分,在SSO-Client请求SSO受信页面的时候,检查SSO-Server是否登录,如果没有登录则跳转到SSO-Server的登录页面,如果已登录,则执行分配Token的代码,在分配完成以后将TokenID作为参数添加到returnUrl中,并跳转到returnUrl,具体的分配代码如下:

if (Domain.Security.SmartAuthenticate.LoginUser != null)
{
//生成Token,并持久化Token
Domain.SSO.Entity.SSOToken token = new Entity.SSOToken(); token.User = new Entity.SSOUser();
token.User.UserName = Domain.Security.SmartAuthenticate.LoginUser.UserName;
token.LoginID = Session.SessionID;
Domain.SSO.Entity.SSOToken.SSOTokenList.Add(token); //拼接返回的url,参数中带Token
string spliter = returnUrl.Contains('?') ? "&" : "?";
returnUrl = returnUrl + spliter + "token=" + token.ID;
Response.Redirect(returnUrl);
}

当完成Token分配之后,页面将带有TokenID的参数跳转到SSO-Client页面,并在SSO-Client的Cookie中添加Token值,在以后的每次请求中,SSO-Client通过调用SSO-Server的服务来验证Token的合法性。

SSO-Server验证Token

我是通过WebService来验证Token的。

首先在SSO-Server定义一个Web Service:

[WebMethod]
public Entity.SSOToken ValidateToken(string tokenID)
{
if (!KeepToken(tokenID))
return null; var token = Domain.SSO.Entity.SSOToken.SSOTokenList.Find(m => m.ID == tokenID);
return token;
} [WebMethod]
public bool KeepToken(string tokenID)
{
var token = Domain.SSO.Entity.SSOToken.SSOTokenList.Find(m => m.ID == tokenID);
if (token == null)
return false;
if (token.IsTimeOut())
return false; token.AuthTime = DateTime.Now;
return true;
}

ValidateToken用来验证TokenID的合法性,KeepToken用来保持Token不会过期。

SSO-Client通过调用Validate验证Token,并得到当前的登录用户信息。接下来看看SSO-Client的实现。

SSO-Client

SSO-Client作为受信系统来存在的,它自己没有认证系统,只能通过SSO-Server来完成用户身份认证的工作。

当用户请求SSO-Client的受保护资源时,SSO-Client会首先是否有TokenID,如果存在TokenID,则调用SSO-Server的WebService来验证这个TokenID是否合法;

验证成功以后将会返回SSOToken的实例,里面包含已登录的用户信息。具体代码如下:

if (!string.IsNullOrEmpty(tokenID))
{
AuthTokenService.AuthTokenServiceSoapClient client = new AuthTokenService.AuthTokenServiceSoapClient();
var token = client.ValidateToken(tokenID);
if (token != null)
{
this.lblMessage.Text = "登录成功,登录用户:"
+ token.User.UserName
+ "<a href='http://sso-server.com/logout.aspx?returnUrl="
+ Server.UrlEncode("http://sso-client.com")
+ "'>退出</a>";
}
else
{
Response.Redirect("http://sso-server.com/sso.aspx?returnUrl=" +
Server.UrlEncode("http://sso-client.com/default.aspx"));
}
}
else
{
Response.Redirect("http://sso-server.com/sso.aspx?returnUrl=" +
Server.UrlEncode("http://sso-client.com/default.aspx"));
}

源代码

文章中已经介绍了我的具体思路和一些实现,如果你仍然感兴趣,可以下载我的代码>>Demo.SSO

源代码的部署:

1. 在IIS中创建两个站点,分别绑定到SSO-Server和SSO-Client,它们绑定的域名分别是sso-server.com和sso-client.com

2. 在hosts文件中添加两行映射,将sso-server.com和sso-client.com映射到127.0.0.1,确保可以访问

3.访问sso-client.com,这个时候页面将跳转到sso-server.com的登录页面,用户名、密码随便输入,然后点击登录即可

我很认真的完成了这个方案,也感谢你很认真的看完!欢迎拍砖!

谁都能看懂的单点登录(SSO)实现方式(附源码)的更多相关文章

  1. 轻松入门CAS系列(1)-轻松看懂企业单点登录的解决方案

    常见的企业应用情况 企业内部的信息化一般都是一个过程中的 ,起初企业为了部分管理的需要,会上线几个信息化系统:后来对这块慢慢重视,信息系统会越来越多.开始,只有一两个系统时,员工还好,靠脑袋还能记得住 ...

  2. SSO单点登录系列1:cas客户端源码分析cas-client-java-2.1.1.jar

    落雨 cas 单点登录 希望能给以后来研究cas的兄弟留下一点思路,也算是研究了两天的成果,外国人的代码写的很晦涩,翻译下来也没有时间继续跟进,所以有错误的还请大家跟帖和我讨论,qq 39426378 ...

  3. 单点登录(三)-----实战-----cas server 源码下载和部署

    我们在上一篇文章中使用的是4.0版本的cas,4.0版本的有发布好的war包可以直接使用,那如果我们要使用更新的版本怎么办呢? 就需要下载源码自己编辑打包了. 步骤如下: 版本选择 我们在cas的gi ...

  4. 一篇文章看懂TPCx-BB(大数据基准测试工具)源码

    TPCx-BB是大数据基准测试工具,它通过模拟零售商的30个应用场景,执行30个查询来衡量基于Hadoop的大数据系统的包括硬件和软件的性能.其中一些场景还用到了机器学习算法(聚类.线性回归等).为了 ...

  5. 【原创】基于Memcached 实现用户登录的Demo(附源码)

    一个简单的Memcached在Net中运用的一个demo.主要技术 Dapper+MVC+Memcached+sqlserver, 开发工具为vs2015+Sql 效果图如下: 登录后 解决方案 主要 ...

  6. 55张图吃透Nacos,妹子都能看懂!

    大家好,我是不才陈某~ 这是<Spring Cloud 进阶>第1篇文章,往期文章如下: 五十五张图告诉你微服务的灵魂摆渡者Nacos究竟有多强? openFeign夺命连环9问,这谁受得 ...

  7. 小学生都能看懂的FFT!!!

    小学生都能看懂的FFT!!! 前言 在创新实践重心偷偷看了一天FFT资料后,我终于看懂了一点.为了给大家提供一份简单易懂的学习资料,同时也方便自己以后复习,我决定动手写这份学习笔记. 食用指南: 本篇 ...

  8. 机器学习敲门砖:任何人都能看懂的TensorFlow介绍

    机器学习敲门砖:任何人都能看懂的TensorFlow介绍 http://www.jiqizhixin.com/article/1440

  9. 只要听说过电脑的人都能看懂的网上pdf全书获取项目

    作者:周奇 最近我要获取<概统>的教材自学防挂科(线代已死),于是我看到 htt链ps:/链/max链.book接118接.com接/html/2018/0407/160495927.sh ...

随机推荐

  1. Competition-based User Expertise Score Estimation-20160520

    1.Information publication:sigir 2011 author:Jing Liu Harbin Institute of TechnologyMicrosoft Researc ...

  2. rar 命令

    1 wger http://www.rarlab.com/rar/rarlinux-3.9.2.tar.gz 下载文件包 会下载在当前目录 2 cp xxx.xxx ../ 复制xxx.xxx到上个目 ...

  3. python学习笔记整理——列表

    Python 文档学习笔记 数据结构--列表 列表的方法 添加 list.append(x) 添加元素 添加一个元素到列表的末尾:相当于a[len(a):] = [x] list.extend(L) ...

  4. 【Alpha版本】冲刺阶段——Day 6

    我说的都队 031402304 陈燊 031402342 许玲玲 031402337 胡心颖 03140241 王婷婷 031402203 陈齐民 031402209 黄伟炜 031402233 郑扬 ...

  5. 【BZOJ 2157】旅游

    再水一道模板题,明天就要出发去参加二轮省选了赶紧复习复习模板. 链剖模板题,可是写链剖太麻烦了,还是写lct吧. 但这个lct比较麻烦了,因为边权有正有负,要统计最大值和最小值,这样点权赋为什么值都会 ...

  6. hdu1161 欧拉路

    欧拉路径是指能从一个点出发能够“一笔画”完整张图的路径:(每条边只经过一次而不是点) 在无向图中:如果每个点的度都为偶数 那么这个图是欧拉回路:如果最多有2个奇数点,那么出发点和到达点必定为该2点,那 ...

  7. Oracle的自增长主键

    自增长主键 --首先建一个表TEST create table TEST(  NID int PRIMARY KEY,  test1 varchar2(20),  test2 varchar2(20) ...

  8. 如何更新firefox中的flash

    要了解当前安装的版本是否为最新版本,请访问 插件检查页面http://www.mozilla.com/plugincheck/  ,如果该页面告诉你 Flash 插件需要更新,请手动安装最新版本. 使 ...

  9. 18 BufferedReader使用方法

    生成BufferedReader对象的方法: BufferedReader in=new BufferedReader(new FileReader("foo.in")); imp ...

  10. 【转】ListView学习笔记(二)——ViewHolder

    在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以自由的定义listview每一列的布局,但当listview有大量的数据需要加载的时候, ...