为什么要实现单点登录?
我们希望在分布式开发的过程中,当用户在登录任何一个子系统的时候,在一定时间范围内,相关联的系统在一定时间范围内可实现免登录。
1、在单体架构下:
步骤:(cookie和session)
假如客端对模块进行访问,对某一功能接口进行访问(即对受保护的资源进行访问)
1、客户端会将当前的浏览器里以cookie的方式保存一个对应访问地址的sessionId,携带去服务端请求
2、首次登陆服务端检测不到会返回一个登录界面
3、输入用户名密码
4、服务端会和DB进行一个校验
5、通过校验服务端会创建一个session,然后将受保护的资源返回给客户段;同时也会将域名之下的session返回给客户端(以cookie的方式存在浏览器本地)
6只要sesionid没有过期,再去访问会携带sessionid,服务端会直接进行资源的返回,而不需要进行登录
2、cookie+session 完成单点登录
跟着上图的流程走
1、客户端访问子系统1⃣️(假如是user.com的资源)
在此应该实现一个去拦截:拦截器(/user/*)下的所有受保护资源
拦截器实现的功能:
判断当前子系统域名下的sessionId
2、页面(携带子系统的url)重定向到sso的登录认证中心
目的是判断是否有sessionId
3、sso判断没有对应子系统的sessionId;将页面登录页面login.html返回给用户
4客户端携带usename&password(提供给sso中心的登录接口进行处理)
5、sso验证用户密码是否成功(去DB进行一个校验)
验证成功后的处理:
1、创建sso.server的sessionId(客户端就存在了,对应域名的sessionId)
2、创建令牌token,颁发相应的子系统
(随机数、UUID)
3、对于相应子系统所要访问的url进行跳转并*颁发token*
(
1) 在此,token的安全性问题,回归token的创建方式
2)其次就是token的传输方式
http协议中参数传输方式:基于cookie、禁用cookie(可以通过传参数)、请求头请求体
)
6、进行颁发token还是回到拦截器访问受保护的资源
拦截器功能:接收token并且验证token的有效性
(为防止别人拿到不可用的token或者去篡改这个token带来的安全性隐患:
比如防止第一次传递的时候随便传个token不能够放行,防止伪造)
7、将token传到sso服务端去验证token接口验证一下有效性
token一定存在服务端吗:
sso.server:默认存在jvm内存中(存在服务端,如果服务挂掉了,那么token就无效了)
token的持久化
redis?
mysql?
磁盘中?
拓展:jwt的使用
8、验证成功返回ture,再去回到访问子系统的url;拦截器放行
9、受保护的页面返回给客户端
当再次访问,user子系统或者其他子系统
再次登录子系统user
此时,因为sso服务端已经创建了token并颁发了有效的token,所以我们想要直接访问受保护资源
那怎么办呢?
答:可以在拦截器中:记录局部子系统的sessionId 进行有效验证
(也就是上次拦截器方形的时候将seesionId带给客户端)
登录其他子系统(order)步骤
请求其他子系统的受保护资源(携带全局sessionId) 拦截器,请求判断sso中心是否有session Id(因为上次登录系统已经存储过l,所以存在)直接颁发token 拦截器放行(颁发token) 创建局部的子系统的局部sessionId,如下图
总结拓展:
由于拦截器这一步反复使用,可以在集成一种解决方案
CAS SSO:central Authenation Service 三步 (1)部署服务端jar包:sso-server.jar (2)在各个子系统中引入sso-client(代码相通,可复用) (3)在各个子系统中做一些配置



