自己学习做的笔记.没有具体代码
单点登录:多系统,单一位置登录,实现多系统同时登录的一种技术.
也就是说多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
和三方登录Oauth2是有区别的.Oauth2属于三方登录.通常是某系统,使用其他系统的用户,实现本系统登录的方式.比如京东中使用微信登录
我们可以通过Oauth2实现单点登录,但是Oauth2不是单点登录
单点登录和三方登录不是一回事,不要混肴
解决单点登录的实现方案很多,Session跨域,SpringSession共享,NginxSession共享,最主要,最常用的通过Token技术实现.相对来说用Session和JWT来实现单点登录的更多些
一、
Session
跨域
所谓
Session
跨域就是摒弃了系统(Tomcat)提供的
Session
,而使用自定义的类似
Session
的机制来保存客户端数据的一种解决方案。
如:通过设置
cookie
的
domain
来实现
cookie
的跨域传递。在
cookie
中传递一个自定义
的
session_id
。这个
session_id
是客户端的唯一标记。将这个标记作为
key
,将客户端需要保
存的数据作为
value
,在服务端进行保存(数据库保存或
NoSQL
保存)。这种机制就是
Session
的跨域解决。
绝大多数用 domain 来实现 cookie 的跨域传递实现,但是也可以用请求头信息实现.JWT技术一般用于头信息来实现跨域单点登录
-----------------------------------------------------------------------------------------------------------------------------
核心技术点:
1.HTTP,Cookie与Session
2.Cookie与Session的关系
3.Cookie,SSO令牌的载体
4.决定Cookie内容,生命周期和有效范围的7个属性
1)name和value key=value
2)expires 过期时间
3)path和domain
4)httpOnly(设置了HttpOnly的话用JS是获取不到cookie的)和secure(只在https时有效.http不可见)
5.JavaScript操作Cookie的方法 document.cookie(获取所有cookie字符串
C1=TEST1;C2=TEST2;C3=TEST3)
新增cookie document.cookie="c4=test4"
替换 document.cookie="c4=newtest4"
这里注意下,JS可以直接引入Cookie依赖操作
httpOnly不允许js操作,因此这里无法设置httpOnly,因为没任何意义
设置时间path document.cookie="c4=newtest4;expires="+[GMT时间]+";path=/xxxx;domain=www.amamaw.com;secure" secure这样写就是true
6.Java Web应用中操作Cookie的方法
7.filter.Web层拦截
大概的了解下Cookie
HttpSession session这个参数,有兴趣可以试试,有这个参数和没这个参数,对Cookie有什么影响
Cookie并没有真正的删除方式,可以设置存活时间,比如说cookie.setMaxAge(-1000),当浏览器接受到这个时候,认为该Cookie的存活时间已经过期,就不会再发送回服务端了.也可以进行Cookie覆盖,但是进行Cookie覆盖的时候必须name相同外Path,domain属性相同,不然浏览器会认为是两个不同的Cookie
注意:cookie存活时间设置为-1000 浏览器F12可能会看到还会携带过来,但是服务器接收时候是没有这个Cookie的 存活时间设置为0的话,浏览器看不到携带过来,当然服务端也不能收到这应该是浏览器的原因
关于Path和domain可以自己测试,domain就是域,在域相同的时候会携带
关于Cookie的几点
1.过多过大的Cookie浪费网络流浪
2.不同浏览器对Cookie有个数限制
3.浏览器对Cookie有大小限制
4.Cookie保存在客户端,不要在Cookie里存放敏感信息
Cookie做为SSO令牌载体,伴随着的一个问题,既然Cookie创建后,域,Path等相同会伴随着每个请求,那该在什么时间点,读取Cookie对Cookie进行权限判断?肯定不会在每个业务请求都去判断
那么就可以扯到拦截层,
Filter和Web的拦截器,监听器就不扯了吧,越扯越远写不完了
SpringBoot中实现过滤器的几种方式
这里注意下,高版本的SpringBoot很可能导致此配置无效,记得当时用的2.7.1好像,改回2.2.0以下就OK了,至于具体从哪个版本开始改动的没具体了解.
第二种直接加@Compent注解 但是这样的测试是默认所有请求都经过该过滤器,不过建议使用第三种,因不知道会不会出问题
第三种
自定义一个过滤器进行配置
同域时,Cookie传递可以设置Path为"/"
不同域是.依靠domain
spring-session
技术是
spring
提供的用于处理集群会话共享的解决方案。
spring-session
技术是将用户
session
数据保存到三方存储容器中,如:
mysql
,
redis
等。
注意:Spring-session 技术是解决同域名下的多服务器集群 session 共享问题的。不能解决跨域
session 共享问题。注意不能解决跨域共享!!!注意不能解决跨域共享!!!注意不能解决跨域共享!!!
三、
Nginx Session
共享
nginx
中的
ip_hash
技术能够将某个
ip
的请求定向到同一台后端,这样一来这个
ip
下的
某个客户端和某个后端就能建立起稳固的
session
ip_hash
是容易理解的,但是因为仅仅能用
ip
这个因子来分配后端,
因此 ip_hash 是有
缺陷的,不能在一些情况下使用:
nginx
不是最前端的服务器。
ip_hash
要求
nginx
一定是最前端的服务器,否则
nginx
得不到正确
ip
,就不能根据
ip
作
hash
。譬如使用的是
squid
为最前端,那么
nginx
取
ip
时只能得到
squid
的服务器
ip
地址,
用这个地址来作分流是肯定错乱的。
nginx
的后端还有其它方式的负载均衡。
假如
nginx
后端又有其它负载均衡,将请求又通过另外的方式分流了,那么某个客户端
的请求肯定不能定位到同一台
session
应用服务器上。
nginx演示配置 通过开启ip_hash来实现Session对应服务器,但是不推荐使用
四、
Token
机制(SSO单点登录主流实现方案)
JSON Web Token JWT 可以当成实现Token的有效方案
JWT是一种紧凑(数据量小)且自包含(使用JWT的payload记录用户必要且不隐私的数据,这样减少数据库访问),用于多方传递JSON对象的技术.
JWT一般用于处理用户身份验证或数据信息交换.
JWT
数据结构
JWT
的数据结构是 :
A.B.C
。 由字符点‘.’来分隔三部分数据。
A - header 头信息:{“alg”: “
加密算法名称
”, “typ” : “JWT”}
B - payload
(有效荷载):三部分唯一可以不传的,但是不传不代表没有
payload中常用信息有已注册信息(registered claims),公开数据(public claims),私有数据(private claims),公开数据和私有数据可以自定义,但是不要和已注册信息Key重名,可以配置
C - Signature 签名:
用
header
中定义的加密算法,将
header
和
payload
进行加密,并使用点进行连接。如:加密后的
head.
加密后的
payload
。再使用相同的加密算
法,对加密后的数据和签名信息进行加密。得到最终结果。
大致执行流程: