赞
踩
目录
SSO:Single Sign On,简称SSO。翻译成中文就是单点登录。简单来讲就是,当用户在身份认证服务器(IAM)上登录一次以后,即可获得访问单点登录系统中其它(需要授权的)关联系统和应用软件的权限,同时这种实现是不需要管理员对用户的登录状态或其他信息进行修改的,这也意味着,在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。这种方式减少了多次登录产生的时间消耗,提升了用户体验,也辅助了用户管理,是目前一种比较流行的身份认证体系。
单点登录:SSO的中文翻译。
单点登出:逻辑要完整的话,理论上有单点登录就有单点登出(注销)。某个用户在一个系统登出(退出/注销)了,认证中心需要把该用户的会话和cookie之类的数据全部清理(销毁),然后再通知各个业务系统,让它们都把该用户(如果有登录当前业务的话)的登录会话统统注销,这样才叫实现了了单点登出。某些实际应用里面,为了处理简单,以及用户体验更好,某个用户A在一个系统B登出,仅仅销毁用户A在B系统下的会话数据。
CAS:Central Authentication Service 中心认证服务(备注:这里不是指CAS无锁编程),耶鲁大学提出的,一个著名的开源SSO解决方案(框架),目前比较流行。使用CAS框架实现多个不同站点的单点登录的原理的关键就是使用一个认证服务器集中处理登陆的事务。是一个企业级的单点登录解决方案,在部署上面,CAS分为 CAS Server 和 CAS Client 其中 CAS Server 需要独立部署,CAS Client(这里的Client不是说的PC终端或者移动终端)而是CAS本身一种C/S架构,可认为每个接入的Web应用都是CAS的Client,CAS支持的客户端也比较多,包括Java,.Net,PHP,Perl,Apache,Ruby等等。
统一登录:也叫统一登录认证,其实和单点登录是一个意思,不过找不到统一登录的出处了,理解即可。
有端SSO:一般传统意义上的SSO都是无端的单点登录,所有的SSO逻辑都由前端(Web业务系统)和后端来完成。随着一些“巨无霸”终端产品的出现,基于终端的SSO方案也逐渐流行起来,其实也是原理是类似的。
IAM:Identity and Access Management,身份识别与访问管理。目前一般指统一的身份认证平台,集中管理企业员工和资产的身份和认证管理。
OpenSSO:之前是SUN的一款开源产品,自从SUN被Oracle收购之后,这个项目已经被Oracle关闭了(连官网:www.opensso.org都不可访问了),所以介绍资料极其稀少,可以去这里(https://www.oracle.com/technetwork/testcontent/opensso-ds-129530.pdf?ssSourceSiteId=otncn)看下介绍。
OpenAM:从架构上来看,原型(前身)应该是来自于OpenSSO。
回到Web1.0时代,这里有“世界上最好的语言”PHP,也有新贵JSP等等,每个企业都有大量的内部应用系统(譬如oa系统,hr系统,休假系统……),小的企业可能十几个应用,大的可能有成千上万个系统,而且很可能每个系统都还是不同的语言写的。
在日常工作中,人类为了能进入各个系统,必须得通过帐号和密码进行登录验证(身份验证)后,才能获取到跟自己身份相符的信息。那么问题来了,这么多的系统,每个系统都搞一个密码的话,大多数用户都要记忆不少于10个用户名和相应密码。为了便于记忆,很多人都在不同的站点使用相同的用户名和密码,甚至密码可能极其简单(否则真记不住啊!),虽然这样可以减少负担,但是同时也降低了安全性。
随着业务子系统越来越多,什么办公自动化(OA)系统,财务管理系统,档案管理系统,信息查询系统等。每个系统都使用独立的登录和验证机制,那么每天工作人员都要登录不同的系统进行办公。用户登录的频繁操作,降低了员工的工作效率,造成工作成本的浪费。而大量的密码和用户名的记忆时间长了也会出现问题,忘记密码或者混淆密码都会造成很大的麻烦。
基于以上原因,为用户提供一个畅通的登录通道变得十分重要。 单点登录(SSO)是一种帮助用户快捷访问网络中多个站点的安全通信技术。单点登录系统基于一种安全的通信协议,该协议通过多个系统之间的用户身份信息的交换来实现单点登录。使用单点登录系统时,用户只需要登录一次,就可以访问多个系统,不需要记忆多个口令密码。单点登录使用户可以快速访问网络,从而提高工作效率,同时也能帮助提高系统的安全性。
备注:其实,类似讲解SSO原理的文章,尤其是CAS相关的介绍,网上已经汗牛充栋,本文在简单介绍原理的同时,主要是简单提出我们(iOA)的一些优势。另外,免费(开源)的SSO系统相比商业的SSO系统,在可用性,安全性和用户体验等方面肯定是有一些差距的,但是,也不用担心,基于开源组件发展出来的优秀系统也数不胜数。
图1 基本环节图(图片来之网上)
先举两个单点登录的例子:
这个是腾讯内网统一登录的界面,只要员工登录了iOA,再登录其它的系统时,并不需要真正的去进行账密或者扫码(或者其它多因子)认证,只需要点一下“iOA快速登录”确认一下即可。
图2 腾讯内网单点登录系统Web界面
下图是常见的QQ邮箱登录(Web)界面,在你本地登录了QQ的情况下,你可以选择使用本地的QQ的账号直接登录进入(也是点一下即可)。
图3 QQ邮箱统一登录Web界面
在实际应用中,单点登录的需求和实施环境,在大部分情况下没有想象中那么标准和简单,要想大部分场景完全按标准方案来实施可能是一种一厢情愿的美好愿望。当然,也不是完全没有办法,在计算机领域,遇到解决不了的问题,那就加层嘛,一层不够,再加一层嘛。总之就是把跟客户需求变化和环境相关的部分通过中间层来隔离,我们先看看客户对于SSO可能有哪些需求:
纯Web的(这个应该最多吧,又分跨域和不跨域)
带端的SSO(有些可能希望直接结合Windows登录凭据)
支持移动平台的SSO
要求满足标准方案的SSO
更苛刻的甚至譬如不能改动现存系统(三无系统,无源码,无厂商维护,无SSO接口)等
最终的研发,部署实施方案,需要根据我们的技术实现实情,结合客户需求,客户环境,以及客户长远规划来具体规划制定。
SSO有如此多的好处,而且看起来体验也是极好的,那么从技术的角度来说一般来讲如何实现呢?
登录的本质是什么?先以Web系统为例(终端软件登录其实是类似的。备注:SSO的技术实现方式有多种,这里主要介绍基于cookies的一种实现方式):
用户通过浏览器访问 oa.com ,首次进入需要输入用户名和密码(为了简化说明,这里不考虑密码加盐,hash存储等等细节)之后,提交给后端。
后端经过验证(要么自己验证,要么找其它系统验证),确认账密正确有效,则会告诉前端登录成功,同时回给前端一个ticket(中文一般叫票据。有些地方叫token,可能混淆了登录和授权,不过也说得过去吧)。
这个ticket实际上就是本次登录成功的一个凭据(注意:这个凭据对于后端来说一般都是有时效的,时效有长有短,可以根据你系统的重要性自己控制)。
前端拿到这个ticket之后,它会存起来,存在哪里呢?对于前端来说,存在cookie里面似乎是一个兼容性和实用性最好的方案(备注:实际上就是存在cookie里面的。部分现代浏览器考虑到cookie的安全性,专门设计了自己的存储方式,虽然安全性更好,但是因为兼容性不太好,在跨平台应用上实际不流行)。
用户再通过浏览器访问 oa.com 的其它页面时,http协议会把 oa.com 的所有cookie信息都带到后端,后端发现cookie里面有ticket,经过验证,票据正确有效,则会回给浏览器带用户属性和信息的页面。
备注:ticket会是一些什么?对于计算机来说当然就是一串二进制数,对于人来讲可能也是一串看不懂的“奇怪”字符串,里面有登录信息(譬如账号,登录时间等)的hash的签名等信息。
接下来进入正题,聊一聊如何实现这个SSO?
方案一、从这个登录流程来看,我们是不是把cookie共享给其它的Web应用就可以了?譬如共享给 hr.com ,在访问 hr.com 时,让它也把 oa.com 的ticket带过来就行了嘛!想象很美好,显示很骨感,因为跨域问题的存在,cookie是不能跨域的,因此简单说,该方案在99%的场景基本不可行。
方案二、既然有跨域的问题,那我们搞个大一统,把所有的域名都统一起来,譬如叫什么 great-unification.com O(∩_∩)O,其它的业务都是它的二级域名,譬如 oa.great-unification.com,hr.great-unification.com。这样前端cookie是可以共享了,问题来到了后端,因为后端的各个业务目前都是独立的,要共享这个ticket,必须得有一个共享系统(否则其它的业务系统哪知道是谁登录了啊),假定用目前流行的redis(高性能内存数据库)来共享这个ticket。想一想有点激动,似乎真的可行!不过似乎经不住第二想,如果业务特别多,架构不同,语言也不同,要共享起来这个改造工作量几乎不可行,简单来讲,这个方案基本没有通用性啊(备注:对于小型的企业,业务不多,架构语言都是统一的,这个方案是有一定的实操性的)。另外还有一个致命的问题,那就是各个系统的用户名(账号)得一样才行,否则会乱套(当然,SSO的目标就是消除多个账号)。
方案三、前面两个方案虽然没有解决根本问题,但是我们可以确认,首先,在Web应用里面,使用cookie来共享信息,这个是基本靠谱和通用的,但是各个应用只记录自己的特定cookie。其次,账密要统一,一个用户只有一个账密,由一个统一的系统去注册和认证。所有的应用在未登录前,都先跳转到一个统一的认证中心(假定就叫 sso.com )去做账密认证,认证完成后再跳转回原始页面,并通过url参数的方式把票据带给原始页面,我们先结合下面的时序图来简单锊一锊整个过程(包括第二个业务的自动登录流程):
用户首次(未登录)访问站点www.oa.com/page1,oa.com站点业务服务器检测到用户没登录(因为没有带上本站约定的授权cookie,也可能带了,但是已经过期了。备注:这个约定的cookie里面存储的就是session信息),于是通知浏览器跳转到SSO的服务站点(sso.com),并在跳转的URL参数中带上当前页面的完整地址,以便后面登录成功后能自动跳转回本页(这样才能给用户一个错觉,似乎SSO系统和业务站点是一个统一的系统)。
SSO服务站点(sso.com)检测该请求用户有没有登录,发现用户未登录(因为是首次),于是通知浏览器显示登录界面(可能是扫码,帐号,多因子等其中一种登录方式)。用户提交登录请求到SSO的服务端,服务端验证通过(可以是SSO自己具备验证功能,或者找第三方系统进行验证)后,创建和账号对应的用户登录凭据(ticket)。然后,SSO服务端会通知浏览器设置sso.com的cookie(标识登录成功的session id),并把该ticket(可能加密编码过)作为站点www.oa.com/page1d 的参数,然后跳转回www.oa.com/page1。
浏览器跳转回oa.com站点后。oa.com服务端检测到浏览器请求的URL中带了单点登录的ticket,于是把这个ticket发到SSO服务站点验证有效性。SSO服务端站点验证ticket的有效性(判断是不是SSO站点签发出来的),如果ticket有效,则把对应的用户账号信息等信息返回给oa.com的服务端站点。
oa.com服务端站点根据返回的信息生成用户在本站的session信息,作为要记录的cookie返回给浏览器,从而完成了在本站的登录以及会话保持。备注:通常业务站点在这里还会让浏览器跳转一次,可以想一想是为什么?!
如果后面用户通过同一个浏览器再访问oa.com的另外一个子页面时(譬如:www.oa.com/page2),都会带上这个cookie,从而保持了在本站的登录状态。
如果用户再访问www.hr.com/home1,hr.com的服务器站点检测到用户没登录,于是通知浏览器跳转到SSO的服务站点。
因为刚刚登录过,所以浏览器访问SSO服务站点时会带上上述2环节创建的sso.com的session的cookie。SSO服务站点根据该cookie信息能准确的找到对应用户,于是通知浏览器跳转回站点www.hr.com/home1,并在跳转回去的URL参数里面带上一个新创建的ticket。
显然,hr.com的服务端检测到浏览器请求的URL中带上了单点登录的ticket,于是又会自动走一遍类似上述3-4步骤,完成用户在hr.com的自动登录。
图4 首次访问时序图
图5 第二个业务访问时序图
备注:
1、观察图4和图5里面标红的地方,会发现本质就是浏览器把sso.com和各个业务系统的cookie给认真的保存下来了。
2、会话:因为HTTP是无状态协议,必须有一个会话的概念由服务器和终端(浏览器)来统一维持,确认前后多次请求是否是同一个用户。
3、ticket:需要具备基础信息,譬如用户名,登录时间等。需要具备签名信息,否则无法判断是否是SSO签发的票据,签名用私钥签名即可,签名对象可以是原始数据的hash。
3.1 basicinfo+userid+time → sha256/md5 → hash信息
3.2 hash信息 → 签名(+私钥) → 签名信息
3.3 ticket = basicinfo+userid+time+签名信息
4、全局会话,局部会话,ticket有效期(ticket是否可以只用一次等等),防止ticket或者token出现在地址栏等等,实际上后台还有很多细节需要处理,这里不再赘述。
下面看下开源框架CAS的时序图(备注:CAS还有一种代理模式,解决业务A依赖业务B的场景,譬如用户访问业务A,同时业务A需要通过SSO访问业务B才能完成用户的访问,这种场景下业务A变成了业务B的访问者。有兴趣的同学可以自行参考[10][11]),会发现整体流程和上面的介绍比较相似,原因很简单,CAS也是基于cookie来共享信息的。或者可以认为上述的介绍只是CAS的一个简单原理的陈述。CAS里面的TGT和ST有点类似iOA里面的大小票概念。
图6 CAS时序图(图片版权:CAS)
个人认为一套SSO需要具备三套基础组件(参考了CAS的设计):
SSO服务系统:单点登录共享系统,生成统一的认证标识(ticket),并能够对ticket进行校验,判断其有效性。共享票据,用户数据等信息。
SSO客户端系统:嵌入到第三方(接入)应用里面,通过接管http请求,按需转发到SSO服务系统,并与原始应用进行数据交互。支持对ticket进行提取和识别,通过与SSO服务系统双向通讯,能自动判断当前用户是否具备登录态,自动完成单点登录功能。
IAM系统:身份认证系统,可以和SSO服务系统合并,主要功能是将用户的登录信息和用户信息库相比较,确认用户身份,在大型商业应用里面,建议IAM独立出来(实际上也确实如此)。SSO系统提供一个标准认证接口层,支持跟各种IAM系统做认证对接,甚至可以支持链式认证。
这是另外一种SSO原理的单点登录,之所以在这里提出来是因为,借助于iOA(零信任终端安全管理系统)的零信任网关,理论上可以方便的实现一个最低成本的SSO,前提是需要托管证书(解决https加密应用问题)到零信任网关上面,通过7层代理网关的流量托管转发功能,识别(实际上可配置)应用的登录页面,并自动完成登录验证流程。因为该方案的接入和部署相对来说比较重和繁琐,这里不做重点介绍。
截止到目前,上面讨论的内容都基本上跟终端无关(包括CAS),可以称之为Web SSO。而在实际应用中,有端的SSO因为一些IM软件的存在,实际上也是非常常见和流行的,譬如常见的QQ,企业微信的功能(备注:本文不讨论基于系统级的SSO)。而iOA实现有端SSO的两个优势是:
天然有端。
天然需要登录。
我们接下来简单看下基于端,SSO的流程上面会有哪些变化,以及实现机制和基本原理。实际上主流程上并无大的变化(主要是利用终端的登录凭据),依然以上面的访问www.oa.com和www.hr.com为例,有差异的部分标红了。
用户首次(未登录)访问站点www.oa.com/page1,oa.com站点业务服务器检测到用户没登录(因为没有带上本站约定的授权cookie,也可能带了,但是已经过期了。备注:这个约定的cookie里面存储的就是session信息),于是通知浏览器跳转到SSO的服务站点(sso.com),并在跳转的URL参数中带上当前页面的完整地址,以便后面登录成功后能自动跳转回本页(这样才能给用户一个错觉,似乎SSO系统和业务站点是一个统一的系统)。
SSO服务站点(sso.com)首先请求本地的服务接口(譬如:127.0.0.1:12345,实际应用场景一般是https协议,并且使用域名请求),请求该用户是否已经在端上登录,如果访问不通,或者端返回状态未登录,则整个流程就变成了无端的Web SSO,不再赘述。若该用户已经在端上登录,则端会先向SSO服务端(带着端的登录票据,账户信息和业务域名)请求一个ticket信息,端在终端返回浏览器已经登录时,会把该ticket信息一并回给浏览器,并把该ticket(可能加密编码过)作为站点www.oa.com/page1d 的参数,然后跳转回www.oa.com/page1。
浏览器跳转回oa.com站点后。oa.com服务端检测到浏览器请求的URL中带了单点登录的ticket,于是把这个ticket发到SSO服务站点验证有效性。SSO服务端站点验证ticket的有效性(判断是不是SSO站点签发出来的),如果ticket有效,则把对应的用户账号信息等信息返回给oa.com的服务端站点。
oa.com服务端站点根据返回的信息生成用户在本站的session信息,作为要记录的cookie返回给浏览器,从而完成了在本站的登录以及会话保持。
如果后面用户通过同一个浏览器再访问oa.com的另外一个子页面时(譬如:www.oa.com/page2),都会带上这个cookie,从而保持了在本站的登录状态。
如果用户再访问www.hr.com/home1,hr.com的服务器站点检测到用户没登录,于是通知浏览器跳转到SSO的服务站点。
注意,这里流程上有一些差异了,hr.com又走一遍上述2-4的步骤,完成用户在hr.com的自动登录。
备注:上述流程没有考虑安全性问题,因此大大简化了。考虑上安全性和单点登出等细节,协议复杂度会上一个数量级(理论和工程化的差距,了解即可)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。