10 张流程图+部署图,讲透单点登录原理与简单实现!
Java项目开发
共 7494字,需浏览 15分钟
·
2021-05-07 22:33
点击上方 java项目开发 ,选择 星标 公众号
重磅资讯,干货,第一时间送
- 单系统登录机制 -
请求参数; cookie。
HttpSession session = request.getSession();
session.setAttribute("isLogin", true);
用户再次访问时,tomcat在会话对象中查看登录状态。
HttpSession session = request.getSession();
session.getAttribute("isLogin");
- 多系统的复杂性 -
- 单点登录 -
用户访问系统1的受保护资源,系统1发现用户未登录,跳转至sso认证中心,并将自己的地址作为参数; sso认证中心发现用户未登录,将用户引导至登录页面; 用户输入用户名密码提交登录申请; sso认证中心校验用户信息,创建用户与sso认证中心之间的会话,称为全局会话,同时创建授权令牌; sso认证中心带着令牌跳转会最初的请求地址(系统1); 系统1拿到令牌,去sso认证中心校验令牌是否有效; sso认证中心校验令牌,返回有效,注册系统1; 系统1使用该令牌创建与用户的会话,称为局部会话,返回受保护资源; 用户访问系统2的受保护资源; 系统2发现用户未登录,跳转至sso认证中心,并将自己的地址作为参数; sso认证中心发现用户已登录,跳转回系统2的地址,并附上令牌; 系统2拿到令牌,去sso认证中心校验令牌是否有效; sso认证中心校验令牌,返回有效,注册系统2; 系统2使用该令牌创建与用户的局部会话,返回受保护资源。
局部会话存在,全局会话一定存在; 全局会话存在,局部会话不一定存在; 全局会话销毁,局部会话必须销毁。
用户向系统1发起注销请求; 系统1根据用户与系统1建立的会话id拿到令牌,向sso认证中心发起注销请求; sso认证中心校验令牌有效,销毁全局会话,同时取出所有用此令牌注册的系统地址; sso认证中心向所有注册系统发起注销请求; 各注册系统接收sso认证中心的注销请求,销毁局部会话; sso认证中心引导用户至登录页面。
- 部署图 -
- 实现 -
拦截子系统未登录用户请求,跳转至sso认证中心; 接收并存储sso认证中心发送的令牌; 与sso-server通信,校验令牌的有效性; 建立局部会话; 拦截用户注销请求,向sso认证中心发送注销请求; 接收sso认证中心发出的注销请求,销毁局部会话。
验证用户的登录信息; 创建全局会话; 创建授权令牌; 与sso-client通信发送令牌; 校验sso-client令牌有效性; 系统注册; 接收sso-client注销请求,注销所有会话。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
HttpSession session = req.getSession();
if (session.getAttribute("isLogin")) {
chain.doFilter(request, response);
return;
}
//跳转至sso认证中心
res.sendRedirect("sso-server-url-with-system-url");
}
@RequestMapping("/login")
public String login(String username, String password, HttpServletRequest req) {
this.checkLoginInfo(username, password);
req.getSession().setAttribute("isLogin", true);
return "success";
}
String token = UUID.randomUUID().toString();
// 请求附带token参数
String token = req.getParameter("token");
if (token != null) {
// 去sso认证中心校验token
boolean verifyResult = this.verify("sso-server-verify-url", token);
if (!verifyResult) {
res.sendRedirect("sso-server-url");
return;
}
chain.doFilter(request, response);
}
HttpPost httpPost = new HttpPost("sso-server-verify-url-with-token");
HttpResponse httpResponse = httpClient.execute(httpPost);
if (verifyResult) {
session.setAttribute("isLogin", true);
}
if (verifyResult) {
session.setAttribute("isLogin", true);
}
@RequestMapping("/logout")
public String logout(HttpServletRequest req) {
HttpSession session = req.getSession();
if (session != null) {
session.invalidate();//触发LogoutListener
}
return "redirect:/";
}
public class LogoutListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent event) {}
@Override
public void sessionDestroyed(HttpSessionEvent event) {
//通过httpClient向所有注册系统发送注销请求
}
}
作者:凌承一
原文:www.cnblogs.com/ywlaker/p/6113927.html
推荐阅读:
怎么接私货?这个渠道你100%有用!请收藏!喜欢文章,点个在看
评论