资讯专栏INFORMATION COLUMN

web登录分析(简单登录与单点登录)

jasperyang / 1515人阅读

摘要:系统从认证中心得到校验成功的结果后,则可以认为用户已登录。认证中心发现用户未登录没有,将用户引导至登录界面。用户提交登录信息到认证中心。

简单登录 登录流程

首先让我们分析一下一个简单的登录是怎么实现的。

一个简单的登录流程

用户输入url访问站点,接受用户请求后判断用户是否已经登录,若未登录则跳转到登录页面

用户访问登录页面,填写并提交登录表单

web应用对登录表单进行验证,若验证失败,则返回错误信息给用户;若验证成功,则将用户相关的信息(通常为用户id等信息)写入到当前的session中,将session id以cookie的形式发送给用户(同时可以将session中的身份信息以cookie的形式发送给用户,这个是可选的,使用该cookie可以实现自动登录,如下面的“登录分析图”中所示)。

用户登录后,后续的访问中会将其获得的包含session id的cookie传递给web应用,若web应用能根据session id从session中获取到相应的身份信息(甚至进一步从数据库查找到相关的用户数据),则代表用户成功登录。

退出登录
退出登录主要包括以下两个流程

销毁session信息 (在服务端销毁)

销毁客户端的相关cookie(包含session id的cookie)

自动登录

通常来说,服务器端的session会有一定的过期时间,同样的,客户端中包含session id的cookie也有过期时间。若用户登录后,长时间没有发出访问请求,则等到用户再次访问时,可能服务端的session或客户端的cookie已经失效,导致服务器判断用户为“未登录”,而实际上用户并没有退出登录过。可以通过实现“自动登录”来解决这个问题,即在session失效的时候,可以重新自动登录。

自动登录的基本思路:

在用户登录后,除了生成session id对应的cookie,还会生成一个包含用户身份信息的cookie(假设这个cookie的key为identity)。identity cookie包含的信息可以有:用户id,用户authKey(这个比较重要,authKey的功能有点类似于password),cookie持续时间等。为了达到自动登录的目的,通常会将该cookie的过期时间设置的特别长(可以是一个星期甚至一个月)。

在用户session失效后,用户再次访问web应用,会带上identity cookie(因为该cookie的有效期较长)。web应用首先判断用户为“未登录”状态(因为session失效了)。

web应用尝试通过identity cookie为用户自动登录。应用从identity cookie中获取“用户id”和“用户authKey”,通过与数据库中的数据进行对比,校验“用户authKey”的有效性。

用户authKey认证有效后,web应用为用户生成新的session,并将新的session id放入cookie发送给用户。(即用户登录成功的标志为获取到包含session id的cookie)

例子分析(yii1.1与yii2)

yii1.1原生登录分析

原文件和图片下载百度云盘链接

yii2原生登录分析

原文件和图片下载百度云盘链接

小结

cookie,session是实现登录的核心

对应关系链: 客户端的cookie(包含了session id) ---> session id对应服务器端的session(包含了用户的身份信息,如id) ---> 根据session中的信息,可以进一步从数据库中获取用户的详细信息(甚至是其相应的权限)


单点登录介绍 什么是单点登录?

