单点登录
核心
- 登录成功,登录服务器生成token和对应用户信息以KV形式保存在reids中,并且留下登陆过的标记(Cookie:可以用token充当这个cookie)
- 后续还有其他客户服务器要判定登录时来到登录服务器,发现还有登录过的标记(这个Cookie就是token)就将这个token返回给对应客户服务器
- 然后这个客户服务器携带这个token来登录服务器(或redis中)查询对应信息
- 如果查询的出来,说明登录过,将用户信息保留在客户服务器session中,通过认证
- 如果查询不出来,说明验证未通过,继续重定向到登录服务器去登录
登录服务器核心代码
@Controller
public class SSOServerController {
@Autowired
StringRedisTemplate stringRedisTemplate;
/**
* 客户服务器使用token来登录服务器查询对应信息请求
*
* @param token
* @return
*/
@ResponseBody
@GetMapping("/userInfo")
public String userInfo(@RequestParam("token") String token) {
//3.然后这个客户服务器携带这个token来登录服务器查询对应信息
return stringRedisTemplate.opsForValue().get(token);
}
@GetMapping("/login.html")
public String loginPage(@RequestParam("redirect_url") String url
, Model model
, @CookieValue(value = "ssoToken", required = false) String ssoToken) {
//2.后续还有其他客户服务器要判定登录时来到登录服务器,发现还有登录过的标记(这个Cookie就是token)就将这个token返回给对应客户服务器
if (!StringUtils.isEmpty(ssoToken)) {
return "redirect:" + url + "?token=" + ssoToken;
}
model.addAttribute("url", url);
return "login";
}
@PostMapping("/SSOLogin")
public String login(@RequestParam("username") String username
, @RequestParam("password") String password
, @RequestParam("url") String url
, HttpServletResponse response) {
//1.登录成功,登录服务器生成token和对应用户信息以KV形式保存在reids中,并且留下登陆过的标记(Cookie:可以用token充当这个cookie)
if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)) {
//生成token 保存在redis
String token = UUID.randomUUID().toString();
stringRedisTemplate.opsForValue().set(token, username + password, 30L, TimeUnit.MINUTES);
//生成cookie留下印记
//如果再次来到登录页还有这个cookie说明已经登录过
Cookie cookie = new Cookie("ssoToken", token);
response.addCookie(cookie);
return "redirect:" + url + "?token=" + token;
}
return "redirect:http://sso.com:8080/login.html";
}
}
客户服务器核心代码
@Controller
public class SSOClientController {
@Value("${sso.server.url}")
private String SSOServer;
@ResponseBody
@GetMapping("/hello")
public String hello() {
return "hello";
}
@GetMapping("/list")
public String list(HttpSession session, Model model, @RequestParam(value = "token", required = false) String token) {
//token不为空说明 登录过,再去登录服务器查询对应token信息并验证,成功则将信息保存在当前服务器的session中,否则重定向到登录服务器
if (token != null) {
//3.然后这个客户服务器携带这个token来登录服务器查询对应信息
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> forEntity = restTemplate.getForEntity("http://sso.com:8080/userInfo?token=" + token, String.class);
String loginUser = forEntity.getBody();
//如果没查到对应信息,说明token不正确
if (!StringUtils.isEmpty(loginUser)){
session.setAttribute("loginUser", loginUser);
}
}
//
if (session.getAttribute("loginUser") == null) {
return "redirect:" + SSOServer + "?redirect_url=http://client1.com:8081/list";
} else {
List<String> list = Arrays.asList("芜湖", "起飞", "这波", "不亏");
model.addAttribute("list", list);
return "list";
}
}
}
1万+

被折叠的 条评论
为什么被折叠?



