进公司以来, 所做的产品中, 下面的子系统就没有少于10个的, 其中有的是.net做的, 有的是java做的, 还有安卓端, ios端. 那么这么多子系统, 我可能需要访问其中的多个(同一平台), 我是否需要登录多次来操作呢? 这样是不是太不方便了. 在我们登录qq之后, 进入qq邮箱, 也并没有让我们多登录一次, 而是直接进去了. 那么在我们的这些系统中, 怎么来实现这种功能呢?

到这里, 就引出今天的主题 - SSO 单点登录. 在我们登录系统A之后, 去访问系统B, 此时并不需要再去登陆一次了. 这里有一个前提, 就是不论系统A还是系统B, 用的都是同一个账户和密码. 如果他们之间的用户名和密码不相同, 就麻烦很多了.

在网上搜到的单点登录解决方案, 比较多的是CAS, 耶鲁大学弄得一个单点登录解决方案。当然,在此篇,并不会介绍到CAS,只是通过一个小例子,来看看轮廓而已。

一、效果展示

在这里,我有三个网站, 当我在Server这个网站登录之后,ClientA,ClientB我直接输入backUrl后面的地址, 看看是否要让我登录。

输入之后, 让我直接进去了, 而没有让我再次登录。

当我在HomeA页面登出之后, 再去刷新其他的两个页面来看。

其他两个页面,也被迫登出了。

从效果上看, 是不是一个系统登录, 多个系统可以免登录了, 一处登出, 多个系统都被登出。 这就是一个单点登录的效果了。

二、关键代码

服务器登录部分:

[NoLogin]
public ActionResult LoginCheck(string userName, string userPwd)
{
if (userName == "admin" && userPwd == "")
{
User user = new User { Guid = Guid.NewGuid().ToString(), Name = "admin", Pwd = "" }; var newCookie = new HttpCookie("userCode", user.Guid);
newCookie.Expires = DateTime.Now.AddDays();
Response.Cookies.Add(newCookie); RedisCache.Instance.Set(user.Guid, user, TimeSpan.FromMinutes()); return Json(new { status = "ok", guid = user.Guid });
}
return Json(new { status = "notMatch" });
}

这里的NoLogin就是一个空的特性,里面啥都没有,可以放在类和方法上,用来判断是否不需要登录就可以直接访问页面。

当验证成功登录后, 将生成一个凭据Guid, 一会用户手持这个凭据来系统验证, 我这边就只看redis缓存中是否有这个缓存存在, 有则表示已经登录。并没有做更多的验证了。

我这里的redis是部署在ubuntu虚拟机上面的, redis对windows的支持并不是很好, 但是也能找到windows的版本, 如果可能的话, 我还是建议使用 linux 部署 redis。

客户端验证部分:

public class SSOClientAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
//判断请求的方法或者控制器上, 有没有免登陆特性
if (filterContext.ActionDescriptor.IsDefined(typeof(NoLoginAttribute), false)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(NoLoginAttribute), false))
{
return;
} //需要登陆的方法, 继续验证
base.OnAuthorization(filterContext);
} protected override bool AuthorizeCore(HttpContextBase httpContext)
{
HttpCookie cookie = httpContext.Request.Cookies["userCode"];
if (cookie == null || string.IsNullOrEmpty(cookie.Value))
return false; var user = RedisCache.Instance.GetOrDefault<User>(cookie.Value); if (user != null)
{
cookie.Expires = DateTime.Now.AddDays();
httpContext.Response.SetCookie(cookie);
RedisCache.Instance.Set(user.Guid, user, TimeSpan.FromMinutes());
return true;
} return false;
}
  
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
string loginUrl = ConfigurationManager.AppSettings["LoginUrl"];
string Url = filterContext.RequestContext.HttpContext.Request.Url.AbsoluteUri;
loginUrl += "?backUrl=" + Url;
filterContext.HttpContext.Response.Redirect(loginUrl, true);
}
}

登出部分就简单了, 只要清除cookie和redis缓存就行了。代码就不贴了。

三、结束语

CAS的单点登录比这个复杂多了, 这里只是我自己弄得一个小Demo,只是对单点登录的一个初步认识,后面有机会的话, 希望我会把Cas的搭建、使用方法或者解析贴出来。

参考:

  蔡的mysso例子(以前看过他的例子,我写的更简单点,能实现效果就成了)

