搜索
首页后端开发C#.Net教程基于.Net的单点登录(SSO)实现解决方案

基于.Net的单点登录(SSO)实现解决方案

Dec 28, 2016 pm 04:17 PM
sso单点登录

前些天一位朋友要我帮忙做一单点登录,其实这个概念早已耳熟能详,但实际应用很少,难得最近轻闲,于是决定通过本文来详细描述一个SSO解决方案,希望对大家有所帮助。SSO的解决方案很多,但搜索结果令人大失所望,大部分是相互转载,并且描述的也是走马观花。 
闲话少叙,进入正题,我的想法是使用集中验证方式,多个站点集中Passport验证。 如下图所示: 

基于.Net的单点登录(SSO)实现解决方案

为方便清晰描述,先定义几个名词,本文中出现之处均为如下含义。 
主站:Passport集中验证服务器 http://www.passport.com/ 。 
分站:http://www.a.com/、http://www.b.com/、http://www.c.com/ 
凭证:用户登录后产生的数据标识,用于识别授权用户,可为多种方式,DEMO中主站我使用的是Cache,分站使用Session。 
令牌:由Passport颁发可在各分站中流通的唯一标识。 
OK,现在描述一下单点登录的过程: 
情形一、匿名用户:匿名用户访问分站a上的一个授权页面,首先跳转到主站让用户输入帐号、密码进行登录,验证通过后产生主站凭证,同时产生令牌,跳转回分站a,此时分站a检测到用户已持有令牌,于是用令牌再次去主站获取用户凭证,获取成功后允许用户访问该授权页面。同时产生分站a的本地凭证,当该用户需要再次验证时将先检查本地凭证,以减少网络交互。 
情形二、在分站a登录的用户访问分站b:因为用户在分站a登录过,已持有令牌,所以分站b会用令牌去主站获取用户凭证,获取成功后允许用户访问授权页面。同时产生分站b的本地凭证。 

基于.Net的单点登录(SSO)实现解决方案

设计完成后,接下来是方案实现的一些关键点: 
令牌:令牌由主站颁发,主站颁发令牌同时生成用户凭证,并记录令牌与用户凭证之间的对应关系,以根据用户提供的令牌响应对应的凭证;令牌要在各跨域分站中进行流通,所以DEMO中令牌我使用主站的Cookie,并指定Cookie.Domain="passport.com"。各分站如何共享主站的Cookie?从分站Redirect到主站页面,然后该页面读取Cookie并以URL参数方式回传即可,可在DEMO代码中查看详细实现,当然如果哪位有更好的令牌实现方式也拿出来分享。 

//产生令牌 
string tokenValue = Guid.NewGuid().ToString().ToUpper(); 
HttpCookie tokenCookie = new HttpCookie("Token"); 
tokenCookie.Values.Add("Value", tokenValue); 
tokenCookie.Domain = "passport.com"; 
Response.AppendCookie(tokenCookie);

主站凭证:主站凭证是一个关系表,包含了三个字段:令牌、凭证数据、过期时间。有多种实现方式可供选择,要求可靠的话用数据库,要求性能的话用Cache,DEMO中我使用的是Cache中的DataTable。如下代码所示: 

/// <summary> 
/// 初始化数据结构 
/// </summary> 
/// <remarks> 
/// ---------------------------------------------------- 
/// | token(令牌) | info(用户凭证) | timeout(过期时间) | 
/// |--------------------------------------------------| 
/// </remarks> 
private static void cacheInit() 
{ 
if (HttpContext.Current.Cache["CERT"] == null) 
{ 
DataTable dt = new DataTable(); 
dt.Columns.Add("token", Type.GetType("System.String")); 
dt.Columns["token"].Unique = true; 
dt.Columns.Add("info", Type.GetType("System.Object")); 
dt.Columns["info"].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("CERT", dt, null, DateTime.MaxValue, TimeSpan.FromMinutes(double.Parse(System.Configuration.ConfigurationManager.AppSettings["timeout"]) * 2)); 
} 
}

