一.单点登录:
1)什么是 SSO:
a:单点登录效果:一处登陆,处处使用:
2)前置知识:
3)同域下的 单点登录:
a:多系统,案例图式:
4)不同域下的 单点登录:
5)单点登录框架 & 原理演示:
a:单点登录 Demo:
d:测试:
6)使用 JWT:
a:
b:
c:
d:
一.单点登录:
1)环境准备:
a:创建 单点登录 认证服务器:
b:创建 单点登录客户端:(2 个 / 8081 / 8082)
c:
d:
2)客户端 接口准备:client (8081、8082)
a:pom:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
b:yml:
server:
port: 8081
sso:
server:
url: http://ssoServer.com:8080/loginHtml
spring:
redis:
host: 114.215.173.88
port: 6379
password: 123456
c:controller:(访问:http://localhost:8081/employee)
@Controller
public class HelloController {
@Value("${sso.server.url}")
private String ssoServerUrl;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@ResponseBody
@RequestMapping(value = "/hello")
public String hello() {
return "hello";
}
@RequestMapping(value = "/employee")
public String employee(Model model,
HttpSession session,
@RequestParam(value = "token", required = false) String token) {
if (!StringUtils.isEmpty(token)) {
//去 ssoServer 登陆成功 跳回来,就会带上 token
//TODO 1.去 ssoServer 获取当前 token 真正对应的 用户信息
String s = stringRedisTemplate.opsForValue().get(token);
session.setAttribute("loginUser", s);
}
Object loginUser = session.getAttribute("loginUser");
if (loginUser == null) {
//未登录,跳转到 登陆服务器
//跳转过去以后,使用 url 上的 查询参数标识,告诉 服务端是哪个页面跳转过来的;
return "redirect:" + ssoServerUrl
+ "?redirect_url=http://client1.com:8081/employee";
} else {
//去 登陆成功,用户信息 放入 Session 中
// String s = stringRedisTemplate.opsForValue().get(token);
// session.setAttribute("loginUser", s);
//登陆成功,直接返回页面
ArrayList<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
model.addAttribute("emps", list);
return "employee";
}
}
}
d:跳转的 html:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>员工列表页面 1</title>
</head>
<body>
<h1>欢迎:[]</h1>
<ul>
<li th:each="emp:${emps}"> 姓名:[[${emp}]]</li>
</ul>
</body>
</html>
3)服务端接口准备:server
a:pom:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
b:yml:
server:
port: 8080
spring:
redis:
host: 114.215.173.88
port: 6379
password: 123456
c:Controller:
@Controller
public class LoginController {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@RequestMapping(value = "/loginHtml")
public String loginHtml(@RequestParam(value = "redirect_url") String redirect_url,
Model model,
@CookieValue(value = "sso_token", required = false) String sso_token) {
if (!StringUtils.isEmpty(sso_token)) {
//说明之前登陆,留下了痕迹
//sso_token 就是之前留下的痕迹,
return "redirect:" + redirect_url + "?token=" + sso_token;
}
System.out.println("redirect_url" + redirect_url);
model.addAttribute("redirect_url", redirect_url);
//跳转到 登陆页面
return "login";
}
@RequestMapping(value = "/goLogin", method = RequestMethod.POST)
public String goLogin(@RequestParam(value = "username111") String username,
@RequestParam(value = "password111") String password,
@RequestParam(value = "redirect_url") String redirect_url,
HttpServletResponse response) {
System.out.println(username);
System.out.println(password);
System.out.println(redirect_url);
if (!StringUtils.isEmpty(username) || !StringUtils.isEmpty(password)) {
//登陆成功,把登陆的用户存起来
String uuid = UUID.randomUUID().toString().substring(0, 6);
stringRedisTemplate.opsForValue().set(uuid, username);
//给 浏览器留记号
Cookie cookie = new Cookie("sso_token", uuid);
response.addCookie(cookie);
//登陆成功跳转,跳回之前的页面
return "redirect:" + redirect_url + "?token=" + uuid;
} else {
return "";
}
}
}
d:跳转 html:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登陆页面</title>
</head>
<body>
<form action="/goLogin" method="post">
用户名:<input name="username111" type="text"/>
<br>
密 码:<input name="password111" type="password">
<input type="hidden" name="redirect_url" th:value="${redirect_url}">
<input type="submit">
</form>
</body>
</html>
4)流程图:
b:补充:
登陆信息显示,通过 session 中取值,然后 token 从 redis 获取,存入 session/