原文出处:http://www.cnblogs.com/wu-jian

主站:Passport集中验证服务器,DEMO中为:http://www.passport.com/

分站:http://www.a.com/http://www.b.com/http://www.c.com/

凭证:用户登录后产生的鉴权标识,用于识别授权用户。可为多种方式,DEMO中主站使用的是Cache,分站使用的是Session。

令牌:由Passport颁发可在各分站中流通的用户唯一鉴权标识,DEMO中使用的是Cookie。

核心逻辑

使用集中式身份验证,用户数据存放于Passport,各分站统一使用Passport进行登录和鉴权,如<图1>所示:

<图1>

<图2>

<图2>详细描述了单点登录逻辑与流程

流程一:匿名用户访问分站a

匿名用户访问分站a上的一个授权页面,首先跳转到主站通过帐号、密码进行登录鉴权,验证通过后产生主站凭证,同时产生令牌,跳转回分站a。

此时分站a检测到用户已持有令牌,于是用令牌再次去主站获取用户凭证,获取成功后允许用户访问该授权页面。同时产生分站a的本地凭证。

当该用户需要再次验证时将使用本地凭证,以减少网络交互。

流程二:在分站a登录的用户访问分站b

因为用户在分站a登录过,已持有令牌,所以分站b会用令牌去主站获取用户凭证,获取成功后允许用户访问授权页面。同时产生分站b的本地凭证。

实现关键点

令牌

令牌由主站颁发,主站颁发令牌同时生成用户凭证,并记录令牌与用户凭证之间的对应关系,以根据用户提供的令牌响应对应的凭证;

令牌要在各跨域分站中进行流通,DEMO中使用了Cookie,并指定Cookie.Domain="passport.com";

各分站如何共享主站的Cookie?从分站Redirect到主站页面,然后该页面读取Cookie并以URL参数方式回传即可,可在DEMO代码中查看详细实现。

 
//产生令牌
HttpCookie tokenCookie = new HttpCookie("Passport.Token");
tokenCookie.Domain = "passport.com";
//可使用自定义算法避免Cookie非法复制
//tokenCookie.Values.Add("Key", "加密算法");
tokenCookie.Values.Add("Value", tokenValue);
Response.AppendCookie(tokenCookie);
 

在之前的文章中有读者提到令牌(Cookie)被非法复制导致的安全问题,在此简单说明一下。

首先默认设置了Cookie为关闭浏览器即失效,也就是说用户在成功鉴权后持续打开浏览器的前提下才会导至令牌泄漏。

然后在Passport令牌的设计中有“过期时间”一项,也可以通过使用令牌的过期时间来确保令牌安全。

如果您觉得还不够,其实只需要在令牌验证时添加一些自定义逻辑,比如用时间、用户特征产生一个Hash值作为令牌的安全KEY。

文章主要针对SSO的逻辑,一些细节上的代码并未十全十美,读者可以根据实际需求进行完善。

主站凭证

主站凭证是一个关系表,包含了三个字段:令牌、用户凭证、过期时间。

主站凭证有多种实现方式可供选择,比如要求可靠的话可以使用数据库,要求性能的话可以使用Cache,DEMO中我使用的是Cache。如下代码所示:

 
/// <summary>
/// 初始化缓存数据结构
/// </summary>
/// <remarks>
/// ----------------------------------------------------
/// | token(令牌) | cert(用户凭证) | timeout(过期时间) |
/// |--------------------------------------------------|
/// </remarks>
private static void cacheInit()
{
if (HttpContext.Current.Cache["PASSPORT.TOKEN"] == null)
{
DataTable dt = new DataTable(); dt.Columns.Add("token", Type.GetType("System.String"));
dt.Columns["token"].Unique = true; dt.Columns.Add("cert", Type.GetType("System.Object"));
dt.Columns["cert"].DefaultValue = null; dt.Columns.Add("timeout", Type.GetType("System.DateTime"));
dt.Columns["timeout"].DefaultValue = DateTime.Now.AddMinutes(double.Parse(System.Configuration.ConfigurationManager.AppSettings["Timeout"])); DataColumn[] keys = new DataColumn[1];
keys[0] = dt.Columns["token"];
dt.PrimaryKey = keys; //Cache的过期时间为 令牌过期时间*2
HttpContext.Current.Cache.Insert("PASSPORT.TOKEN", dt, null, DateTime.MaxValue, TimeSpan.FromMinutes(double.Parse(System.Configuration.ConfigurationManager.AppSettings["Timeout"]) * 2));
}
}
 