分站凭证:分站凭证主要用于减少重复验证时网络的交互,比如用户已在分站a上登录过,当他再次访问分站a时,就不必使用令牌去主站验证了,因为分站a已有该用户的凭证。分站凭证相对比较简单,使用Session、Cookie均可。 
分站SSO页面基类:分站使用SSO的页面会做一系列的逻辑判断处理,如文章开头的流程图。如果有多个页面的话不可能为每个页写一个这样的逻辑,OK,那么把这套逻辑封装成一个基类,凡是要使用SSO的页面继承该基类即可。如下代码所示: 

using System; 
using System.Data; 
using System.Configuration; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Web.UI.HtmlControls; 
using System.Text.RegularExpressions; 
namespace SSO.SiteA.Class 
{ 
/// <summary> 
/// 授权页面基类 
/// </summary> 
public class AuthBase : System.Web.UI.Page 
{ 
protected override void OnLoad(EventArgs e) 
{ 
if (Session["Token"] != null) 
{ 
//分站凭证存在 
Response.Write("恭喜,分站凭证存在,您被授权访问该页面!"); 
} 
else 
{ 
//令牌验证结果 
if (Request.QueryString["Token"] != null) 
{ 
if (Request.QueryString["Token"] != "$Token$") 
{ 
//持有令牌 
string tokenValue = Request.QueryString["Token"]; 
//调用WebService获取主站凭证 
SSO.SiteA.RefPassport.TokenService tokenService = new SSO.SiteA.RefPassport.TokenService(); 
object o = tokenService.TokenGetCredence(tokenValue); 
if (o != null) 
{ 
//令牌正确 
Session["Token"] = o; 
Response.Write("恭喜,令牌存在,您被授权访问该页面!"); 
} 
else 
{ 
//令牌错误 
Response.Redirect(this.replaceToken()); 
} 
} 
else 
{ 
//未持有令牌 
Response.Redirect(this.replaceToken()); 
} 
} 
//未进行令牌验证,去主站验证 
else 
{ 
Response.Redirect(this.getTokenURL()); 
} 
} 
base.OnLoad(e); 
} 
/// <summary> 
/// 获取带令牌请求的URL 
/// 在当前URL中附加上令牌请求参数 
/// </summary> 
/// <returns></returns> 
private string getTokenURL() 
{ 
string url = Request.Url.AbsoluteUri; 
Regex reg = new Regex(@"^.*\?.+=.+$"); 
if (reg.IsMatch(url)) 
url += "&Token=$Token$"; 
else 
url += "?Token=$Token$"; 
return "http://www.passport.com/gettoken.aspx?BackURL=" + Server.UrlEncode(url); 
} 
/// <summary> 
/// 去掉URL中的令牌 
/// 在当前URL中去掉令牌参数 
/// </summary> 
/// <returns></returns> 
private string replaceToken() 
{ 
string url = Request.Url.AbsoluteUri; 
url = Regex.Replace(url, @"(\?|&)Token=.*", "", RegexOptions.IgnoreCase); 
return "http://www.passport.com/userlogin.aspx?BackURL=" + Server.UrlEncode(url); 
} 
}//end class 
}

用户退出:用户退出时分别清空主站凭证与当前分站凭证。如果要求A站点退出,B、C站点也退出,可自行扩展接口清空每个分站凭证。 
主站过期凭证/令牌清除:定时清除(DataTable)Cache[“CERT”]中timeout字段超过当前时间的记录。

更多基于.Net的单点登录(SSO)实现解决方案相关文章请关注PHP中文网!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
.NET生态系统:C#的角色和超越.NET生态系统:C#的角色和超越May 03, 2025 am 12:04 AM

C#在.NET生态系统中扮演核心角色,是开发者的首选语言。1)C#提供高效、易用的编程方式,结合C、C 和Java的优点。2)通过.NET运行时(CLR)执行,确保跨平台高效运行。3)C#支持从基本到高级的用法,如LINQ和异步编程。4)优化和最佳实践包括使用StringBuilder和异步编程,提高性能和可维护性。

