项目需要实现仿单点登录,即用户在系统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