分站凭证

分站凭证主要用于减少重复验证时网络的交互,比如用户已在分站a上登录过,当他再次访问分站a时,就不必使用令牌去主站验证了,因为分站a已有该用户的凭证。

分站凭证相对比较简单,使用Session、Cookie均可。

分站SSO页面基类

分站使用SSO的页面会做一系列的逻辑判断处理,如<图2>所示。如果为每个页面写一遍这样的逻辑会非常繁琐。OK,那么把这套逻辑封装成一个基类,凡是要使用SSO的页面继承该基类即可。如下代码所示:

 
public class AuthBase : System.Web.UI.Page
{
protected override void OnLoad(EventArgs e)
{
if (Session["A.Cert"] != null)
{
//分站凭证存在
Response.Write("恭喜,分站凭证存在,您被授权访问该页面!");
}
else
{
//令牌验证结果返回
if (Request.QueryString["token"] != null)
{
//持有令牌
if (Request.QueryString["token"] != "$token$")
{
string tokenValue = Request.QueryString["token"];
//调用WebService获取主站凭证
//防止令牌伪造
//此处还可使用公钥私钥的非对称加密策略
SSO.SiteA.ServiceReference1.PassportServiceSoapClient passportService = new SSO.SiteA.ServiceReference1.PassportServiceSoapClient();
object cert = passportService.TokenGetCert(tokenValue);
if (cert != null)
{
//令牌正确
Session["A.Cert"] = cert;
Response.Write("恭喜,令牌存在,您被授权访问该页面!");
}
else
{
//令牌错误,去Passport登录
Response.Redirect(SSO.Common.Tools.TokenReplace());
}
}
//未持有令牌,去Passport登录
else
{
Response.Redirect(SSO.Common.Tools.TokenReplace());
}
}
//未进行令牌验证,去Passport验证
else
{
//当前url附加上token参数
Response.Redirect(SSO.Common.Tools.TokenUrl());
}
} base.OnLoad(e);
} }//end class
 

用户退出

<图3>

用户退出时分别清空主站令牌/凭证与所有分站凭证。DEMO中通过调用WebService清空该用户的主站令牌/凭证,通过iframe清空各分站凭证,请参阅DEMO中的详细代码实现。

主站过期令牌/凭证清除

读者可自行实现该逻辑,定时清除(DataTable)Cache[“PASSPORT.TOKEN”]中timeout字段超过当前时间的记录。

DEMO

DEMO开发环境

.Net Framework 4.0

Visual Studio 2012

在IIS中配置站点

配置4个站点指向相应的目录,并分别指定4个站点的主机头:

http://www.passport.com/

http://www.a.com/

http://www.b.com/

http://www.c.com/

修改hosts文件以将域名解析到本地站点

127.0.0.1          http://www.passport.com/

127.0.0.1          http://www.a.com/

127.0.0.1          http://www.b.com/

127.0.0.1          http://www.c.com/

DEMO下载

http://files.cnblogs.com/files/tinya/wujian_sso.rar

