- 本文是尚硅谷-雷丰阳-谷粒商城学习笔记-
- 单点登录-主要步骤
服务器: 第一系统; 第二系统; 认证服务器
关键点:认证服务器在认证域名下存储cookie;起到各个系统中转作用
- 浏览器访问第一系统发送请求到客户端服务器-判断是否登录-没有登录-携带源系统url重定向到认证服务器-显示登录页面
- 输入登录用户名密码-点击登录成功-跳转到源系统-同时记录token到redis中在认证服务器域名下保存一份token到cookie中(以便其他系统再次登录可以免登录)
- 认证服务域名下已存在登录过的cookie,浏览器以后访问这个域名都会带上这个cookie。
- 浏览器访问第二系统后台验证未登录-浏览器重定向携带第二系统url重定向(同时会带上cookie)到认证服务器-进入跳转登录页面的方法会判断cookie是否存在token,如果存在表示之前登录过,直接返回第二系统并且携带上token;
- 第二系统接收到token,查询用户信息保存session中将用户设置为登录状态。
登录页面:
<form th:action="@{/doLogin}" method="post">
用户名: <input type="text" name="username" th:value="${username}"/> <br/>
密码: <input type="password" name="password"/> <br/>
<input type="hidden" name="url" th:value="${url}">
<input type="submit" value="登录"/>
</form>
认证服务器-登录控制器
@Controller
public class LoginController {
@RequestMapping("/login.html")
public String loginPage(@RequestParam(value = "redirect_url",required = false) String redirectUrl,
Model model,
@CookieValue(value = "atguigusso",required = false) String sso){
//判断之前是否已经有其他系统登录过给浏览器留下cookie了;
if(StringUtils.isEmpty(sso)){
//没有人登录过
if(!StringUtils.isEmpty(redirectUrl)){
//登陆页面上记录-返回系统的url地址
model.addAttribute("url",redirectUrl);
}
return "login";
}else {
//之前有人登录过了,调回自己哪里,我会额外给你加参数
return "redirect:"+redirectUrl+"?atguigusso="+sso;
}
}
@PostMapping("/doLogin")
public String doLogin(String username,
String password,
String url, Model model,
HttpServletResponse response){
System.out.println("提交的数据。"+username+"==>"+password+"==>"+url);
//登录
if(!StringUtils.isEmpty(username)&&!StringUtils.isEmpty(password)){
//登录成功....
//保存到了redis; key=username;UUID
// jwt;
//1、支持本地验证;
//2、jwt自带负载信息;
String token = UUID.randomUUID().toString().substring(0, 5);
/**
* JWT的负载信息
*/
Map<String,Object> loginUser = new HashMap<>();
loginUser.put("name",username);
loginUser.put("email",username+"@qq.com");
loginUser.put("token",token);
/**
* 做成一个jwt
*/
DefaultClaims claims = new DefaultClaims();
// claims.setIssuer("ssoserver.com");
String jwt = GuliJwtUtils.buildJwt(loginUser, claims);
//将登陆信息token存储在(认证服务器域名下的)cooke中,第二个客户端登陆的时候的就知道已经登陆了
//我们如果能获取到atguigusso的值,就能去redis中查到这个用户
Cookie cookie = new Cookie("atguigusso", jwt);
//ssoserver.com
response.addCookie(cookie);
return "redirect:"+url+"?atguigusso="+jwt;
}
model.addAttribute("username",username);
model.addAttribute("password",password);
model.addAttribute("url",url);
//登录失败,再次来到login.html
return "forward:/login.html";
}
}
第一系统;第二系统
@Controller
public class ClientController {
@Value("http://ssoserver.com:11000/login.html")
String ssoServer;
@GetMapping("/say")
public String hello(){
return "hello";
}
@GetMapping("/see")
public String meinv(@CookieValue(value = "atguigusso",required = false) String ssocookie,
@RequestParam(value = "atguigusso",required = false) String ssoparam,
HttpServletRequest request,
HttpServletResponse response){
StringBuffer url = request.getRequestURL();
try {
if(!StringUtils.isEmpty(ssoparam)){
//有参数,验参数
GuliJwtUtils.checkJwt(ssoparam);
response.addCookie(new Cookie("atguigusso",ssoparam));
return "meinv";
}
if(!StringUtils.isEmpty(ssocookie)){
GuliJwtUtils.checkJwt(ssocookie);
return "meinv";
}
throw new NullPointerException();
}catch (NullPointerException e){
return "redirect:"+ssoServer+"?redirect_url="+url.toString();
}catch (Exception e){
//验证失败
System.out.println("令牌校验非法....");
request.setAttribute("url",ssoServer+"?redirect_url="+url.toString());
return "error";
}
}
}