做者 | 凌承一
php
連接 | cnblogs.com/ywlaker/p/6113927.htmlhtml


-
請求參數 -
cookie

HttpSession session = request.getSession();
session.setAttribute("isLogin", true);
用戶再次訪問時,tomcat在會話對象中查看登陸狀態java
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);
}
String logout = req.getParameter("logout");
if (logout != null) {
this.ssoServer.logout(token);
}
@RequestMapping("/logout")
public String logout(HttpServletRequest req) {
HttpSession session = req.getSession();
if (session != null) {
session.invalidate();//觸發LogoutListener
}
return "redirect:/";
}
sso認證中心有一個全局會話的監聽器,一旦全局會話註銷,將通知全部註冊系統註銷程序員
public class LogoutListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent event) {}
@Override
public void sessionDestroyed(HttpSessionEvent event) {
//經過httpClient向全部註冊系統發送註銷請求
}
}
點下面
給個在看唄
本文分享自微信公衆號 - 程序員匯聚地(chasays)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。web