目标
这一章节我们来一起学习,单点退出登录,是怎么让所有sso系统一起退出登录的。 视频详细讲解请见https://www.bilibili.com/video/BV14A4y1S7HP/ 源码下载地址:https://gitcode.net/kiduo08/yuantai-sso.git
时序图
- 当用户点击某一个系统的退出登录时候
- 统一的发起跳转到认证中心http://authentication.sso.com:8080/logout?redirectUri=http://client.sso.com:8082
- 认证中心接受登出请求,注销认证中心登录凭证并清除cookie中的凭证信息。
- 携带特定登出参数,向各已登录的应用系统(已获取accessToken)且未过期的应用系统发送http请求,请求注销本地session.
- 各应用系统应答处理登出请求。
- 认证中心接受各应用系统应答后、跳转回发起登出请求的系统
http://client.sso.com:8082/ - 应用系统(
例如:OA系统 )发现本地session已清除或者失效,认证失败发起302重定向 - 浏览器
(这里重点是浏览器重定向) 发起重定向请求http://authentication.sso.com:8080/login?appId=demo1&redirectUri=http://client.sso.com:8082/ - 认证中心接受请求判断未登录,返回展示SSO统一登录页面
代码
a. com.yuantai.controller.LogoutController 的logout 方法
@RequestMapping(method = RequestMethod.GET)
public String logout(
@RequestParam(value = SsoConstant.REDIRECT_URI, required = true) String redirectUri,
HttpServletRequest request, HttpServletResponse response) {
sessionManager.invalidate(request, response);
return "redirect:" + redirectUri;
}
调用sessionManager.invalidate(request, response); 方法
public void invalidate(HttpServletRequest request, HttpServletResponse response) {
String tgt = getCookieTgt(request);
if (StringUtils.isEmpty(tgt)) {
return;
}
// 删除登录凭证
ticketGrantingTicketManager.remove(tgt);
// 删除凭证Cookie
CookieUtils.removeCookie(AppConstant.TGC, "/", response);
// 删除所有tgt对应的调用凭证,并通知客户端登出注销本地session
accessTokenManager.remove(tgt);
}
b.认证中心删除认证嘻嘻
// 删除登录凭证
ticketGrantingTicketManager.remove(tgt);
// 删除凭证Cookie
CookieUtils.removeCookie(AppConstant.TGC, "/", response);
c.接着调用accessTokenManager.remove(tgt);
@Override
public void remove(String tgt) {
Set<String> accessTokenSet = tgtMap.remove(tgt);
if (CollectionUtils.isEmpty(accessTokenSet)) {
return;
}
accessTokenSet.forEach(accessToken -> {
DummyAccessToken dummyAt = accessTokenMap.get(accessToken);
if (dummyAt == null || System.currentTimeMillis() > dummyAt.expired) {
return;
}
CodeContent codeContent = dummyAt.accessTokenContent.getCodeContent();
if (codeContent == null || !codeContent.isSendLogoutRequest()) {
return;
}
logger.debug("发起客户端登出请求, accessToken:{}, url:{}", accessToken, codeContent.getRedirectUri());
sendLogoutRequest(codeContent.getRedirectUri(), accessToken);
});
}
这里循环调用获取accessToken时候存下来的应用系统信息。 d.最后发起重定向,走第一次打开系统页面的流程。
总结
SSO单点系统登录的原理,及其重要,系统小伙伴一定要认真的看我的视频,了解原理。 今天发生了一件事情想想赶紧把sso单点登录搞完 ,啥事情呢?BPM系统开发小伙伴调用别人提供的接口,验证接口不通一直403(一天多没有搞定 ),但是postman可以调用,领导让我把把脉,我看了接口文档(SAP开发CPI的人提供的接口信息),自己写了接口调用排查了一下确实403,然后postman试了试可以通(这说明什么postman自动记录了一些信息,那就只能是cookie里的session信息),果然发现接口网关需要cookie里的JESSIONID信息(他们一直传了登录Basic auth认证返回的token )、我告诉了他们这个类似SSO单点登录通过session认证信息(就是目前我讲的手撸SSO单点登录基于httpSession)可能是他们(SAP)类似网关需要session信息,cpi提供的接口系统只需要token验证信息。然后他们一会搞定,我瞬间在领导的心目中又提升了地位。哈哈哈!!!! 原理!原理!原理!这样在遇到问题时能够迅速的排除问题。大家慢慢积累吧又肝到了很晚
|