最强SSO单点登录教程(二)单点登录流程分析

一、简介

单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

二、应用场景

如公司有多个系统,分别OA系统、CRM系统、财务管理系统、设备管理系统等,总不能访问每个系统都要登录一遍吧,用户会疯掉的,应该我们认证一遍,其他系统即可访问。网上很多项目都在使用SSO单点登录,比如天猫,淘宝,CSDN,博客园.

三、流程分析

相比于单系统登录,sso需要一个独立的认证中心,只有认证中心能接受用户的用户名密码等安全信息,其他系统不提供登录入口,只接受认证中心的间接授权。间接授权通过令牌实现,sso认证中心验证用户的用户名密码没问题,创建授权令牌,在接下来的跳转过程中,授权令牌作为参数发送给各个子系统,子系统拿到令牌,即得到了授权,可以借此创建局部会话,局部会话登录方式与单系统的登录方式相同。这个过程,也就是单点登录的原理,用下图说明:

单点登录原理

步骤分析:
1.用户通过浏览器访问WMS(进销存)系统的受保护资源,访问地址为:http://www.wms.com/index,该资源为受保护资源,所以需要先判断一下用户登陆了.(是否有局部会话)
2.WMS系统发现用户并没有登陆,此时重定向到统一认证中心,并把请求地址作为参数传过去.
3.此时浏览器发出一个请求查看统一认证中心是否已经登录了?发现用户并没有登录,转发到统一认证中心的登陆页面.
4.用户输入账号密码.
5.统一认证中心认证用户信息.如果认证成功,创建浏览器与统一认证中心之间的会话,称为全局会话.同时创建授权令牌.重定向到WMS之前请求的地址,并把令牌信息带上.http://www.wms.com/index?token=4KLdkEo9k7CXfle4
6.WMS拿到令牌后,需要到统一认证中心检验令牌是否有效.
7.统一认证中心认证令牌有效,返回有效,并注册WMS的系统地址.
8.WMS得到统一认证中心的响应,知道令牌是有效的,创建局部的会话.并放行请求
9.WMS后续的请求访问的时候,发现WMS系统中有局部的会话,直接就放行了.
10.用户访问CRM(客户关系管理)系统的受保护资源,访问地址为:http://www.crm.com/index
11.WMS系统发现用户并没有登陆(没有局部会话),此时重定向到统一认证中心,并把请求地址作为参数传过去.
12.此时浏览器发出一个请求查看统一认证中心是否已经登录了?发现用户已经登录了,从会话中取出令牌,重定向到CRM系统,并把令牌带上.http://www.crm.com/index?token=SrEpDwAQlHLdkJIE
13.CRM拿到令牌后,需要到统一认证中心检验令牌是否有效.
14.统一认证中心认证令牌有效,返回有效,并注册CRM的系统地址.
15.CRM得到统一认证中心的响应,知道令牌是有效的,创建局部的会话.并放行请求
16.WMS后续的请求访问的时候,发现WMS系统中有局部的会话,直接就放行了.

用户登录成功之后,浏览器会与统一认证中心及各个子系统建立会话,浏览器与统一认证中心建立的会话称为全局会话,浏览器与各个子系统建立的会话称为局部会话,局部会话建立之后,浏览器访问子系统受保护资源将不再通过统一认证中心,全局会话与局部会话有如下约束关系.

1.局部会话存在,全局会话一定存在
2.全局会话存在,局部会话不一定存在
3.全局会话销毁,局部会话必须销毁

同学们花20分钟时间把这张流程图好好理解理解.

四、系统中的Cookie和Session存储图解

这个执行流程里面很关键的点是统一认证中心和各个子系统的cookie和session是如何存储的?如果把里面的cookie和session搞清楚了,单点登录原理基本已经理解90%了.
下面我们就通过图解的方式来看看,上面的访问流程中每个系统中的cookie和session是怎么存储的.

注意:以下图解是方便同学们理解所画的,可能有细节和真实情况有细微出入.但是不影响理解,希望不要钻牛角尖,能看懂即可.

图01:下图中,我们有三个服务器,分别是统一认证中心:www.sso.com,CRM客户关系管理系统:www.crm.com,WMS经销存系统:www.wms.com.每个系统都有一个区域存储session的地方,同学们可以暂时理解就是有个map来存储session对象.这个map的key存的是session的id,value存的是session对象.
在浏览器本地会有三个目录存储对应域名的cookie.比如:访问www.crm.com的时候会在浏览器本地的crm.com目录找对应的cookie,并在请求的时候把这个目录下的cookie请求一并的带到服务器.(这个动作是浏览器完成的,不需要用户操作.),而且www.crm.com服务器响应cookie的时候会写入到浏览器本地的crm.com目录.
目前我们还没发起请求,所以所有的内容都是空的.

单点登录01

图02:第一次访问http://www.crm.com/employee,首先会在浏览器本地的crm.com目录中寻找是否有对应的cookie,如果可以没有说明目前浏览器和服务器之间还没有建立会话,也就是说没有局部的会话.
这时候我们需要重定向到统一认证中心,查看是否有全局会话(如果有全局会话说明有其他系统已经登录了).
需要把请求访问的地址作为参数传递过去,因为待会得回调这个地址.
具体代码如下:

String url = "http://www.sso.com/checkLogin?redirectUrl=http://www.crm.com/employee";
response.sendRedirect(url);

单点登录02

图03:因为重定向,浏览器会调用统一认证www.sso.com中的checkLogin方法,查看是否有全局的会话.
这时候是请求http://www.sso.com/checkLogin地址,浏览器会在本地的sso.com目录找对应的cookie信息并在请求的时候一并得带到服务器.
但是这次的请求,浏览器本地目录sso.com中并没有cookie信息,意味浏览器和统一认证中心之间还没有建立会话.
没有会话说明并没有登录.此时要转发到统一认证中心的登陆页面.
需要把地址栏中的redirectUrl从地址栏中获取出来.

