昨天碰到了一篇讲单点登录(SSO)的文章,作者可能是从字面意思理解的单点登录(只允许一个地方登录,一方登陆了,另一方就要下线,这种应该是单设备登录)。正好最近我也在处理多系统访问的问题,也要用到单点登录,就打算整理点东西。
单点登录: 英文Single Sign On,根据英文含义不难理解,即:单一标记(单点)登录。就是说,我只需要登录一次。例如:QQ,我在QQ空间登录一次,我可以去访问QQ产品的其他服务:QQ邮箱、腾讯新闻等,都能保证你的账户保持登录状态。
单设备登录: 就是只能在一个设备上登录,若同时在其他设备登录,先前登录的用户会被提醒:该账户在其他设备登录。例如qq,小米手机登录中,同时拿华为手机登录该账户,小米手机的账户会被挤下线。
SSO(Single Sign-On)是一种统一认证和授权机制,指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后,再访问其他应用中的受保护资源时,不再需要重新登录验证。
解决了用户只需要登录一次就可以访问所有相互信任的应用系统,而不用重复登录。
如下图所示:
当用户第一次访问应用系统1的时候,因为还没有登录,会被引导到认证系统中进行登录;根据用户提供的登录信息,认证系统进行身份效验,如果通过效验,应该返回给用户一个认证的凭据--ticket;用户再访问别的应用的时候,就会将这个ticket带上,作为自己认证的凭据,应用系统接受到请求之后会把ticket送到认证系统进行效验,检查ticket的合法性(4,6)。如果通过效验,用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了。
从上图可以看出sso的实现技术点:
1)所有应用系统共享 一个身份认证系统 。
统一的认证系统是SSO的前提之一。
认证系统的主要功能是将用户的登录信息和用户信息库相比较,对用户进行登录认证;认证成功后,认证系统应该生成统一的认证标志(ticket),返还给用户。
另外,认证系统还应该对ticket进行效验,判断其有效性。
2)所有应用系统能够识别和提取ticket信息
要实现SSO的功能,让用户只登录一次,就必须让应用系统能够识别已经登录过的用户。
应用系统应该能对ticket进行识别和提取,通过与认证系统的通讯,能自动判断当前用户是否登录过,从而完成单点登录的功能。
关于 统一身份认证机制 :如下图
①用户请求访问业务系统。
②业务系统在系统中查看是否有对应请求的有效令牌,若有,则读取对应的身份信息,允许其访问;若没有或令牌无效,则把用户重定向到统一身份认证平台,并携带业务系统地址,进入第③步。
③在统一身份认证平台提供的页面中,用户输入身份凭证信息,平台验证此身份凭证信息,若有效,则生成一个有效的令牌给用户,进入第④步;若无效,则继续进行认证,直到认证成功或退出为止。
④用户携带第③步获取的令牌,再次访问业务系统。
⑤业务系统获取用户携带的令牌,提交到认证平台进行有效性检查和身份信息获取。
⑥若令牌通过有效性检查,则认证平台会把令牌对应的用户身份信息返回给业务系统,业务系统把身份信息和有效令牌写入会话状态中,允许用户以此身份信息进行业务系统的各种 *** 作;若令牌未通过有效性检查,则会再次重定向到认证平台,返回第③步。
1)提高用户的效率。
用户不再被多次登录困扰,也不需要记住多个 ID 和密码。另外,用户忘记密码并求助于支持人员的情况也会减少。
2)提高开发人员的效率。
SSO 为开发人员提供了一个通用的身份验证框架。
实际上,如果 SSO 机制是独立的,那么开发人员就完全不需要为身份验证 *** 心。
他们可以假设,只要对应用程序的请求附带一个用户名,身份验证就已经完成了。
3)简化管理。
如果应用程序加入了单点登录协议,管理用户帐号的负担就会减轻。
简化的程度取决于应用程序,因为 SSO 只处理身份验证。
所以,应用程序可能仍然需要设置用户的属性(比如访问特权)。
1)不利于重构
因为涉及到的系统很多,要重构必须要兼容所有的系统,可能很耗时
2) 无人看守桌面
因为只需要登录一次,所有的授权的应用系统都可以访问,可能导致一些很重要的信息泄露。
实现方式一:父域 Cookie
实现方式二:认证中心
实现方式三:LocalStorage 跨域
补充:域名分级
在 B/S 系统中,登录功能通常都是基于 Cookie 来实现的。当用户登录成功后,一般会将登录状态记录到 Session 中,或者是给用户签发一个 Token,无论哪一种方式,都需要在客户端保存一些信息(Session ID 或 Token ),并要求客户端在之后的每次请求中携带它们。在这样的场景下,使用 Cookie 无疑是最方便的,因此我们一般都会将 Session 的 ID 或 Token 保存到 Cookie 中,当服务端收到请求后,通过验证 Cookie 中的信息来判断用户是否登录 。
单点登录(Single Sign On, SSO)是指在同一帐号平台下的多个应用系统中,用户只需登录一次,即可访问所有相互信任的应用系统。举例来说,百度贴吧和百度地图是百度公司旗下的两个不同的应用系统,如果用户在百度贴吧登录过之后,当他访问百度地图时无需再次登录,那么就说明百度贴吧和百度地图之间实现了单点登录。
单点登录的本质就是在多个应用系统中共享登录状态。如果用户的登录状态是记录在 Session 中的,要实现共享登录状态,就要先共享 Session,比如可以将 Session 序列化到 Redis 中,让多个应用系统共享同一个 Redis,直接读取 Redis 来获取 Session。
当然仅此是不够的,因为不同的应用系统有着不同的域名,尽管 Session 共享了,但是由于 Session ID 是往往保存在浏览器 Cookie 中的,因此存在作用域的限制,无法跨域名传递,也就是说当用户在 app1com 中登录后,Session ID 仅在浏览器访问 app1com 时才会自动在请求头中携带,而当浏览器访问 app2com 时,Session ID 是不会被带过去的。实现单点登录的关键在于,如何让 Session ID(或 Token)在多个域中共享。
实现方式一:父域 Cookie
在将具体实现之前,我们先来聊一聊 Cookie 的作用域。
Cookie 的作用域由 domain 属性和 path 属性共同决定。domain 属性的有效值为当前域或其父域的域名/IP地址,在 Tomcat 中,domain 属性默认为当前域的域名/IP地址。path 属性的有效值是以“/”开头的路径,在 Tomcat 中,path 属性默认为当前 Web 应用的上下文路径。
如果将 Cookie 的 domain 属性设置为当前域的父域,那么就认为它是父域 Cookie。Cookie 有一个特点,即父域中的 Cookie 被子域所共享,换言之,子域会自动继承父域中的Cookie。
利用 Cookie 的这个特点,不难想到,将 Session ID(或 Token)保存到父域中不就行了。没错,我们只需要将 Cookie 的 domain 属性设置为父域的域名(主域名),同时将 Cookie 的 path 属性设置为根路径,这样所有的子域应用就都可以访问到这个 Cookie 了。不过这要求应用系统的域名需建立在一个共同的主域名之下,如 tiebabaiducom 和 mapbaiducom,它们都建立在 baiducom 这个主域名之下,那么它们就可以通过这种方式来实现单点登录。
总结:此种实现方式比较简单,但不支持跨主域名。
实现方式二:认证中心
我们可以部署一个认证中心,认证中心就是一个专门负责处理登录请求的独立的 Web 服务。
用户统一在认证中心进行登录,登录成功后,认证中心记录用户的登录状态,并将 Token 写入 Cookie。(注意这个 Cookie 是认证中心的,应用系统是访问不到的。)
应用系统检查当前请求有没有 Token,如果没有,说明用户在当前系统中尚未登录,那么就将页面跳转至认证中心。由于这个 *** 作会将认证中心的 Cookie 自动带过去,因此,认证中心能够根据 Cookie 知道用户是否已经登录过了。如果认证中心发现用户尚未登录,则返回登录页面,等待用户登录,如果发现用户已经登录过了,就不会让用户再次登录了,而是会跳转回目标 URL ,并在跳转前生成一个 Token,拼接在目标 URL 的后面,回传给目标应用系统。
应用系统拿到 Token 之后,还需要向认证中心确认下 Token 的合法性,防止用户伪造。确认无误后,应用系统记录用户的登录状态,并将 Token 写入 Cookie,然后给本次访问放行。(注意这个 Cookie 是当前应用系统的,其他应用系统是访问不到的。)当用户再次访问当前应用系统时,就会自动带上这个 Token,应用系统验证 Token 发现用户已登录,于是就不会有认证中心什么事了。
这里顺便介绍两款认证中心的开源实现:
Apereo CAS 是一个企业级单点登录系统,其中 CAS 的意思是”Central Authentication Service“。它最初是耶鲁大学实验室的项目,后来转让给了 JASIG 组织,项目更名为 JASIG CAS,后来该组织并入了Apereo 基金会,项目也随之更名为 Apereo CAS。
XXL-SSO 是一个简易的单点登录系统,由大众点评工程师许雪里个人开发,代码比较简单,没有做安全控制,因而不推荐直接应用在项目中,这里列出来仅供参考。
总结:此种实现方式相对复杂,支持跨域,扩展性好,是单点登录的标准做法。
实现方式三:LocalStorage 跨域
前面,我们说实现单点登录的关键在于,如何让 Session ID(或 Token)在多个域中共享。
父域 Cookie 确实是一种不错的解决方案,但是不支持跨域。那么有没有什么奇技巧能够让 Cookie 跨域传递呢?
很遗憾,浏览器对 Cookie 的跨域限制越来越严格。Chrome 浏览器还给 Cookie 新增了一个 SameSite 属性,此举几乎禁止了一切跨域请求的 Cookie 传递(超链接除外),并且只有当使用 >
不过,在前后端分离的情况下,完全可以不使用 Cookie,我们可以选择将 Session ID (或 Token )保存到浏览器的 LocalStorage 中,让前端在每次向后端发送请求时,主动将 LocalStorage 的数据传递给服务端。这些都是由前端来控制的,后端需要做的仅仅是在用户登录成功后,将 Session ID (或 Token )放在响应体中传递给前端。
在这样的场景下,单点登录完全可以在前端实现。前端拿到 Session ID (或 Token )后,除了将它写入自己的 LocalStorage 中之外,还可以通过特殊手段将它写入多个其他域下的 LocalStorage 中。
————————————————
版权声明:本文为CSDN博主「风水道人」的原创文章,遵循CC 40 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:>
前端通过 iframe+postMessage() 方式,将同一份 Token 写入到了多个域下的 LocalStorage 中,前端每次在向后端发送请求之前,都会主动从 LocalStorage 中读取 Token 并在请求中携带,这样就实现了同一份 Token 被多个域所共享。
总结:此种实现方式完全由前端控制,几乎不需要后端参与,同样支持跨域。
补充:域名分级
从专业的角度来说(根据《计算机网络》中的定义),com、cn 为一级域名(也称顶级域名),comcn、baiducom 为二级域名,sinacomcn、tiebabaiducom 为三级域名,以此类推,N 级域名就是 N-1 级域名的直接子域名。
从使用者的角度来说,一般把可支持独立备案的主域名称作一级域名,如 baiducom、sinacomcn 皆可称作一级域名,在主域名下建立的直接子域名称作二级域名,如 tiebabaiducom 为二级域名。
用户已经登录企业门户的前提下,单点登录到门户中的应用。门户与应用的域名有一定关系,门户的域名是父级域,比如xxxcom,应用的域名为二级域,比如axxxcom、bxxxcom、cxxxcom登录门户后,颁发一个token用于接口认证,创建一个key为_a,domain为xxxcom,path为/,value为token的cookie并set-cookie到前端,访问其他应用时,由于_a的domain为其他应用域名的父级域,会自动带上_a到后端,后端根据_a做接口校验,获取用户信息等资源,实现单点登录。
用户已经登录企业门户的前提下,单点登录到门户中的应用。门户与应用的域名没有关系。
依旧使用上面的方案一,但是token使用header传输,不存在跨域问题
以上方案二,有一些细节需要注意
没有门户,或者用户不提前登录门户的前提下,不同应用实现单点登录。
CAS,网上教程众多,比如 CAS简介和整体流程 。
方案二实际上也是利用了CAS思想实现的,ticket和token,可以类比CAS的ST(Service Ticket)和TGC(Ticket Granted Cookie)。如果用户的平台,比较大,用户量也比较多,建议把单点登陆单独做成一个服务。如果用户量减少,用户又没有做成单独应用的资金预算,可以将单点登陆,与用户最主要的一个业务系统合并在一起,对外(就是对其他应用系统)提供登陆验证的接口程序。
单点登陆的验证,可以采用多次交互验证的方式验证,流程如下:
1应用系统将账号密码传给单点登陆服务
2单点登陆服务验证账号密码是否正确,如不正确返回错误信息;如正确,随机生成一个验证字符,返回给应用系统
3应用系统,将单点登陆返回的随机字符在发送给单点登陆的验证服务,再次验证这个随机字符是否正确
4验证成功,则最终登陆成功。
单点登录原理是让应用系统能够识别已经登录过的用户。应用系统应该能对ticket进行识别和提取,通过与认证系统的通讯,能自动判断当前用户是否登录过,从而完成单点登录的功能。
用户第一次访问应用系统的时候,因为还没有登录,会被引导到认证系统中进行登录;根据用户提供的登录信息,认证系统进行身份校验,如果通过校验,应该返回给用户一个认证的凭据--ticket。
用户再访问别的应用的时候,就会将这个ticket带上,作为自己认证的凭据,应用系统接受到请求之后会把ticket送到认证系统进行校验,检查ticket的合法性。如果通过校验,用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了。
扩展资料
优点:
1)提高用户的效率。
用户不再被多次登录困扰,也不需要记住多个 ID 和密码。另外,用户忘记密码并求助于支持人员的情况也会减少。
2)提高开发人员的效率。
SSO 为开发人员提供了一个通用的身份验证框架。实际上,如果 SSO 机制是独立的,那么开发人员就完全不需要为身份验证 *** 心。他们可以假设,只要对应用程序的请求附带一个用户名,身份验证就已经完成了。
3)简化管理。
如果应用程序加入了单点登录协议,管理用户帐号的负担就会减轻。简化的程度取决于应用程序,因为 SSO 只处理身份验证。所以,应用程序可能仍然需要设置用户的属性(比如访问特权)。
所谓单点登录(Single Sign On就是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。其实对于程序员在技术上要实现就得就是多个不同域名间共享cookie的问题。最近在为ERP添加一个部署在另一台机器上,链接到原有老系统中的子项目,调用原有老项目中的Login实现单点登录,尝试了N次屡试不成,最后确定问题,是,net20与40中对cookie的加密/解密方法由此差异,于是经过研究,重写实现了一个可以在不同net版本中实现单点登录的简单方法。
代码:
protected void btnLogin_Click(object sender, EventArgs e)
{
//认证开票,跳转到原始请求页面
SystemWebSecurityFormsAuthenticationRedirectFromLoginPage("ejiyuan", false);
}
配置文件:
<!--访问权限控制-->
<authorization>
<deny users=""/>
</authorization>
<!--身份认证方式-->
<authentication mode="Forms">
<forms name="ASPNET" protection="All" enableCrossAppRedirects="true" loginUrl="Loginaspx" timeout="2880" path="/" domain="localcom"/>
</authentication>
<!--验证算法-->
<machineKey validationKey="F9D1A2D3E1D3E2F7B3D9F90FF3965ABDAC304902" decryptionKey="F9D1A2D3E1D3E2F7B3D9F90FF3965ABDAC304902F8D923AC" validation="SHA1" decryption="3DES" /> <compilation debug="true"/>SSO英文全称Single Sign On(单点登录)。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制。它是目前比较流行的企业业务整合的解决方案之一。(本段内容来自百度百科)
二级域名的单点登录
什么是二级域名呢?例如:
site1domaincom
site2domaincom
对于二级域名的单点登录,我们可以非常方便的通过共享cookie来实现,简单的说,就是在设置Form票据的时候,将cookie的domain设置为顶级域名即可,例如:
>
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)