简单点说就是公司有A,B两个系统,我登陆了A系统以后再跳转到B系统能够直接访问,而不须要再次登陆B系统.java
在讲解单点登陆以前先讲解几个基本的概念:nginx
Cookie是一段不超过4KB的小型文本数据,是保存在用户本地的,常见格式为:web
Expires属性:设置Cookie的生存期redis
Domain属性:指定了能够访问该 Cookie 的 Web 站点或域跨域
好比图中的Domain:192.168.1.72这就表示只能只有1.72下的请求可使用这个cookie,百度什么的就不能使用这个cookie浏览器
Path属性:定义了Web站点上能够访问该Cookie的目录安全
图中的Path是/,这表示这个cookie是根目录拥有的,只要1.72的请求都会默认带上这个cookie,加入Path是/webaikn,那么只有http://192.168.1.72/webaikn/**的请求会带上这个cookie,而http://192.168.1.72/webadmin/**就没法使用这个cookie服务器
其余:略cookie
http请求是无状态的,可是咱们平常访问系统的时候都是但愿系统能记住我这个用户,这时候就要靠session去实现,所以session成为会话控制.可是光靠session仍是没法实现会话控制的,还须要cookie的配置,如图所示:session
这个JESSIONID就是保持会话的关键,它的value对应的就是该用户在服务器的sessionId,因此咱们代码直接写HttpSession session = request.getSession(); 才不会数据错乱.
Ps:session的存在方便了咱们的开发,可是也在必定程度上增长了麻烦,好比多机部署时候的seesion丢失,
一句话,转发是服务器行为,重定向是客户端行为.
转发和重定向均可以由java后台实现,例如:
请求转发:
request.getRequestDispatcher("/user").forward(request,response);
重定向:
response.sendRedirect(request.getContextPath + "/user")
当设置转发以后,请求会直接去转发的地址,而重定向的话请求会先返回客户端,而后再由客户端从新发起请求去新的地址.这里就隐藏了一个知识点,当我在后台设置了cookie而后重定向的时候,其实我重定向的请求中已经带上了我设置的cookie
(1) 假设A和B两个系统都部署在192.168.110.110服务器上
用户在登陆了A系统以后,后台代码设置将userName和password做为cookie存入到用户的浏览器中并将cookie的domain设置为192.168.110.110,path设置为/
以后访问B系统的时候因为你们的Ip都是同样的,因此B系统可以获取到A系统设置的cookie,这是只须要设置一个拦截器,在拦截器中判断用户是不是登陆状态,若是未登陆就去request中获取cookie信息,获取到以后解密而后模拟登陆,这样用户能够无感知的登陆到B系统.
点评:这是典型的同域单点登陆实现方式,局限性很是大,必需要两个系统在同一个服务器或者二级域名相同的状况下才能实现,通常称为伪单点登陆
(2) 知识库系统的单点登陆实现
知识库的方案1的基础上增长了Nginx做为反向代理(有反向代理就有正向代理,自行查找资料什么是正向代理什么是反向代理)
虽然webaikn和webadmin部署在不一样的服务器,可是对客户是无感知的,因为都是访问Nginx,而后再由nginx作转发代理,因此域名是同一个,这样cookie也是能够共享的,这里有一个点须要注意一下,webaikn多是多机部署,因此nginx在作转发的时候须要设置ip_hash策略,目的就是保证用户上一次请求访问的哪台服务器,下一次仍是访问那一台服务器,不至于致使session丢失的状况.
点评:解决了多机部署单点登陆失效的状况,可是仍是须要服务器端保存用户的session状态,一方面对于服务器端会产生内存压力,另外一方面须要配置ip_hash致使流量不均衡,某些服务器压力比较大的状况.并且用户名和密码保存在cookie中也存在必定的安全隐患,只要被截取到一次请求都会形成帐户被盗的状况
(3) 跨域token实现单点登陆
主要步骤:
生成一个cookie,name就叫token,value能够是任意不重复的值,uuid就行(注意这个cookie是浏览器和sso系统之间的)
将用户信息保存到redis中,key是生成的uuid,value就是user对象
重定向到oldUrl的地址,注意要拼接上token参数
没有找到:说明其余子系统发起了注销操做,须要重定向到sso登陆页面
找到了:有了User对象以后能够判断当前请求是否在用户权限表中,存在就直接放行,不存在返回权限不足,以后的请求都须要将token放到请求头信息或者url中
点评:独立出单点登陆认证中心,统一作权限认证操做,清晰明了
子系统不须要用session保存用户登陆状态,减轻了服务器的负担
每次请求都是以token做为验证标准,就算请求被拦截了,用户的信息也不会泄露
后期作三方登陆的时候也不须要将用户数据暴露给其余系统,其余系统能获取的只有token(真要作三方登陆redis中存放的确定是最简单的一些用户信息)
下面这个图取自哪位大佬我已经没有地址了,好像是百宝门