【学习笔记】:基于SpringBoot实现单点登录sso测试demo

一、对单点登录的认识

1、传统springboot单体项目的会话技术

传统springboot单体项目中,客户端和服务器的会话交互,我们可以通过cookie和session技术的配合使用来实现。当用户首次访问服务器的受限资源时,服务器会要求用户进行登录。用户登录后,服务器将创建一个 session 对象,用来保存用户信息,同时向客户端发送一个会话编号sessionID,保存到浏览器cookie中。浏览器后续访问时会将带有sessionID的cookie一同发送给服务器,服务器根据sessionId查到session,确定用户已经登录过,并获取到用户的信息如用户名等等。

2、微服务下的SpringSession技术

随着用户访问量的增加以及项目业务体系的不断扩大,传统单体项目逐渐呈现出各种各样的困难,如:应对高并发访问的能力差,代码耦合度高,维护困难等种种弊端。单纯提高并发能力,可以通过多台服务器集群部署和负载均衡的方式实现,同时,微服务的架构思想,也为公司业务发展和单体项目能力限制的矛盾带来了解决方案。将单体项目按照功能拆分出多个微服务,服务之间通过轻量级的通信机制建立网络连接。
但,之前通过cookie和session实现的会话技术已不能适应微服务的会话要求。session是保存在当前服务器的,而在集群模式下,如果我在A服务器登录过,后续请求如果转发到B服务器,B服务器并没有当前用户的session信息,此时,B服务器会要求我们重新登录,这显示很不合理。而且,在微服务架构下,通常不同的服务会有不同的域名,如:“search.gulimall.com”、“auth.gulimall.com”等,它们都是“gulimall.com”域名下的子域名,对应着各自的微服务,但session是不能跨域共享的。为此,springSession技术应运而生,在cookie和session技术大体方向不变的基础上,它将session信息存放到redis中,所有需要判断用户登录的请求均使用sessionID去redis中获取用户信息,同时对session放大作用域,使其在登录系统“auth.gulimall.com”中产生的session,在整个系统“gulimall.com”中都是有效的。

3、不同项目下的单点登录

随着互联网的不断发展,很多互联网公司,旗下并不仅仅只有一个系统,例如QQ、QQ音乐、QQ邮箱等等,它们都是腾讯旗下独立不同的系统,但是在使用过程中,只要你登录了QQ,之后再去打开QQ邮箱或者QQ音乐,只需要简单的授权一下即可自动登录,无需重新输入账号密码。这便是单点登录所解决的问题,用户只需要一次登录就可以访问所有相互信任的应用系统(这让我不由得想到了Java“一次编译,到处运行”的思想,当然,它们是完全不相干的两件事,这只是题外话)。

二、单点登录的实现流程

我们需要实现在服务端1登录之后,访问服务端2的资源无需重复登录的功能,具体的逻辑如下图所示:

浏览器 ssoclient1.com ssoserver.com ssoclient2.com 1、访问受限资源http://ssoclient1.com:8081/employees 2、判断是否登录: 2.1、若请求参数中有token,认为用户已登录,并创建一个局部会话session, 根据token去redis中获取用户信息,放在session中。 2.2、若请求参数中没有token,再判断局部会话session中是否有内容, 如果有,则认为用户已登录。 3、判断未登录,浏览器重定向到指定路径进行登录 http://ssoserver.com:8080/login.html 4、访问认证服务ssoserver.com的登录页, 并带上需要访问的受限资源地址 "?redirect_url=http://ssoclient1.com:8081/employees" 5、判断是否登录过(cookie中是否有存放sso_token), 如果存在,代表用户已经登录过,直接返回原资源页, 如果不存在,则输入账号密码进行登录 6、处理登录请求,校验成功后 6.1、生成一个令牌token,将用户信息保存到redis中 6.2、浏览器要在ssoserver.com域名下保存一个cookie(sso_token) 7、登录成功,重定向回原资源页 http://ssoclient1.com:8081/employees, 并返回token 8、浏览器获取到令牌后,重新访问资源 http://ssoclient1.com:8081/employees?token=xxx 9、此时用户已经登录,后续在session 生效期间,多次访问都不会再要求用户进行登录。 10、访问另一处域名下的受限资源http://ssoclient2.com:8082/boss 11、判断是否登录,判断逻辑与第2步相同 12、判断未登录,浏览器重定向到指定路径进行登录 http://ssoserver.com:8080/login.html 13、访问认证服务ssoserver.com的登录页, 并带上需要访问的受限资源地址 "?redirect_url=http://ssoclient2.com:8082/boss" 14、判断是否登录过,此时cookie中应该存放有sso_token, 代表用户已经登录过,无需重新登录,直接返回原资源页,并携带token 15、浏览器获取到令牌后,重新访问资源 http://ssoclient2.com:8082/boss?token=xxx 16、ssoclient2.com服务执行第2步操作,并在当前服务下, 创建一个局部会话session,后续session生效期间,不再要求用户重新登录。 浏览器 ssoclient1.com ssoserver.com ssoclient2.com

三、单点登录的简单实现

1、搭建环境

● 1.1、设定三个不同的域名,两个作为资源服务器,一个作为认证服务器
Alt
● 1.2、创建三个springboot项目,配置认证服务器的端口为8080,两个资源服务器的端口分别为8081和8082。

● 1.3、设定资源服务器1的资源路径为http://ssoclient1.com:8081/employees,用户需要登录后才能获取到内容
Alt
● 1.4、设定资源服务器2的资源路径为http://ssoclient2.com:8082/boss,同理,用户获取内容需要先登录
● 1.5、用户登录首先需要到认证服务器的http://ssoserver.com:8080/login.html这个路径下获取表单登录页
Alt
● 1.6、用户输入用户名和密码后,点击登录,处理登录请求,并在登录成功后,返回到原来的位置。
Alt

2、流程测试

环境搭建大致如以上所述,接下来开始测试,在多个不同的域名下单点登录功能的运行过程:

● 2.1、浏览器访问http://ssoclient1.com:8081/employees,由于首次访问,系统判断未登录,重定向到认证服务的登录页,并携带了我想要访问的资源页
Alt
● 2.2、输入账号密码后,点击登录,认证服务处理登录请求,登录成功后,认证服务会生成一个令牌token,并将token和用户信息保存到redis中,然后重定向到上一步参数中指定的url地址,并携带token,同时会指定浏览器保存一个cookie(sso_token)
Alt
● 2.3、当浏览器再次访问http://ssoclient1.com:8081/employees,将不再需要重新登录
Alt
● 2.4、此时,若浏览器访问另一个域名下的http://ssoclient2.com:8082/boss资源时,将不再需要重新登录,认证服务器判断用户已登录过,不再需要重新登录
Alt

3、总结

基于以上的测试结果,单点登录sso的整个流程就大致实现了,在这过程中,个人觉得有几个点非常重要:
● ①、去认证服务登录的时候,一定要带上自己原来的路径,否则登录后也不知道返回到哪个地方。
● ②、登录成功后,一定要在返回的时候,将token一并返回原地址,并且要指定浏览器在认证服务器的域名下保存一个cookie(sso_token)。
● ③、用户在前往登录页时,先判断认证服务的域名下是否有sso_token的cookie,如果有,代表之前已经在其他资源中登录过,无需再次登录。

感谢你能看到这里,受作者的知识水平有限,本文内容若有考虑不合理的地方,很高兴您能在评论区和我交流。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值