cas中重要的三个关键词:
- TGT: 缓存在cas server用户登录标识的票据(可以存放在mongodb,mysql等数据存储介质中,默认是放在本地内存中)
- TGC:缓存在浏览器cookie中用户登录标识票据,在同一个用户下,可以用TGC去cas server中查找对应的TGT,获取ST
- ST:就是ticket,访问资源服务器的票据,即一张通行证
现在有两台资源服务器,一台资源服务器9003,一台资源服务器9004,现在想要实现资源服务9003和资源服务器9004实现单点登录
第一次登录资源服务器9003流程:
由资源服务器9003跳转至资源服务器9004流程:
看其中能不能实现SSO,最重要的就是浏览器缓存的TGC
这个cookie是在 cas server(192.168.2.6)IP下,第一次用户登录成功就会setCookie到浏览器中,第一次单点登录到其他资源服务器会拿他去获取ticket,而且用TGC去拿ST这个请求一定要是https请求,否则会报SSL相关错误,这也是为了数据传输安全考虑,如果别人窃取到了你的TGC,就可以获取到ST,从而创建会话
ST(ticket)刚获取的时候也是缓存在客户端的cookie中,默认失效时间为10s,只能使用一次,使用的时候就会把cookie中的ST给删除了,这个跟oauth2的授权码code一样,只能使用一次,而且都是作为用户身份认证成功的标志
cas用户身份认证就是经典的cookie-session模式,有状态的安全认证,如果把浏览器cookie清除,就需要重新进行登录,这块跟ouath2 token,JWT无状态认证的有明显的区别
安全性
1、sessionId
public void test8(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println(request.getSession().getMaxInactiveInterval());//1800
}
服务器默认的是: 1800s,30分钟
如果我知道了cookie中保存的sessionId,我可以访问资源,因为资源服务器端已经缓存了当前会话的用户信息
@ResponseBody
@RequestMapping("/getUserInfo")
public String test(Principal principal) {
return "当前登录用户名是:" + principal.getName();
}
所以后端服务器的session过期时间应合理的设置
还有就是浏览器对cookie的清除策略要设置好,如下expires为session的时候,当空闲时间还没到30分钟,谷歌浏览器默认情况下就算关掉窗口,都清除不了cookie
2、TGC
后端服务器session失效了,用户信息同时也被清除了,可以通过浏览器中的TGC,去获取ticket,会再次创建session,保存用户信息,则TGC被窃取存在很大的风险
这个也取决于浏览器的cookie的过期策略
cas-server端的TGT,过期时间为2个小时,只要两个小时内,获取到cookie中的TGC,就可以获取ticket,从而创建会话
https主要是对数据传输过程中数据的加密和防篡改,实现安全的传输,并不能防止别人在浏览器上获取cookie信息,所以应该使用完,最好退出登录,退出登录能让cas-server TGT和资源服务器的session失效
shiro+cas
cas由于只能做身份认证,不能做授权,一般项目中都会根据用户的角色,匹配相应的权限,如果有权限,则访问资源,如果没有资源的权限,则拒绝访问,这块跟oauth2有明显的区别,oauth2授权码模式集身份认证,客户端认证,授权于一身,称为最安全的模式
shiro是现在项目中使用较多的用于身份认证和授权的安全框架,也是基于cookie-session模式,但是本身不能实现SSO(当然自己可以自定义实现,如:借助JWT可以实现无状态的SSO,需要实现统一的登录登出,JWT的登出实现比较麻烦,还要考虑用户会话集中式管理等等),cas本质就是SSO框架,所以集两者的优点,shiro+cas就是一个集身份认证SSO+授权于一体了
微服务中大致请求流程:
gateway:统一身份认证和授权,缓存缓存着用户的信息,如果有多台gateway,需要使用spring-session保证两个gateway的sessionid是一致的
mysql:存储着用户权限信息
redis:主要是作为共享TGT的作用,cas支持很多种存储方式,如:
如果不使用redis缓存做共享TGT,则可以使用nginx的ip hash转发方式