简单登录登录流程我们先来分析一下简单登录是如何实现的。一个简单的登录过程。用户输入url以访问站点。接受用户请求后,判断用户是否已经登录,如果没有,则跳转到登录页面。用户访问登录页面,填写并提交登录表单,Web应用程序验证登录表单。如果失败,将向用户返回错误信息;如果验证成功,则将用户相关信息(通常是userid等信息)写入当前session,并将sessionid以cookie的形式发送给用户(同时,session中的身份信息以cookie的形式发送给用户,可选,使用这个cookie可以实现自动登录,如下图“登录分析图”)。用户登录后,包含其获取的sessionid的cookie将在后续访问中传递给web应用。如果web应用可以根据sessionid从session中获取到相应的身份信息(甚至进一步从数据库中查找相关的用户数据),则说明用户登录成功。Logout注销主要包括以下两个过程Destroysessioninformation(destroyontheserverside)销毁client-side相关cookies(cookie包含sessionid)自动登录一般来说,server端的session会有一定的过期时间,同理,client端包含sessionid的cookie也有过期时间。如果用户登录后长时间没有发送访问请求,当用户再次访问时,服务器的session或者客户端的cookie可能已经过期,导致服务器判断用户“未登录”,但是用户实际上并没有注销。可以通过实现“自动登录”来解决这个问题,即当会话失败时,可以自动重新登录。自动登录的基本思想:用户登录后,除了生成sessionid对应的cookie外,还会生成一个包含用户身份信息的cookie(假设这个cookie的key是identity)。身份cookie中包含的信息可以包括:用户id、用户authKey(这个比较重要,authKey的作用有点类似于password)、cookie持续时间等。为了达到自动登录的目的,过期时间Cookie的使用时间通常设置得很长(可以是一周甚至一个月)。用户session过期后,用户再次访问web应用,会带上identitycookie(因为cookie有更长的有效期)。Web应用程序首先确定用户“未登录”(因为会话无效)。Web应用程序尝试通过身份cookie自动登录用户。应用程序从identitycookie中获取“userid”和“userauthKey”,通过与数据库中的数据进行比对来验证“userauthKey”的有效性。用户authKey认证有效后,web应用为用户生成一个新的session,并将新的sessionid放入cookie中发送给用户。(即用户登录成功标志是获取包含sessionid的cookie)实例分析(yii1.1和yii2)yii1.1原生登录分析原文件及图片下载百度云盘链接yii2原生登录分析原文件及图片下载百度云盘链接摘要cookie,session是登录的核心对应关系链:客户端cookie(包括sessionid)--->sessionid对应服务端session(包括用户身份信息,如id)--->根据session中的信息,可以进一步从数据库中获取用户的详细信息(甚至是其对应的权限)。单点登录简介什么是单点登录?单点登录(Singlesign-on,缩写为SSO),又译为单点登录,是一种为许多相互关联但又相互独立的软件系统提供访问控制的属性。在具有此属性的环境中,当用户登录一个系统时,他可以获得对所有系统的访问权限,而不是一个一个地登录到每个单独的系统。该功能通常由轻量级目录访问协议(LDAP)实现,用户信息将存储在服务器上的LDAP数据库中。类似地,单点注销意味着只需一个单点注销操作即可结束对多个系统的访问。(即在多个应用系统中,用户只需登录一次,即可访问所有相互信任的应用系统;用户只需注销一次,即可退出所有应用系统)单点登录的优势降低了风险访问第三方网站(用户密码不在外部存储或管理)。用户无需在不同站点使用不同的用户名和密码,减少“密码疲劳”(passwordfatigue)。减少在使用不同站点时重新输入密码以进行身份??验证所花费的时间。降低IT成本。Web单点登录的基本思想当用户第一次访问应用系统1时,由于没有登录,会被引导到认证系统进行登录。(1)根据登录信息用户提供,认证系统进行身份验证。如果有效性检查通过,则向用户返还认证凭证票。(2)用户重新访问应用系统1,此时将票带上。应用系统1收到请求后,将车票发送给鉴权系统进行验证,以检查车票的合法性;如果ticket有效性验证通过(代表用户已经登录),则用户访问应用系统1后,再访问其他应用(3、5)时,也会将这张ticket作为自己的认证凭证。应用系统收到请求后,将票证发送给认证系统进行验证,检查票证的合法性(4、6)。如果验证通过,则用户无需重新登录即可访问应用系统2和应用系统3。总结:票是整个系统的核心,票会在用户、应用系统、认证系统的交互中传递,最终达到单点登录的目的。票证是所有系统对用户的统一认证标志。单点登录遇到的问题Q1:什么是ticket?它是由什么组成的?如前所述,票证是所有系统对用户的统一认证标志。在具体实现中,我们可以使用cookie来实现ticket的功能。最简单的说,一个包含会话ID的cookie可以被视为一张票。在后续的具体实现分析中,我们会对ticket有更深入的了解。出于安全原因,我们通常对票进行加密。为了实现单点登录功能,让用户只登录一次,应用系统必须能够识别已经登录的用户。应用系统应该能够识别和提取票据,并通过与认证系统的通信,可以自动判断当前用户是否已经登录,从而完成单点登录功能。Q2:单点登录在技术实现上有哪些分类?单点登录在技术实现上分为跨子域单点登录和完全跨域单点登录Q3:什么是跨子域单点登录?它的实现具体思路是什么?跨子域单点登录是实现同根域名站点之间的单点登录。例如,有以下站点a.example.com、b.example.com、p.example.com(CertificateAuthority),它们都有一个共同的根域名“example.com”。单点登录写cookie时,将cookie域设置为它们共同的父域(即“example.com”),这样可以在不同的子域名下使用同一个cookie(即ticket);同时,多个系统可以共享会话信息。Q4:什么是全跨域单点登录?它的实现具体思路是什么?完全跨域单点登录是指不同根域名的站点都可以实现单点登录。实现思路:每个站点需要有自己的ticket(A-tikcet,B-ticket,P-ticket);访问应用系统(A,B)时,如果没有对应的ticket,会自动重定向到鉴权系统(P),鉴权系统鉴权得到P-ticket后,重定向到应用系统(A或B),P-tikcet换取对应的A-ticket或B-ticket;注销时,必须取消所有票(P票、A票、B票)Q5:Q3中分享cookie的方式有什么限制?首先,应用组的域名要统一;其次,应用组各系统(至少web服务器)使用的技术必须相同,否则cookie的键值(tomcat为JSESSIONID,php为PHPSESSID)不一样,无法维持session和共享cookies的方式无法跨语言技术平台登录,如java、php、.net系统之间;第三,cookies本身并不安全。单点登录实现跨子域单点登录跨子域单点登录的实现比较简单,可以基于cookie来实现。基本思路如下:前提:应用组内各个站点的域名需要统一,即具有相同的根域名;应用组使用的技术必须相同,这样才能保持session(比如tomcat下cookie的键值是JSESSIONID,而PHP技术栈下是PHPSESSID)。以上,ticket具体实现为cookie中的sessionid,可以省略向认证中心申请验证ticket的步骤。具体图如下:1、当用户访问系统1(域名为a.example.com)时,系统检测到用户请求中没有ticket(即没有对应的cookie),然后判断用户未登录,将用户重定向到认证中心(使用系统1的url,认证中心可以在认证后将用户重定向到系统1)2.用户提交登录表单到验证中心,验证通过后创建相应的session。使用sessionid作为ticket,作为cookie发送给用户,将用户重定向到系统1。(注意cookie的域是根域“example.com”)3.用户被重定向到系统1(此时会带上相应的cookie作为ticket)。当系统1检测到有票时,向认证中心发起请求,验证票的有效性。4、鉴权中心验证ticket的合法性(即确实存在相应的session),并将验证结果返回给系统15,系统1从鉴权中心得到验证成功的结果后,可以认为该用户“登录”。6、用户继续访问系统2(因为系统2的域名是“b.example.com”,其根域名也是“example.com”,所以会带上对应的cookie作为ticket在这次)。系统2检测到有票,然后向认证中心发起请求,验证票的有效性。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;注销时需要注销所有票证(P-ticket、A-ticket、B-ticket),如下图所示:注:在具体实现中,tikcet可以通过cookie来实现。票证可以是包含会话ID的cookie。1、当用户访问系统1时,系统1发现用户未登录(无A票),以系统url为参数(即回调url,使其认证后可跳转)。2、认证中心发现用户没有登录(没有P-ticket),引导用户进入登录界面。3、用户向认证中心提交登录信息。4、认证中心对用户的登录信息进行验证。验证通过后,创建全局会话,并生成与当前会话绑定的P-ticket。然后将P-ticket发送给用户,用户被重定向到System1(注意此时P-ticket会被带上)。5.系统1收到带有P-ticket的请求后,会向认证中心发送请求,验证P-ticket的有效性。6、认证中心收到系统1的验证请求,将验证结果返回给系统1。同时,如果验证通过,则将映射关系(P-ticket,系统1)记录在一个mapping中表(称为“注册系统表”,记录了已登录的子系统与P-ticket的对应关系,以便用户注销时,可以向对应的子系统发送请求,销毁对应的本地session).7、系统1收到认证中心的认证结果。如果验证通过,则认为用户已“登录”。系统1在自己的系统中为用户创建会话(本地会话),并生成会话绑定A-ticket,并将映射关系(A-ticket,P-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(localsession),并生成session绑定的B-ticket,同时在自己的一张映射表中记录映射关系(A-ticket,P-ticket)(此表称为“票映射表”)。然后系统2将B-ticket发送给用户,用户在以后访问系统2时会随身携带B-ticket,然后B-ticket可以用来判断用户是否已经登录。注销图标:1.用户向系统1发起注销请求(使用A-ticket)。2、系统1根据映射表“ticketmappingtable”取出对应的P-ticket。系统1向证书颁发机构发起注销请求(使用P-ticket)。3、认证中心收到注销请求后,验证P-ticket的有效性。如果P-ticket有效,则销毁本地全局会话(根据P-ticket)。认证中心从“注册系统表”中找出与P-ticket相关的所有系统,并向所有相关系统发送注销本地会话请求。4、系统2收到认证中心的“删除本地会话”请求,根据P-ticket从“票据映射表”中取出对应的B-ticket,根据B-ticket销毁本地本地会话。5、系统1收到认证中心的“删除本地会话”请求,根据P-ticket从“票据映射表”中取出对应的A-ticket,根据A-ticket销毁本地本地会话。需要注意的地方:1.在上面的实现中,我们可以看到P-ticket需要在每一端传输,所以为了安全起见,需要对P-ticket做一些安全处理,比如加密。