C#作为.NET语言:生态系统的基础C#作为.NET语言:生态系统的基础May 02, 2025 am 12:01 AM

C#是微软在2000年发布的编程语言,旨在结合C 的强大功能和Java的简洁性。1.C#是一种类型安全、面向对象的编程语言,支持封装、继承和多态。2.C#的编译过程将代码转化为中间语言(IL),然后在.NET运行时环境(CLR)中即时编译成机器码执行。3.C#的基本用法包括变量声明、控制流和函数定义,而高级用法涵盖异步编程、LINQ和委托等。4.常见错误包括类型不匹配和空引用异常,可通过调试器、异常处理和日志记录来调试。5.性能优化建议包括使用LINQ、异步编程和提高代码可读性。

c#vs. .net:澄清关键差异和相似之处c#vs. .net:澄清关键差异和相似之处May 01, 2025 am 12:12 AM

C#是一种编程语言,而.NET是一个软件框架。1.C#由微软开发,适用于多平台开发。2..NET提供类库和运行时环境,支持多语言。两者协同工作,构建现代应用。

超越炒作:评估C#.NET的当前作用超越炒作:评估C#.NET的当前作用Apr 30, 2025 am 12:06 AM

C#.NET是一个强大的开发平台,结合了C#语言和.NET框架的优势。1)它广泛应用于企业应用、Web开发、游戏开发和移动应用开发。2)C#代码编译成中间语言后由.NET运行时环境执行,支持垃圾回收、类型安全和LINQ查询。3)使用示例包括基本控制台输出和高级LINQ查询。4)常见错误如空引用和类型转换错误可以通过调试器和日志记录解决。5)性能优化建议包括异步编程和优化LINQ查询。6)尽管面临竞争,C#.NET通过不断创新保持其重要地位。

C#.NET的未来:趋势和机遇C#.NET的未来:趋势和机遇Apr 29, 2025 am 12:02 AM

C#.NET的未来趋势主要集中在云计算、微服务、AI和机器学习集成以及跨平台开发三个方面。1)云计算和微服务:C#.NET通过Azure平台优化云环境表现,支持构建高效微服务架构。2)AI和机器学习集成:借助ML.NET库,C#开发者可在应用中嵌入机器学习模型,推动智能化应用发展。3)跨平台开发:通过.NETCore和.NET5 ,C#应用可在Windows、Linux和macOS上运行,扩展部署范围。

C#.NET开发今天:趋势和最佳实践C#.NET开发今天:趋势和最佳实践Apr 28, 2025 am 12:25 AM

C#.NET开发的最新动态和最佳实践包括:1.异步编程提高应用响应性,使用async和await关键字简化非阻塞代码;2.LINQ提供强大查询功能,通过延迟执行和表达式树高效操作数据;3.性能优化建议包括使用异步编程、优化LINQ查询、合理管理内存、提升代码可读性和维护性、以及编写单元测试。

C#.NET:使用.NET生态系统构建应用程序C#.NET:使用.NET生态系统构建应用程序Apr 27, 2025 am 12:12 AM

如何利用.NET构建应用?使用.NET构建应用可以通过以下步骤实现:1)了解.NET基础知识,包括C#语言和跨平台开发支持;2)学习核心概念,如.NET生态系统的组件和工作原理;3)掌握基本和高级用法,从简单控制台应用到复杂的WebAPI和数据库操作;4)熟悉常见错误与调试技巧,如配置和数据库连接问题;5)应用性能优化与最佳实践,如异步编程和缓存。

C#作为多功能.NET语言:应用程序和示例C#作为多功能.NET语言:应用程序和示例Apr 26, 2025 am 12:26 AM

C#在企业级应用、游戏开发、移动应用和Web开发中均有广泛应用。1)在企业级应用中,C#常用于ASP.NETCore开发WebAPI。2)在游戏开发中,C#与Unity引擎结合,实现角色控制等功能。3)C#支持多态性和异步编程,提高代码灵活性和应用性能。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。