单点登录设计解决了以前存在的问题:
1.CAS服务器独立部署,业务系统的单点登录程序在业务系统内,Ecloud系统的单点登录程序与权限系统分开,从而实现解耦;
2.系统注册时,对密码进行md5加密,可以用不同算法多次加密,防止破解;
3.用户登录时在CAS服务器增加在线用户数,当超过设定的预警值时拒绝登录,当低于这个值时可以登录;
4.用户登陆后,ticket 需要采用Md5加密传输;
5.java和.net产品单点登录的设计和集成规范,通过统一的uri进行访问。
6.单点登录系统的高并发访问问题,用户30分钟未操作系统,则用户登出。基于此需求,解决方式是,用户每次访问系统资源,均向服务器发出请求,表明用户正在使用系统并验证。其实这是不必要的,由于此种设计,导致各子系统频繁与单点登录系统进行通信。
解决办法:通过设置失效时间(半小时),用户如果半小时没有访问则自动退出。不需要每次都去访问服务器,从而提高速度。每5分钟在缓存记录一次用户操作的时间,设置失效时间。如果超时,则重新登录。
Cas原理图:
St验证图:
现在单点登录使用了1个listener和4个过滤器,性能低,需要大力度简化,提高系统效率和性能。根据对cas单点登录原理的分析,验证过程调用太多,影响性能,而这是可以简化的,完全不需要,应用系统登录后用权限进行控制来保证安全,不需要st验证,因此可以简化登录过程,保留单点登录过滤器,登录成功后把userid和注销uri保存到缓存,取消st验证过滤器,注销由应用系统完成,这样3个过滤器就可以解决问题,AuthenticationFilter完成登录,CasReceivingTicketValidationFilter获取userid、注销的uri存入缓存by ticket,CasSetUserStatusFilter判断超时和根据用户数判断是否可用登录,其中前2个过滤器只需要过滤一次,另一个判断也很简单。新的设计简单高效,极大地提高产品的性能。
单点登录的关键在于userid的获取,第一次登录后可以得到userid,然后存入redis,以后从缓存获取userid和useName 便by ticket。再根据userid获得权限,存入应用系统session,这样应用系统就可以正常工作。
注销由用户系统的logout完成,把中心用户数-1,并调用其他应用系统的logout。
只需要对应用系统的主页index进行过滤,其他请求不需要过滤,这样就大大减少了对过滤器的调用,可以提高数倍的访问速度,有效提升应用系统的性能。如果要对所有uri过滤也行,因为只有一个过滤器请求,效率也会提升许多。
使用3个filter独立完成sso,具有非侵入性,便于第三方产品的集成,可以不修改代码,放入这3个过滤器即可使用sso。
单点登录的过程是这样的:业务系统需要通过index进入,并开发AuthenticationFilter程序,完成单点登录功能,当用户有index请求时,判断用户是否登录,如果用户没有登录,则从数据库读取cas的登录uri:http://10.1.134.31:9080/cas/login,
cas服务器完成登录后返回到用户请求的地址。cas登录地址uri如下:
http://10.1.134.31:9080/cas/login?service=http://10.1.134.38:7080/index;jsessionid=710CCF84C6B52424C0B9AC74063B03AC。
使用jsessionid可以防止用户关闭cookie时,一样能访问到服务器的session,可以根据cookieEnabled判断,需要时才加。
cas服务器弹出登录页面,用户输入用户名和密码后校验,如果登录成功,则返回userid存入缓存,把ticket存入用户的cookie,然后AuthenticationFilter过滤器通过缓存获取userid,把用户请求的logout的uri根据ticket保存到缓存,用户注销请求的uri地址为http://10.1.42.14:8080/platform-power/logout,然后根据userid获取用户权限,把userid和权限存入session。redis缓存采用list, list第一个放userid,后面放注销uri。
如果用户已经登录,则CasReceivingTicketValidationFilter从cookie获取ticket,再从缓存读取userid by ticket,然后根据userid获取用户权限,把userid和权限存入session,再更新cas服务器的失效时间。
用户操作都经过CasSetUserStatusFilter,判断是否超时,如果超时且没有超过最大在线用户数,则采用index的uri登录。
用户注销时,需要同步注销用户在使用的其他产品,为此需要业务产品提供标准的注销方式,这样便于注销其他业务系统。用户注销时,需要从注销的系统的session中删除用户、权限数据、从cookie中删除ticket,以及删除缓存的数据,还需要调用cas服务器注销用户登录的其他产品,让Cas服务器减少一个在线用户数,从而完成多个产品的注销,然后跳转登录页面。
· .NET系统使用和java是一样的,需要修改现在的filter程序AuthorizationAttribute。这是业务系统单点登录的标准规范,大家统一按照这个方法实现单点登录。由于跨域的cookie不同,所以需要采用跨域重定向和跨域设置Cookie完成跨域免登。
1.单点登录
CAS服务器提供SSO功能,各业务系统通过Filter访问CAS,登录成功后获取ticket,并把ticket放入COOKIE,以后用户凭这个ticket登录其他系统。要考虑内外网部署项目的情况,提供对内外网 访问的区别和支持。
单点登录会话维护要求:
A、单点登录会话的有效时长建议设置为半小时,时间设置过长登录服务会产生大量的无用会话信息,时间设置过短调用用户查询服务的频率增加,增加网络压力。
B、用户每登录到另一个网站,更新单点登录会话有效期,使得单点登录会话的有效时长为半小时(可配置)。
C、单点登录会话的时长要求各登录服务模块在建设的过程中考虑支持可配置。
3、单点登录会话销毁
A、当用户主动退出时,登录服务器应注销单点登录会话,并通知所有登录过的网站做登出处理。如果单点登录会话超时后,用户再次要求单点登录时,登录服务器应提示用户重新登录。
B、单点登录会话因为用户长时间不操作而过期,认证中心系统检测单点登录会话过期,认证中心要销毁用户单点登录会话。
C、用户关闭浏览器或者浏览器崩溃导致用户的单点登录会话没有销毁,用户再次登录,允许用户登录,为用户重新创建会话。
D、当用户需要在两台不同的终端进行登录操作,允许用户登录,并为用户建立两个不同的会话。
2.登录注销
用户注销时,需要同步注销用户在使用的其他产品,为此需要业务产品提供标准的注销方式,其注销uri是把登录的uri加上logout,这样便于主动注销业务系统。用户注销时,需要从注销的系统的session中删除用户、权限数据、从cookie中删除ticket,还需要从缓存取出所有其他应用系统的userid、注销uri,去调用用户登录的其他产品的logout功能,减少一个在线用户数,从而完成多个产品的注销,然后跳转登录页面。
这样logoutController就有2种调用方式,一个是主动退出,一个是被动退出,主动退出需要调用其他应用系统的logout退出其他产品,而被动退出不需要,需要进行区别,为此需要加入localOut变量进行区别。
用户从页面退出时,其uri如下:
http://10.1.134.38:8080/xueji/logout/?localOut=1
在logoutController中,判断localOut是否为1,如果是,则表明是从页面退出的,完成清除操作。然后应用系统的注销程序在缓存根据userid找到用户登录的其他产品之注销uri,然后调用其他产品退出的uri如下:
http://10.1.134.35:8080/deansCourse/logout
uri中没有localOut参数,其他产品的logout退出时就不会再调用其他的logout。这样就可以区别开是自己主动退出还是被动退出,从而防止多次调用logout。