单点登录(Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。在拥有这项属性的环境中,当用户在某个系统登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一注销(single sign-off)就是指,只需要单一的注销动作,就可以结束对于多个系统的访问权限。(即,在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统;用户只需要退出登录一次就可以退出所有的应用系统

单点登录的优点

降低访问第三方网站风险(用户密码不存储或外部管理)。

用户不需要在不同的站点使用不同的用户名和密码,减少“密码疲劳”(password fatigue )。

减少在使用不同站点时花费时间来重新输入密码进行身份验证。

降低IT成本。

web单点登录的基本思路

当用户第一次访问应用系统1的时候,因为还没有登录,会被引导到认证系统中进行登录(1)

根据用户提供的登录信息, 认证系统进行身份校验,如果通过效校验,返回给用户一个认证的凭据ticket(2)

用户重新访问应用系统1,此时会带上ticket。应用系统1接受到请求后会把ticket发送到认证系统进行校验,检查ticket的合法性;若ticket合法性验证通过(代表用户已经登录),则用户可以访问应用系统1

用户再访问别的应用的时候(3,5)也会将这个ticket 带上,作为自己认证的凭据,应用系统接受到请求之后会把ticket送到认证系统进行效验,检查ticket的合法性(4,6)。如果通过效验,用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了。

总结:ticket是整个系统的核心,ticket会在用户,应用系统,认证系统的交互中传输,最终达到实现单点登录的目的。ticket是所有系统对用户的统一的认证标志。

单点登录会遇到的问题

Q1:ticket是什么?由什么组成?
正如前面所说,ticket是所有系统对用户的统一的认证标志。在具体的实现中,我们可以用cookie来实现ticket的功能。最简单的,一个包含session id的cookie就可以看成是一个ticket。在后续对具体实现的分析中,我们会更深入地理解ticket。出于安全需要,通常我们会对ticket进行加密。要实现SSO的功能,让用户只登录一次,就必须让应用系统能够识别已经登录过的用户。应用系统应该能对ticket进行识别和提取,通过与认证系统的通讯,能自动判断当前用户是否登录过,从而完成单点登录的功能。

Q2:单点登录在技术实现上有哪些分类?
在技术实现上,单点登录可以分为跨子域单点登录完全跨域单点登录

Q3:什么是跨子域单点登录?其实现的具体思路是什么?
跨子域单点登录即在具有相同根域名的站点之间实现单点登录。例如,有以下站点a.example.com, b.example.com, p.example.com(认证中心),它们都有一个共同的根域名“example.com”。在单点登录写cookie时,把cookie的域设为它们共同的父域(即“example.com”),这样在不同的子域名下都可以使用同一个cookie(即ticket);与此同时,可以让多个系统共享session信息。

Q4:什么是完全跨域单点登录?其实现的具体思路是什么?
完全跨域单点登录即具有不同根域名的站点之间实现单点登录。实现思路:每个站点需要有自己的ticket(A-tikcet,B-ticket,P-ticket);当访问应用系统(A,B)时,若没有相应的ticket,则自动重定向到认证系统(P),在认证系统认证获得P-ticket后重定向到应用系统(A或B),用P-tikcet换取相应的A-ticket或B-ticket;注销的时候要注销所有的ticket(P-ticket,A-ticket,B-ticket)

Q5:Q3中共享cookie的方式存在什么局限?
首先,应用群域名得统一;其次,应用群各系统使用的技术(至少是web服务器)要相同,不然cookie的key值(tomcat为JSESSIONID,php为PHPSESSID)不同,无法维持会话,共享cookie的方式是无法实现跨语言技术平台登录的,比如java、php、.net系统之间;第三,cookie本身不安全。


单点登录实现 跨子域单点登录

跨子域单点登录的实现相对比较简单,可以基于cookie来实现,基本思想如下:

前提: 应用群中各个站点的域名需要统一,即具有相同的根域名;应用群使用的技术要相同,这样才能够维持回话(例如tomcat下cookie的key值为JSESSIONID,而PHP技术栈下则为PHPSESSID)

在前面所述的“web单点登录的基本思路”的基础上,将ticket具体实现为cookie中的session id,并且可以省略应用到认证中心对ticket进行校验的步骤。

具体图示如下:

1.当用户访问系统1(域名为a.example.com)时,系统检测到用户的请求中没有ticket(即没有相应的cookie),则判断用户未登录,将用户重定向到认证中心(带上系统1的url,则认证完后认证中心可将用户重定向会系统1)

2.用户提交登录表单到认证中心,验证通过后创建相应的session。将session id作为ticket,以cookie的方式发送给用户,并将用户重定向到系统1。(注意,cookie的域为根域“example.com”

3.用户重定向到系统1(此时会带上相应的cookie作为ticket)。系统1检测到有ticket,则向认证中心发起请求,验证ticket的有效性。

4.认证中心验证ticket的有效性(即确实有对应的session),将校验结果返回给系统1

5.系统1从认证中心得到校验成功的结果后,则可以认为用户“已登录”。

6.用户继续访问系统2(因为系统2的域名为“b.example.com”,其根域名也为“example.com”,故此时会带上相应的cookie作为ticket)。系统2检测到有ticket,则向认证中心发起请求,验证ticket的有效性。

7.认证中心验证ticket的有效性(即确实有对应的session),将校验结果返回给系统2。

8.系统2从认证中心得到校验成功的结果后,则可以认为用户“已登录”。

完全跨域单点登录

完全跨域单点登录的实现思路正如前面所述,这里复述一下:
1.每个站点需要有自己的ticket(假设:系统1为A-tikcet,系统2为B-ticket,认证中心为P-ticket)
2.当访问应用系统(系统1,系统2)时,若没有相应的ticket,则自动重定向到认证系统(P),在认证系统认证获得P-ticket后重定向到应用系统(系统1或系统2),用P-tikcet换取相应的A-ticket或B-ticket;注销的时候要注销所有的ticket(P-ticket,A-ticket,B-ticket)

具体图示如下:
注意: 在具体的实现中,可以用cookie来实现tikcet。ticket可以是包含session id的cookie。

1.用户访问系统1,系统1发现用户未登录(没有A-ticket),跳转至认证中心,并带上系统的url作为参数(即回调url,这样认证后就可以跳转回来了)。

2.认证中心发现用户未登录(没有P-ticket),将用户引导至登录界面。

3.用户提交登录信息到认证中心。

4.认证中心校验用户的登录信息,通过验证后,创建一个全局session,生成一个绑定当前session的P-ticket。然后将P-ticket发送给用户,并将用户重定向到系统1(注意,此时会带上P-ticket)。

5.系统1接收到带有P-ticket的请求后,会向认证中心发出一个请求,验证P-ticket的有效性。

6.认证中心接收到系统1的校验请求,将校验结果返回给系统1。同时若验证通过则会将映射关系(P-ticket,系统1)记录到一个映射表中(称该表为“注册系统表”,即记录那些登录的子系统与P-ticket的对应关系,这样在用户注销的时候就可以向相应的子系统发送请求,销毁相应的局部session)。

7.系统1接受到认证中心的校验结果,若校验通过,则认为用户是“已登录”,系统1在自身系统为用户创建一个session(局部session),并生成一个绑定该session的A-ticket,同时将映射关系(A-ticket,P-ticket)记录到自己的一个映射表中(称该表为“ticket映射表”)。然后系统1将A-ticket发送给用户,在后续用户对系统1的访问中,会带上A-ticket,则可以通过A-ticket判断用户是否已经登录。

8.用户访问系统2,系统2发现用户为登录(没有B-ticket),跳转到认证中心(此时对认证中心的访问会带上P-ticket),并带上系统2的url作为参数(即回调url,这样认证后就可以跳转回来了)。

9.认证中心发现用户已经登录(因为用户已经持有P-ticket),确认P-ticket的有效性后即可认为用户“已登录”。认证中心将用户重定向到系统2(带上P-ticket)。

10.系统2接收到带有P-ticket的请求后,会向认证中心发出一个请求,验证P-ticket的有效性。

11.认证中心接收到系统2的校验请求,将校验结果返回给系统2。同时若验证通过则会将映射关系(P-ticket,系统2)添加到“注册系统表”

12.系统2接受到认证中心的校验结果,若校验通过,则认为用户是“已登录”,系统2在自身系统为用户创建一个session(局部session),并生成一个绑定该session的B-ticket,同时将映射关系(A-ticket,P-ticket)记录到自己的一个映射表中(称该表为“ticket映射表”)。然后系统2将B-ticket发送给用户,在后续用户对系统2的访问中,会带上B-ticket,则可以通过B-ticket判断用户是否已经登录。


注销图示:

1.用户向系统1发起注销请求(会带上A-ticket)。

2.系统1根据映射表“ticket映射表”,取出相应的P-ticket。系统1向认证中心发起注销请求(带上P-ticket)。

3.认证中心接收到注销请求后,验证P-ticket的有效性。若P-ticket有效,则销毁本地的全局session(根据P-ticket)。认证中心从“注册系统表”中查找出与P-ticket相关的所有系统,向所有相关的系统发送注销局部会话请求。

4.系统2接收到认证中心的“注销局部会话”请求,根据P-ticket从“ticket映射表”中取出相应的B-ticket,根据B-ticket销毁本地局部会话。

5.系统1接收到认证中心的“注销局部会话”请求,根据P-ticket从“ticket映射表”中取出相应的A-ticket,根据A-ticket销毁本地局部会话。


值得注意的地方:
1.在上面的实现中,我们可以看到P-ticket是需要在各个端传递的,故出于安全考虑,应该对P-ticket做一些安全性处理,如加密等。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30812.html

相关文章

  • 从前端开发者看待用友建筑云移动端单点登录报错原因

    摘要:本文对单点登录有一个初步介绍,重点叙述前端开发者使用单点登录可能遇到的问题,以及问题分析方案全部来源于用友建筑云,本文仅用于内部分享,所以不过多介绍方案实现。 本文对单点登录有一个初步介绍,重点叙述前端开发者使用单点登录可能遇到的问题,以及问题分析!方案全部来源于用友建筑云,本文仅用于内部分享,所以不过多介绍方案实现。原文来自博客 单点登录介绍 showImg(https://seg...

    Youngdze 评论0 收藏0
  • 单点登录实现原理及小结

    摘要:用户登录成功之后,会与认证中心及各个子系统建立会话,用户与认证中心建立的会话称为全局会话,用户与各个子系统建立的会话称为局部会话。 在工作中,有这样一个需求,因为公司有多个管理平台,每次登录一个平台都需要输入账号和密码进行登录,特别麻烦,所以,希望只需登录一个平台的账号和密码,其他平台的不用输入账号和密码也可以自动登录,即单点登录,经过两周的研究和实践,终于完成了该需求,目前公司的两个...

    TigerChain 评论0 收藏0
  • 单点登录消息队列

    摘要:前言很久都没有写博客了,这次为大家简单介绍两个在开发中经常使用的概念单点登录和消息队列以及具体到中的一些实现方案。单点登录的实质就是安全上下文或凭证在多个应用系统之间的传递或共享。 前言 很久都没有写博客了,这次为大家简单介绍两个在WEB开发中经常使用的概念——单点登录和消息队列以及具体到J2EE中的一些实现方案。本文原创性的工作比较少,主要是一些总结概括和自己的理解。 单点登录SS...

    Jioby 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<