SSO - 开篇引例的更多相关文章

  1. Java多线程引例及实现多线程的方式

    多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术. Java多线程是由JVM来实现,不必关心操作系统的调用问题. 假如我们要实现如下功能: public c ...

  2. 单点登录SSO

    转载自 http://www.blogjava.net/xcp/archive/2010/04/13/318125.html   摘要:单点登录(SSO)的技术被越来越广泛地运用到各个领域的软件系统当 ...

  3. Java实现SSO

    摘要:单点登录(SSO)的技术被越来越广泛地运用到各个领域的软件系统当中.本文从业务的角度分析了单点登录的需求和应用领域:从技术本身的角度分析了单点登录技术的内部机制和实现手段,并且给出Web-SSO ...

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

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

  5. 单点登录实现机制:桌面sso

    参考链接,感谢作者:https://zm10.sm-tc.cn/?src=l4uLj8XQ0IiIiNGckZ2TkJiM0ZyQktCZlo2Mi5uNmp6S0I/QysrJyszPztGXi5K ...

  6. OAuth2实现单点登录SSO

    1.  前言 技术这东西吧,看别人写的好像很简单似的,到自己去写的时候就各种问题,“一看就会,一做就错”.网上关于实现SSO的文章一大堆,但是当你真的照着写的时候就会发现根本不是那么回事儿,简直让人抓 ...

  7. SSO 单点登录解决方案

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

  8. c#编程基础之ref、out参数

    引例: 先看这个源码,函数传递后由于传递的是副本所以真正的值并没有改变. 源码如下: using System; using System.Collections.Generic; using Sys ...

  9. html基础起航

    废话不多说,直接上例子! 工欲善其事,必先利其器 浏览器要有吧~                       比如:IE.Chrome.Firefox…… 纯文本编辑软件不可少~          比 ...

随机推荐

  1. mysql同时使用order by和limit查询时的一个严重隐患 -- 丢失数据

    转自: https://blog.csdn.net/tsxw24/article/details/44994835 我经常使用order by和limit来做数据分页显示并排序,一直也没发现过什么问题 ...

  2. C#.NET WebApi返回各种类型(图片/json数据/字符串),.net图片转二进制流或byte

    using System.IO; /// <summary> /// WebApi返回图片 /// </summary> public HttpResponseMessage  ...

  3. 数据压缩之经典——哈夫曼编码(Huffman)

    (笔记图片截图自课程Image and video processing: From Mars to Hollywood with a stop at the hospital的教学视频,使用时请注意 ...

  4. Flume source 支持的type类型

    Flume是一个分布式的高可用的消费组件.通过修改配置文件,可以启动不同的agent处理不同来源的数据. agent包含source,channel,sink三个组件.今天我们学习下source的ty ...

  5. DXP常用有效的快捷操作记录

    1.在PCB中快速选中一个器件 1)  M+C+Enter将弹出元件对话框,移动一个元件后,在十字架光标 状态时按[Enter]键 2)M(Move)+M(Move)按下时,鼠标光标变成“+”后,点击 ...

  6. jQuery WeUI V0.4.2 发布

    http://www.oschina.net/news/71590/jquery-weui-v0-4-2 jQuery WeUI V0.4.2 发布了! jQuery WeUI 中使用的是官方WeUI ...

  7. TextBox Ctrl+A不能全选的问题

    问题: 当TextBox控件在设置了MultiLine=True之后,Ctrl+A 无法全选,十分影响使用体验. 对于这个问题不明所以,不知道是Bug,还是故意而为之... 解决1: 添加KeyDow ...

  8. AEAI DP V3.8.0 升级说明,开源综合应用开发平台

    1 升级说明AEAI DP 3.8版本是一次常规升级,安全机制是本次开发平台的升级重点,如果开发的应用对外部用户开放,一定要注意升级!升级说明及产品介质已上传至网盘中,地址:http://pan.ba ...

  9. Spring Cloud实践之服务注册与发现Eureka

    一.简述: 服务提供者producer与服务消费者consumer都注册到eureka server,然后服务consumer在其应用内直接调用producer的服务名来调用服务,而不是像之前一样调用 ...

  10. DS-博客作业03--栈和队列

    1.本周学习总结 第三章主要介绍栈和队列的基本概念,存储结构,基本运算算法设计和应用实例.从组成元素的逻辑关系来看,栈和队列都属于线性结构.栈和队列与线性表的不同之处就在于他们的相关运算具有一些特殊性 ...