Asp.net单点登录解决方案
原文出处: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个站点的主机头:
修改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单点登录解决方案的更多相关文章
- asp.net单点登录(SSO)解决方案
前些天一位朋友要我帮忙做一单点登录,其实这个概念早已耳熟能详,但实际应用很少,难得最近轻闲,于是决定通过本文来详细描述一个SSO解决方案,希望对大家有所帮助.SSO的解决方案很多,但搜索结果令人大失所 ...
- SSO单点登录解决方案[转载]
1 什么是单点登陆 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互 ...
- .NET 单点登录解决方案
这里指的单点,泛指在WEB服务端,一个账户同一时刻只能存在一个票据! 大家开发中可能都碰到的一个问题,怎么使同一个用户,在同一时间内只允许登录一次. 很多人都会想到在数据库中用一个标识字段,登录进去置 ...
- SSO 单点登录解决方案
转自:http://www.blogjava.net/Jack2007/archive/2014/03/11/191795.html 1 什么是单点登陆 单点登录(Single Sign O ...
- 著名ERP厂商的SSO单点登录解决方案介绍一
SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次主要的登录映射到其他应用中用于同一个用户 ...
- ASP.NET单点登录(代码)
[p=25, null, left]由于某些原因,在我们的应用中会遇到一个用户只能在一个地方登录的情况,也就是我们通常所说的单点登录.在ASP.NET中实现单点登录其实很简单,下面就把主要的方法和全部 ...
- sso单点登录解决方案收集
本文来自:http://blog.csdn.net/huwei2003/article/details/6038017 我的想法是使用集中验证方式,多个站点集中Passport验证. 主站:Passp ...
- 【分布式系列】session跨域及单点登录解决方案
Cookie机制 Cookie技术是客户端的解决方案,Cookie就是由服务器发给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息. ...
- Asp.Net_单点登录
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
随机推荐
- NodeJS require a global module/package in linux
https://stackoverflow.com/questions/15636367/nodejs-require-a-global-module-package 1 export NODE_P ...
- Linux top命令用法
统计信息区前五行是系统整体的统计信息.第一行是任务队列信息,同 uptime 命令的执行结果.其内容如下: :: 当前时间 up : 系统运行时间,格式为时:分 user 当前登录用户数 load a ...
- maven tomcat插件上传项目到tomcat服务器报错SEVERE: One or more listeners failed to start.
以前觉了maven依赖设置很简单,就是将手动导入jar包转化为自动下载导入 但发现的一个问题, 在使用maven插件tomcat打包上传工具时 tomcat-maven-plugin <buil ...
- mongodb-mongotemplate进行地理坐标操作
因为项目中使用的springboot + mongotemplate, 所以还是需要mongotemplate的操作方式 首先建立一个bean: package com.iwhere.easy.tra ...
- Linux-(touch,cat,nl,more|less,head|tail)
touch命令 1.命令格式: touch [选项]... 文件... 2.命令参数: -a 或--time=atime或--time=access或--time=use 只更改存取时间. -c ...
- 使用DAO模式开发宠物管理系统---hellokitty
宠物有狗和企鹅. 狗的属性有:编号.名称.亲密值.健康值.品种.所属主人编号. 企鹅的属性有:编号.名称.亲密值.健康值.性别.所属主人编号. 该系统中主人可以领养宠物,主人的属性有:编号.用户名.密 ...
- APPCAN的mas服务报错
报错信息 主要是: [meap_im_java]load java warning { [Error: Cannot find module 'java'] code: 'MODULE_NOT_FOU ...
- Jsp&Servlet入门级项目全程实录第4讲
惯例广告一发,对于初学真,真的很有用www.java1234.com,去试试吧! 1.添加搜索.添加.修改.删除按钮 <div id="tb"> <div> ...
- [日常] go语言圣经-获取URL练习题
1.主要使用net/http和io/ioutil包 2.http.Get函数是创建HTTP请求的函数,resp这个结构体中,Body字段包括一个可读的服务器响应流 3.ioutil.ReadAll函数 ...
- Sql Server 中使用日期遍历
一个存储过程小案例,内容如下: declare @dt datetime set @dt='2016-01-01' while (@dt<='2016-12-31') begin -- 转换字符 ...