【JWT学习之二】JWT实现单点登录

环境
  apache-tomcat-8.5.45
  jdk1.8.0_65
  java-jwt3.3.0
  SpringBoot-2.1.3.RELEASE

一、需求背景
一个认证中心SSO:sso.cac2020.com
两个Java Web应用:
app1:app1.cac2020.com
app2:app2.cac2020.com
以上三个系统使用jwt实现单点登录。

二、架构设计图

使用Spring boot搭建示例工程:

参考:

IntelliJ IDEA创建maven多模块项目

三、JWT单点登录方案

1、方案

前端方案:不同域应用每次请求从localStorage里获取token作为url参数,然后应用使用拦截器校验token,然后向sso应用发起校验请求;(在浏览器中跨域将获取不到localstorage中的JWT令牌,例如www.a.com域下的JWT,在www.b.com域下是获取不到的,可以使用iframe+H5的postMessage实现跨域共享JWT,具体参考:浅谈postMessage跨域通信与localStorage实现跨域共享

后端方案:为一个唯一用户生成JWT,每个JWT生成一个随机的秘钥secret,将 jwt–secret 保存到redis中,想要让某个jwt失效,只需将该记录在 redis 中删除即可(这样在解密时便无法获取到 secret)。但是这样让无状态的认证机制变成有状态了(记录了 jwt 和 secret 的对应关系)

2、流程图:

首次访问app1流程:
app1:index.html-->app1:LoginFilter.java-->sso:checkJwt-->未登录app1:index.html-->sso:index.html-->sso:login.html-->sso:login-->app1:redirect.html-->app1:index.html
已登录app1再次访问app1:
app1:index.html-->app1:LoginFilter.java-->sso:checkJwt-->app1:index.html
已登录app1然后访问app2:
app2:index.html-->app2:LoginFilter.java-->sso:checkJwt-->app2:index.html
注销app1:
app1:index.html-->app1:LoginFilter.java-->app1:logout-->sso:inValid

3、验证

 

参考文章:

方案一:spring boot如何基于回调共享JWT实现单点登录详解

代码参考:wjy_parent

 方案二:

使用JWT实现单点登录(完全跨域方案)
JWT实现单点登录

方案特点:
(1)依赖JWT包生成工具类JWTHelper工具包;
(2)采用iframe+H5的postMessage解决页面跨域问题;

方案三
基于JWT的单点登录 

github代码

本方案特点:

(1)使用cookie存储JWT,存在跨域问题;
(2)sso在首次生成JWT时将User相关信息存储到JWT里,应用侧获取到JWT解密JWT字符串获取User信息;
(3)sso和应用端使用同一个加密key,SSO侧使用加密key进行加密,应用端使用加密key进行紧密获取用户信息,如果泄露加密key就会产生安全问题。

方案四

java实现SSO单点登录(同父域跨域)
java实现 SSO 单点登录(不同父域跨域)
参考代码:github

方案特点:

方案特点:
(1)采用cookie存储JWT,页面跨域部分使用的是ajax的jsonp方式;
(2)将不同的域存到表里,然后首次登录成功之后,在页面循环调用各个域种下cookie,首次登录会慢一下

posted @ 2020-10-09 12:44  cac2020  阅读(1964)  评论(0编辑  收藏  举报