Asp.net单点登录解决方案的更多相关文章

  1. asp.net单点登录(SSO)解决方案

    前些天一位朋友要我帮忙做一单点登录,其实这个概念早已耳熟能详,但实际应用很少,难得最近轻闲,于是决定通过本文来详细描述一个SSO解决方案,希望对大家有所帮助.SSO的解决方案很多,但搜索结果令人大失所 ...

  2. SSO单点登录解决方案[转载]

    1 什么是单点登陆      单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互 ...

  3. .NET 单点登录解决方案

    这里指的单点,泛指在WEB服务端,一个账户同一时刻只能存在一个票据! 大家开发中可能都碰到的一个问题,怎么使同一个用户,在同一时间内只允许登录一次. 很多人都会想到在数据库中用一个标识字段,登录进去置 ...

  4. SSO 单点登录解决方案

    转自:http://www.blogjava.net/Jack2007/archive/2014/03/11/191795.html 1 什么是单点登陆      单点登录(Single Sign O ...

  5. 著名ERP厂商的SSO单点登录解决方案介绍一

          SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次主要的登录映射到其他应用中用于同一个用户 ...

  6. ASP.NET单点登录(代码)

    [p=25, null, left]由于某些原因,在我们的应用中会遇到一个用户只能在一个地方登录的情况,也就是我们通常所说的单点登录.在ASP.NET中实现单点登录其实很简单,下面就把主要的方法和全部 ...

  7. sso单点登录解决方案收集

    本文来自:http://blog.csdn.net/huwei2003/article/details/6038017 我的想法是使用集中验证方式,多个站点集中Passport验证. 主站:Passp ...

  8. 【分布式系列】session跨域及单点登录解决方案

    Cookie机制 Cookie技术是客户端的解决方案,Cookie就是由服务器发给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息. ...

  9. Asp.Net_单点登录

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

随机推荐

  1. 一款高效视频播放控件的设计思路(c# WPF版)

    因工作的需要,开发了一款视频播放程序.期间也经历许多曲折,查阅了大量资料,经过了反复测试,终于圆满完成了任务. 我把开发过程中的一些思路.想法写下来,以期对后来者有所帮助. 视频播放的本质 就是连续的 ...

  2. TemplateBinding和Binding的区别

    定义 TemplateBinding是为了某个特定场景优化出来的数据绑定版本--需要把ControlTemplate里面的某个Property绑定到应用该ControlTemplate的控件的对应Pr ...

  3. 配置私有仓库(使用registry镜像搭建一个私有仓库)

    在使用Docker一段时间后,往往会发现手头积累了大量的自定义镜像文件,这些文件通过公有仓库进行管理并不方便:另外有时候只是希望在内部用户之间进行分享,不希望暴露出去.这种情况下,就有必要搭建一个本地 ...

  4. Low Power之CPF/UPF

    1 CPF The Common Power Format is a standard promoted by the Low Power Coalition at Si2. CPF is also ...

  5. MongoDB之集合管理一

    最近的几篇博客都是关于MongoDB的,虽然个人感觉也没多少知识点,但没想到竟然有转载我的博客的,不管有经过我同意还是没经过我同意,说明写的应该还是有价值的,这也是我写博客的一个动力之一吧.上一博客学 ...

  6. Angular2入门教程-2 实现TodoList App

    最近在学习<Angular从零到一>(机械工业出版社) 遇到一些问题,书中讲的不明白,在网上找了一些,资源很多,也有很多前人的经验 https://blog.csdn.net/ztguan ...

  7. favi.icon是什么?

    各大网站都有属于自己的图标 概念解释: ico是Icon file的缩写,是Windows的图标文件格式的一种 1.制作ico格式的图片一个上传到服务器的根目录图片保存为favicon.ico 2.制 ...

  8. 谷歌旗下专业图片编辑Snapseed获重大更新

    谷歌旗下的图片编辑应用Snapseed今天获得重大更新,承诺为用户的手机或者平板带来“精确和卓越控制的专业图片编辑软件”.Android和iOS版本同时获得更新,新增包括镜头模糊.色条对比.更加灵活的 ...

  9. Grunt - 安装指南

    发现周围有些人对前端存在偏见. 他们认为前端只是用没那么复杂的技术对着界面调来调去,一点点打磨,最后做出一个没什么实用价值的“花瓶”. 其实,前端的技术栈并不简单,比如我们可以用Grunt进行一些自动 ...

  10. JSTL判断list是否为空

    1.先在jsp页面中导入下列类库. <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" ...