假设现在有两个域名,分别为:(分别记为client1、client2)
client1.com
client2.com
一个认证服务器,域名:
ssoserver.com
client1、client2都需要登陆后才能访问到数据,现在想要实现client1登录了,再去访问client2不需要登录
简单实现:
- 在
C:\Windows\System32\drivers\etc\HOSTS
中配置需要用的三个域名:127.0.0.1 ssoserver.com
127.0.0.1 client1.com
127.0.0.1 client2.com
- 现在设老师、学生需要登录后才能访问到具体数据:
老师:
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@Controller
public class Client1Controller {
@GetMapping("/teacher")
public String getData(HttpServletRequest request, @RequestParam(required = false) String token, HttpSession session, Model model) {
if (token != null) {
//说明刚刚登录,获取到了token
session.setAttribute("admin", token);
}
Object admin = session.getAttribute("admin");
if (admin != null) {
//说明登陆过了
String teacher = request.getServerName() + " -> 老师的数据xxx";
model.addAttribute("msg", teacher);
return "teacher";
}
//未登录,去登陆
return "redirect:http://ssoserver.com:8080/login?redirect_url=http://client1.com:8080/teacher";
}
}
学生:
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@Controller
public class Client2Controller {
@GetMapping("/student")
public String getData(HttpServletRequest request, HttpSession session, Model model, @RequestParam(required = false) String token) {
if (token != null) {
session.setAttribute("admin", token);
}
Object admin = session.getAttribute("admin");
if (admin != null) {
String student = request.getServerName() + " -> 学生的数据xxx";
model.addAttribute("msg", student);
return "student";
}
return "redirect:http://ssoserver.com:8080/login?redirect_url=http://client2.com:8080/student";
}
}
实现的比较简单:
- 首先判断是否有token,如果有,说明是从认证服务器跳转过来的,那么把数据存到session,之后当前域名再访问就不用去认证了;
- 再判断session,如果session中有数据,说明已经登录;
- 最后如果都没数据,去认证服务器认证,这里需要注意要带上跳转回来的url,否则认证完不知道去哪了。
3.认证服务器
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
/**
* @program: gulimall
* @description:
* @author: liangjiayy
* @create: 2022-06-17 21:59
**/
@Controller
@Slf4j
public class SSOServerController {
/**
* 登录逻辑
*/
@PostMapping ("/login")
public String login(String username,
String password,
String url,
HttpServletResponse response) {
log.info("用户名:{},密码:{},登陆成功,带token跳转回原网页!",username,password);
Cookie cookie=new Cookie("sso_token",username);
response.addCookie(cookie);
return "redirect:" + url + "?token=" + username;
}
@GetMapping ("/login")
public String login(@RequestParam(value = "redirect_url",required = false) String url,
Model model,
@CookieValue(value = "sso_token",required = false) String token){
if (!StringUtils.isEmpty(token)) {
//说明最近登录过,直接返回
return "redirect:" + url + "?token=" + token;
}
if (!StringUtils.isEmpty(url)) {
model.addAttribute("url",url);
}
return "login";
}
}
本文单点登录的核心在:
Cookie cookie=new Cookie("sso_token",username);
response.addCookie(cookie);
即如果登录了,则把登录的信息(用户名)存到cookie中,当用户再次访问当前服务器,回首先看cookie中有没有登录的用户信息,如果有,则不需要再登录,就实现了单点登录。
- 效果图:
附html页面:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/login" method="post">
用户名:<input name="username">
密 码:<input name="password">
<input name="url" hidden th:value="${url}">
<input type="submit" value="登录">
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>student</title>
</head>
<body>
你好,<div th:text="${session.admin}"></div>
获取到学生的数据:<br>
<div th:text="${msg}"></div>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>teacher</title>
</head>
<body>
你好,<div th:text="${session.admin}"></div>
获取到老师的数据:<br>
<div th:text="${msg}"></div>
</body>
</html>