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

简单登陆

登陆流程

首先让咱们分析一下一个简单的登陆是怎么实现的。php

  1. 一个简单的登陆流程java

    • 用户输入url访问站点,接受用户请求后判断用户是否已经登陆,若未登陆则跳转到登陆页面
    • 用户访问登陆页面,填写并提交登陆表单
    • web应用对登陆表单进行验证,若验证失败,则返回错误信息给用户;若验证成功,则将用户相关的信息(一般为用户id等信息)写入到当前的session中,将session id以cookie的形式发送给用户(同时能够将session中的身份信息以cookie的形式发送给用户,这个是可选的,使用该cookie能够实现自动登陆,以下面的“登陆分析图”中所示)。
    • 用户登陆后,后续的访问中会将其得到的包含session id的cookie传递给web应用,若web应用能根据session id从session中获取到相应的身份信息(甚至进一步从数据库查找到相关的用户数据),则表明用户成功登陆。
  2. 退出登陆
    退出登陆主要包括如下两个流程web

    • 销毁session信息 (在服务端销毁)
    • 销毁客户端的相关cookie(包含session id的cookie)

自动登陆

一般来讲,服务器端的session会有必定的过时时间,一样的,客户端中包含session id的cookie也有过时时间。若用户登陆后,长时间没有发出访问请求,则等到用户再次访问时,可能服务端的session或客户端的cookie已经失效,致使服务器判断用户为“未登陆”,而实际上用户并无退出登陆过。能够经过实现“自动登陆”来解决这个问题,即在session失效的时候,能够从新自动登陆。数据库

自动登陆的基本思路:跨域

  1. 在用户登陆后,除了生成session id对应的cookie,还会生成一个包含用户身份信息的cookie(假设这个cookie的key为identity)。identity cookie包含的信息能够有:用户id,用户authKey(这个比较重要,authKey的功能有点相似于password),cookie持续时间等。为了达到自动登陆的目的,一般会将该cookie的过时时间设置的特别长(能够是一个星期甚至一个月)。
  2. 在用户session失效后,用户再次访问web应用,会带上identity cookie(由于该cookie的有效期较长)。web应用首先判断用户为“未登陆”状态(由于session失效了)。
  3. web应用尝试经过identity cookie为用户自动登陆。应用从identity cookie中获取“用户id”和“用户authKey”,经过与数据库中的数据进行对比,校验“用户authKey”的有效性。
  4. 用户authKey认证有效后,web应用为用户生成新的session,并将新的session id放入cookie发送给用户。(即用户登陆成功的标志为获取到包含session id的cookie)

例子分析(yii1.1与yii2)

  1. yii1.1原生登陆分析
    yii1.1原生登陆分析

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

  2. yii2原生登陆分析
    图片描述

    原文件和图片下载百度云盘连接安全

小结

  1. cookie,session是实现登陆的核心
  2. 对应关系链: 客户端的cookie(包含了session id) ---> session id对应服务器端的session(包含了用户的身份信息,如id) ---> 根据session中的信息,能够进一步从数据库中获取用户的详细信息(甚至是其相应的权限)

单点登陆介绍

什么是单点登陆?

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

单点登陆的优势

  • 下降访问第三方网站风险(用户密码不存储或外部管理)。
  • 用户不须要在不一样的站点使用不一样的用户名和密码,减小“密码疲劳”(password fatigue )。
  • 减小在使用不一样站点时花费时间来从新输入密码进行身份验证。
  • 下降IT成本。

web单点登陆的基本思路

  1. 当用户第一次访问应用系统1的时候,由于尚未登陆,会被引导到认证系统中进行登陆(1)
  2. 根据用户提供的登陆信息, 认证系统进行身份校验,若是经过效校验,返回给用户一个认证的凭据ticket(2)
  3. 用户从新访问应用系统1,此时会带上ticket。应用系统1接受到请求后会把ticket发送到认证系统进行校验,检查ticket的合法性;若ticket合法性验证经过(表明用户已经登陆),则用户能够访问应用系统1
  4. 用户再访问别的应用的时候(3,5)也会将这个ticket 带上,做为本身认证的凭据,应用系统接受到请求以后会把ticket送到认证系统进行效验,检查ticket的合法性(4,6)。若是经过效验,用户就能够在不用再次登陆的状况下访问应用系统2和应用系统3了。
  • 单点登陆机制

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

单点登陆会遇到的问题

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

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来实现,基本思想以下:

  1. 前提: 应用群中各个站点的域名须要统一,即具备相同的根域名;应用群使用的技术要相同,这样才可以维持回话(例如tomcat下cookie的key值为JSESSIONID,而PHP技术栈下则为PHPSESSID)
  2. 在前面所述的“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作一些安全性处理,如加密等。

相关文章
相关标签/搜索