This commit is contained in:
fanxb 2021-07-20 15:13:03 +08:00
parent c3ab069d65
commit 47120d8af6

View File

@ -8,7 +8,7 @@ categories:
- "spring boot学习" - "spring boot学习"
--- ---
![塞尔达,林克](http://static.tapme.top/blog/20201027201713.png) ![塞尔达,林克](http://sqiniupic.fleyx.com/blog/20201027201713.png)
  最近我们组要给负责的一个管理系统 A 集成另外一个系统 B为了让用户使用更加便捷避免多个系统重复登录希望能够达到这样的效果——用户只需登录一次就能够在这两个系统中进行操作。很明显这就是**单点登录(Single Sign-On)**达到的效果,正好可以明目张胆的学一波单点登录知识。   最近我们组要给负责的一个管理系统 A 集成另外一个系统 B为了让用户使用更加便捷避免多个系统重复登录希望能够达到这样的效果——用户只需登录一次就能够在这两个系统中进行操作。很明显这就是**单点登录(Single Sign-On)**达到的效果,正好可以明目张胆的学一波单点登录知识。
@ -39,7 +39,7 @@ categories:
  cookie 允许同域名(或者父子域名)的不同端口中共享 cookie,这点和 http 的同域策略不一样http 请求只要协议、域名、端口不完全相同便认为跨域)。因此只需将多个应用前台页面部署到相同的域名(或者父子域名),然后共享 session 便能够实现单点登录。架构如下:   cookie 允许同域名(或者父子域名)的不同端口中共享 cookie,这点和 http 的同域策略不一样http 请求只要协议、域名、端口不完全相同便认为跨域)。因此只需将多个应用前台页面部署到相同的域名(或者父子域名),然后共享 session 便能够实现单点登录。架构如下:
![共享session架构](http://static.tapme.top/blog/20201027204149.png) ![共享session架构](http://sqiniupic.fleyx.com/blog/20201027204149.png)
  上面方案显而易见的限制就是不仅前台页面需要共享 cookie后台也需要共享 session可以用`jwt`来干掉 session但是又会引入新的问题这里不展开.这个方案太简单了,不作进一步说明。   上面方案显而易见的限制就是不仅前台页面需要共享 cookie后台也需要共享 session可以用`jwt`来干掉 session但是又会引入新的问题这里不展开.这个方案太简单了,不作进一步说明。
@ -47,13 +47,13 @@ categories:
  通过上文可以知道,要实现单点登录只需将用户的身份凭证共享给各个系统,让后台知道现在是`谁`在访问。就能实现一次登录,到处访问的效果,实在是非常方便的。在 session 机制中是共享 sessionId然后多个后台使用同一个 session 源即可。这里我们用一种新的基于 JWT 的 token 方式来实现,不了解 JWT 的可以看这篇:[java-jwt 生成与校验](http://www.tapme.top/blog/detail/2019-02-28-15-50),简单来说 jwt 可以携带无法篡改的信息(一段篡改就会校验失败),所以我们可以将用户 id 等非敏感信息直接放到 jwt 中,干掉了后台的 session。然后我们要做的就是将 jwt 共享给各个平台页面即可。系统架构如下:   通过上文可以知道,要实现单点登录只需将用户的身份凭证共享给各个系统,让后台知道现在是`谁`在访问。就能实现一次登录,到处访问的效果,实在是非常方便的。在 session 机制中是共享 sessionId然后多个后台使用同一个 session 源即可。这里我们用一种新的基于 JWT 的 token 方式来实现,不了解 JWT 的可以看这篇:[java-jwt 生成与校验](http://www.tapme.top/blog/detail/2019-02-28-15-50),简单来说 jwt 可以携带无法篡改的信息(一段篡改就会校验失败),所以我们可以将用户 id 等非敏感信息直接放到 jwt 中,干掉了后台的 session。然后我们要做的就是将 jwt 共享给各个平台页面即可。系统架构如下:
![基于jwt的回调](http://static.tapme.top/blog/20201027204300.png) ![基于jwt的回调](http://sqiniupic.fleyx.com/blog/20201027204300.png)
  此架构中,业务系统 A 和业务系统 B 之间不需要有任何联系,他们都只和 SSO 认证平台打交道,因此可以任意部署,没有同域的限制。你可能就要问了这样要怎么共享身份凭证(也就是 jwt 字符串)?这里就要通过 url 参数来进行骚操作了。文字总结来说是这样的jwt 存到认证平台前端的 localStore(不一定是 localStorecookiesessionStore 都可以),然后业务平台携带自己的回调地址跳转到认证中心的前台,认证中心的前台再将 ujwt 作为 url 参数,跳回到那个回调地址上,这样就完成了 jwt 的共享。   此架构中,业务系统 A 和业务系统 B 之间不需要有任何联系,他们都只和 SSO 认证平台打交道,因此可以任意部署,没有同域的限制。你可能就要问了这样要怎么共享身份凭证(也就是 jwt 字符串)?这里就要通过 url 参数来进行骚操作了。文字总结来说是这样的jwt 存到认证平台前端的 localStore(不一定是 localStorecookiesessionStore 都可以),然后业务平台携带自己的回调地址跳转到认证中心的前台,认证中心的前台再将 ujwt 作为 url 参数,跳回到那个回调地址上,这样就完成了 jwt 的共享。
  文字很可能看不懂,下面是整个过程的路程图:   文字很可能看不懂,下面是整个过程的路程图:
![流程图](http://static.tapme.top/blog/20201027204342.png) ![流程图](http://sqiniupic.fleyx.com/blog/20201027204342.png)
相信通过上面的流程图你应该能大概看明白jwt 是如何共享了的吧,还看不懂的继续看下来,下面上一个 spring boot 实现的简易 SSO 认证。主要有两个系统SSO 认证中心,系统 A系统 A 换不同端口运行就是系统 A、B、C、D 了). 相信通过上面的流程图你应该能大概看明白jwt 是如何共享了的吧,还看不懂的继续看下来,下面上一个 spring boot 实现的简易 SSO 认证。主要有两个系统SSO 认证中心,系统 A系统 A 换不同端口运行就是系统 A、B、C、D 了).
@ -123,12 +123,12 @@ SSO 说:好嘞,这个地址是合法的可以送 jwt 过去,这就跳转
  这里上几个效果图:   这里上几个效果图:
- 系统 A 首次登陆系统 - 系统 A 首次登陆系统
![系统A登陆gif](http://static.tapme.top/blog/20201027205546.gif) ![系统A登陆gif](http://sqiniupic.fleyx.com/blog/20201027205546.gif)
可以看到首次登陆是需要跳到 sso 认证中心输入用户名密码进行登陆验证的。登陆成功回跳后接口请求成功。 可以看到首次登陆是需要跳到 sso 认证中心输入用户名密码进行登陆验证的。登陆成功回跳后接口请求成功。
- 将 A 的启动端口改为 8082 后再次启动,当作系统 B - 将 A 的启动端口改为 8082 后再次启动,当作系统 B
![系统B登陆gif](http://static.tapme.top/blog/20201028091355.gif) ![系统B登陆gif](http://sqiniupic.fleyx.com/blog/20201028091355.gif)
可以看到这次是无需登陆的,跳到认证中心后就马上跳回了,如果去掉 alert 一般是看不出跳转过程的。 可以看到这次是无需登陆的,跳到认证中心后就马上跳回了,如果去掉 alert 一般是看不出跳转过程的。