SSO单点登录

SSO单点登录

1 学习SSO,先来学习会话?

web环境中的会话指的是一个浏览器与交互系统之间通信的时间间隔,通常指从注册进入系统到注销退出系统之间所经过的时间,

浏览器和服务器之间的会话是通过本地的cookie来实现的。

过程解释:

1.浏览器在第一次访问tomcat服务器的时候,tomcat服务器会在浏览器端创建session对象,并存储到map中,key是session的id。value是session本身。
2.在响应的时候会把session的id通过cookie的方式写入到客户端的浏览器端。
3.浏览器会在本地的目录中吧session的id写入到本地的cookie中。
4.在后续的请求中,都会先读取本地的cookie中的内容,并在请求的时候带上对应的cookie。  
复制代码

那么服务器端的session和客户端的cookie是如何进行存储的。

2 SSO单点登录

SSO单点登录产生的背景:

1.公司内部使用系统越来越多。
2.每个系统都是受保护的资源,要记住对应的账号和密码。很多员工会把每个系统的账号和密码设置成一样的。
3.假设用户如果同时要使用A系统和B系统,以及OA系统,用户需要登录三次。
4.如果不使用了,还需要在每个系统中注销登录。
复制代码

单点登录:

一次登录,到处访问。单点登录解决方案的核心是cookie ,cookie携带的会话id在浏览器与服务器之间维护会话状态。但是cookie是有限制的。
限制就是cookie的域(通常对应网站的域名),浏览器发送HTTP请求时会自动携带与该域匹配的cookie,而不是所以的cookie。
复制代码

2.3登录机制:

	我们假设浏览器第一次请求服务器需要输入用户名和密码来验证身份。服务器拿到用户名和密码去数据库进行对比,比较正确,说明用户合法,应该将这个会话标记为“已授权”或者“已登录”等等之类的状态。
	既然是会话状态,自然要保存在会话对象中,tomcat在会话对象中设置登录状态如下:
		HttpSession session = request.getSession();
		session.setAttribute("isLogin",true);
	用户再次访问的时候,tomcat在会话对象中查看登录状态:
		HttpSession session = request .getSession();
		session.getAttribute("isLogin");
	实现了登录状态在浏览器请求服务器模型如下图:
		![](https://java-markdown.oss-cn-shenzhen.aliyuncs.com/java_img/20200519142352.png)
复制代码

结论:

		每次请求受保护资源时候,都会检查会话对象中的登录状态,只有isLogin=true的会话才能访问,登录机制因此而实现。
复制代码

上面的图:

为什么不将web应用群众的所有的子系统的域名统一在一个顶级域名下,例如“*.baidu.com”,然后将他们的cookie域设置为“baidu.com",这种做法理论上是可以的,甚至早期很多系统登录就是采用这种同域名共享cookie的方式。
但是,可行不代表好。共享cookie的方式有很多局限。
首先,应用群域名得统一;
其次,应用群各系统使用的技术(只要web服务器)要相同,不然cookie的key值(tomcat为jsessionid)不同,无法维持会话。共享cookie的方式是无法实现跨语言技术平台登录的,比如java,PHP,.net系统之间;
第三个,cookie本身是不安全的。
因此,我们需要一种全新的登录方式来实现多系统应用群的登录,这就是单点登录。    
复制代码

3 系统中的cookie和session是怎么存储?

假设有AB两个系统,A:www.a.com B系统:www.b.com

这个两个系统都有自己一个区域来存储session的地方。可以理解map来存储session对象,

map的key存sessionid也就是jessionid。value存session对象。 在浏览器本地有三个目录来存储对应的域名的cookie,假设访问A系统,在浏览器本地a.com的目录找对应的cookie,

在请求的时候 ,把这个目录下的cookie请求也带到服务器(浏览器来搞,我们不用来搞)。

www.a.com服务器响应cookie的时候会写入到浏览器本地的a.com目录。

4 单点登录,session和cookie的情况怎样?

过程:

  1. 假设我们第一次访问www.a.com/index,首先会在浏览器本地的a.com目录中寻找对应的cookie,

    如果没有,证明目前浏览器和服务器之间还没有建立会话(部会话)。

    这时需要重定向到统一认证中心。查看全局会话(如果全局会话有,说明其他系统登录了),

    需要把请求访问的地址作为参数传递过去(为什么要传递过去?因还要回调这个地址)

  2. 浏览器会调用统一认证中心中的checklogin方法,看是否有全局会话,

    这时请求的是www.sso.com/checklogin地址,浏览器会在本地的sso.com目录找对的cookie信息,并在请求的时候也带到服务器。但是这一次请求,

    浏览器本地的目录sso.com目录也没有cookie的信息。

    意味着浏览器和统一认证中心没有建立会话。没有会话说明没有登录,需要转发到统一认证中心的登录页面。

    同时需要把地址栏中的redirectURL从地址中获取出来,并把这个参数放入到request域中(下面认证成功,还要跳回到之前的访问的地址)

    www.sso.comchecklongin?redirectURL=http://www.a.com/…

  3. 转发到统一认证中心的登录页面,用户在统一认证中心的登录页面输入账号密码。认证中心服务做一些事情就可以了:

    • 创建令牌后,间接授权给后面的子系统。
    • 创建全局会话后,把令牌存放在全局会话中。
    • 将令牌信息存放在我们的db中的token表中(后面子系统检验token的有效性要查询这个表)
    • 重定向回到之前的请求的地址redirectURL,把令牌发给该子系统:www.a.com?token=xxxx1;
  4. 统一认证中心会把session的id(jessionid)响应到客户端浏览器本地目录sso.com目录cookie文件中。

    以key/value的格式存储(注意:key是固定的jessiond,value是服务器sessionid的字符串)。

    后面还需要访问www.sso.com的时候就都会带上这个jessionid

分类:
阅读