request.getParamter("redirectUrl");

并把这个参数放入到request域中.因为在登陆成功之后要跳转到用户之前访问的地址.

单点登录03

图04:转发到统一认证中的登陆页面.

单点登录04

图05:用户在统一认证中心的登陆页面输入了账户名和密码之后.统一认证中心服务器对用户信息进行认证.认证通过需要做这几个事情:
1.创建令牌,后续操作中得发给子系统,相当于间接授权.
2.创建全局会话,并把令牌存储到全局会话中.
3.把令牌信息存储到数据库中的t_token表中.主要是后续客户端校验token的有效性需要查询这种表.
4.重定向到之前用户请求的地址redirectUrl.并把令牌发给该子系统.http://www.crm.com/employee?token=VcnVMguCDWJX5zHa

统一认证中心会把session的id(我们也称为JSESSIONID)响应到客户端浏览器本地目录sso.com的cookie文件中.存储的结构是key/value格式.key是固定的字符串JSESSIONID,value是服务器sessionid的字符串.
在后续访问www.sso.com的时候都会带上这个JSESSIONID

单点登录05

图06:因为重定向,浏览器访问http://www.crm.com/employee?token=VcnVMguCDWJX5zHa,此时浏览器会在本地的crm.com把所有的cookie一并的带上.
但是本地的crm.com目录中没有内容,说明浏览器还没有和CRM系统建立会话,说明没有局部会话.
但是这次的请求中包含了token令牌的信息.
但是token是直接拼接在地址栏上的,存在被伪造的可能性.所以我们需要对token令牌做有效性的校验.

单点登录06

图07:CRM系统在接受到令牌token信息之后,需要去统一认证中心中校验令牌信息是否有效.
我们使用HttpUrlConnection发送http请求http://www.sso.com/verify?token=VcnVMguCDWJX5zHa
统一认证中心接受到这个请求后,拿到令牌token对应的值,在数据库表t_token中查询是否有这条记录.如果能找到说明这个令牌是统一认证中心发放的,返回true给调用者.
如果找不到,说明不是统一认证中心产生的,我们就该返回false给调用者.

单点登录07

图08:CRM系统发送的校验请求之后,统一认证中心返回true的结果.说明令牌是有效的.此时需要做这几件事情:
1.创建局部的会话,并且标记这个会话已登录,设置isLogin=true
2.放行该次的请求.
服务器会把session的id响应到客户端,存储在浏览器本地目录crm.com目录的cookie文件中.在后续访问www.crm.com的域名的时候会把该目录下的cookie信息一并带上.

到这一步其实我们单个系统的登陆就已经完成了.

单点登录08

图09:后续的请求.比如请求http://www.crm.com/department,首先根据请求的域名在本地crm.com目录中找到对应的cookie信息,在请求的时候会把这个JSESSIONID一并的带上,通过这个JSESSIONID可以找到服务中属于该浏览器的会话对象,并查看isLogin属性,如果为true,就直接放行该次的请求.

单点登录09

图10:此时我们访问http://www.wms.com/orderBill地址,浏览器根据域名会在本地的wms.com目录中把cookie信息在请求的时候一并带上,但是并没有cookie信息,说明浏览器还没有和WMS系统建立会话.
WMS没有局部会话,我们就要重定向到统一认证中心的checkLogin方法,查看是否有全局的会话(是否有其他的系统登陆了).

单点登录10

图11:因为重定向的关系,浏览器发送请求:
http://www.sso.com/checkLogin?redirectUrl=http://www.wms.com/orderBill,
校验是否有全局的会话,因为之前CRM已经登录了,所以有全局会话.
需要做如事情:
1.从全局会话中取出令牌信息token
2.重定向到子系统之前访问的地址,并把令牌信息带上.
http://www.wms.com/orderBill?token=VcnVMguCDWJX5zHa

单点登录11

图12:因为重定向,浏览器发送请求:
http://www.wms.com/orderBill?token=VcnVMguCDWJX5zHa,
浏览器会根据域名找本地目录中wms.com目录中的cookie,并在请求的时候一并的带上.
但是并没有cookie信息,说明没有局部会话,但是有令牌信息token.
需要到统一认证中心校验令牌信息token的有效性.

单点登录12

图13:WMS系统后台通过HttpUrlConnection的方式发送请求,校验token是否有效.
统一认证中心接受到请求之后,拿到token在数据库表中查看是否有这条记录.并响应对应的结果信息到WMS系统中.

单点登录13

图14:如果认证中心的返回的校验结果为true,说明令牌有效.那就在WMS中创建局部的会话,并在会话中设置登陆属性isLogin=true.
放行请求
浏览器会默认的被sessionid的信息通过cookie的方式响应到浏览器.
浏览器把sessionid信息存储到wms.com目录的cookie文件中.

单点登录14

图15:后去访问WMS其他的受保护资源.比如:http://www.wms.com/customer,浏览器会在本地wms.com目录中找cookie,并在请求的时候一并的把cookie信息带到服务器.
通过JSESSIONID找到数据该浏览器的会话对象,检查isLogin属性是否为true.
放行请求.

单点登录15

当这步结束之后,在CRM系统和WMS系统中都存在局部的会话,我们访问这两个系统中的任何受保护资源都会直接放行.

五、总结

同学们需要花点时间好好把上面的流程和cookie和session存储图解弄清楚了.代码实现就变得So Easy.而且开源的单点登录框架内部的实现和分析的流程基本上一致.

作者:叩丁狼教育
链接:https://www.jianshu.com/p/5cc...
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的:(单点登录,后端,java)