一、单点登录问题
由于Http请求是无状态的请求,服务器无法确认登录信息。当用户登录时,将用户信息存储到Session中,Session将认证的用户信息以Cookie方式返回给客户端。每次用户请求不同的业务系统,都会携带Cookie去请求。保证了不同系统之间访问时,不需要用户重新认证。
如下图所示:当客户端登录商品系统时(①②),Session会记录用户登录的信息并返回给Cookie。当用户发起支付时(③),支付系统会请求Session进行认证(④),Session认证成功后返回认证信息给支付系统(⑤),支付系统完成支付并返回支付信息给商品系统(⑥),从而完成整个购买支付流程。
- 但不同的服务器,session无法共享,导致商品系统和支付系统无法通信!!!
- cookie无法跨域,存放在商品系统【http://goods.com】下的cookie认证信息无法在请求支付系统【http://pay.com】中使用(域名不同)!!!
二、Session共享的解决方案
- Tomcat集群Session全局复制(集群内每个tomcat的session完全同步)【会影响集群的性能,不建议】。
- 根据请求的IP进行Hash映射到对应的机器上(这就相当于请求的IP一直会访问同一个服务器)【如果服务器宕机了,会丢失了一大部分Session的数据,不建议】
- 把Session数据放在Redis中(使用Redis模拟Session)【建议】
- 独立出来一个认证子系统,将所有的认证信息存放到认证子系统中。
三、cookie跨域问题的解决方案
- 服务端将Cookie写到客户端后,客户端对Cookie进行解析,将Token解析出来,此后请求都把这个Token带上。
- 多个域名共享Cookie,在写到客户端的时候设置Cookie的domain。
- 将Token保存在SessionStroage中(不依赖Cookie就没有跨域的问题了)
四、单点登录认证系统实现
下面对上图简要描述
(1)用户访问系统1的受保护资源,系统1发现用户未登录,跳转至sso认证中心,并将自己的地址作为参数;
(2)sso认证中心发现用户未登录,将用户引导至登录页面;
(3)用户输入用户名密码提交登录申请;
(4)sso认证中心校验用户信息,创建用户与sso认证中心之间的会话,称为全局会话,同时创建授权令牌;
(5)sso认证中心带着令牌跳转会最初的请求地址(系统1);
(6)系统1拿到令牌,去sso认证中心校验令牌是否有效;
(7)sso认证中心校验令牌,返回有效,注册系统1;
(8)系统1使用该令牌创建与用户的会话,称为局部会话,返回受保护资源;
(9)用户访问系统2的受保护资源;
(10)系统2发现用户未登录,跳转至sso认证中心,并将自己的地址作为参数;
(11)sso认证中心发现用户已登录,跳转回系统2的地址,并附上令牌;
(12)系统2拿到令牌,去sso认证中心校验令牌是否有效;
(13)sso认证中心校验令牌,返回有效,注册系统2;
(14)系统2使用该令牌创建与用户的局部会话,返回受保护资源。