項目需要實現仿單點登錄,即用戶在系統A登錄後,當切換到系統B時,會攜帶一個token。系統B需要去驗證token的有效性,當token有效,則相當於用戶在系統B已登錄,session各自系統管理。
實現的前提:
由於兩個系統的數據庫不同,那麼需要系統A的用戶和系統B的用戶需要有一定的關聯,比如使用用戶名來關聯,用戶名一樣則表示同個用戶。這樣,當用戶在系統A登錄後,跳轉到系統B,系統B才知道要登錄哪個用戶。
代碼登錄:
@RequestMapping(value = "/sso/login", produces = "application/json")
public Object sso(@RequestParam String token, HttpServletRequest request, HttpServletResponse response){
// 1、驗證token
Object resp = remoteService.verifyToken(token);
UserVO userVO = (UserVO)resp;
String username = userVO.getName();
// String username = "admin";//test
// 2、手動設置認證信息(其實正常的認證流程最終也是設置這些信息,在此處我們只需要驗證token,所以繞過認證)
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
authenticationToken.setDetails(new WebAuthenticationDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
// 3、可選的,防止csrf攻擊
CsrfToken csrfToken = csrfTokenRepository.generateToken(request);
csrfTokenRepository.saveToken(csrfToken, request, response);
return RespMessage.ok("登錄成功!", csrfToken);
}
reference:
代碼登錄spring security並且獲取jsessionId