Single Sign On 一处登陆、处处可用
参考:https://gitee.com/xuxueli0323/xxl-sso.git
一、项目搭建
结构:
- gulimall-test-sso-client 登录服务器 8080 ssoserver.com
- gulimall-test-sso-client 项目 1 8081 client1.com
1 2 3
| 127.0.0.1 ssoserver.com 127.0.0.1 client1.com 127.0.0.1 client2.com
|
核心:
三个系统即使域名不一样,想办法给三个系统同步同一个用户的票据
1、 中央认责服务器:ssoserver.com
2、 其他系统‘想要登录去 ssoserver.com 登录,登录成功跳转回来
3、只要一个登录,其他都不用登录
4、全系统一个ss0-sessionid
; 所有系统可能域名都不相同
二、项目流程图
三、项目代码
1.gulimall-test-sso-client
pom
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <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.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
|
controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| import org.springframework.http.ResponseEntity; 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 org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.client.RestTemplate; import org.thymeleaf.util.StringUtils;
import javax.servlet.http.HttpSession; import java.util.ArrayList;
@Controller public class HelloController {
@ResponseBody @GetMapping(value = "/hello") public String hello(){ return "hello"; }
@GetMapping(value = "/employees") public String employees(Model model, HttpSession session, @RequestParam(value = "token", required = false) String token) { if(!StringUtils.isEmpty(token)){ RestTemplate restTemplate = new RestTemplate(); ResponseEntity<String> forEntity = restTemplate.getForEntity("http://ssoserver.com:8080/userinfo?token=" + token, String.class); String body = forEntity.getBody();
session.setAttribute("loginUser",body); }
Object logUser = session.getAttribute("loginUser");
if(logUser == null){ return "redirect:" + "http://ssoserver.com:8080/login.html"+"?redirect_url=http://client1.com:8081/employees"; }else{
ArrayList<String> emps = new ArrayList<>();
emps.add("张三"); emps.add("李四");
model.addAttribute("emps",emps);
return "employees"; } } }
|
application.properties
1 2 3 4 5 6 7 8 9 10
| spring.application.name=gulimall-test-sso-client
server.port=8081
spring.thymeleaf.cache=false
spring.redis.host=192.168.56.10 spring.redis.port=6379
|
employees.html
1 2 3 4 5 6 7 8 9 10 11 12 13
| <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>员工列表</title> </head> <body> <h1>欢迎:[[${session.loginUser}]]</h1> <ul> <li th:each="emp:${emps}">姓名:[[${emp}]]</li> </ul> </body> </html>
|
2.gulimall-test-sso-server
pom
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
|
controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import org.thymeleaf.util.StringUtils;
import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; import java.util.UUID;
@Controller public class LoginController {
@Autowired private StringRedisTemplate redisTemplate;
@ResponseBody @GetMapping(value = "/userinfo") public String userinfo(@RequestParam(value = "token")String token){ String s = redisTemplate.opsForValue().get(token); return s; }
@GetMapping("/login.html") public String loginPage(@RequestParam("redirect_url") String url, Model model, @CookieValue(value = "sso_token", required = false) String sso_token) { if(!StringUtils.isEmpty(sso_token)){ return "redirect:"+url+"?token="+sso_token; }
model.addAttribute("url",url);
return "login"; }
@PostMapping(value = "/doLogin") public String doLogin(@RequestParam("username") String username, @RequestParam("password") String password, @RequestParam("redirect_url") String url, HttpServletResponse response) { if(!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)){
String uuid = UUID.randomUUID().toString().replace("_", ""); redisTemplate.opsForValue().set(uuid, username); Cookie sso_token = new Cookie("sso_token", uuid);
response.addCookie(sso_token); return "redirect:" + url + "?token=" + uuid; }
return "login"; } }
|
application.properties
1 2 3 4 5 6 7
| spring.application.name=gulimall-test-sso-server
server.port=8080
spring.redis.host=192.168.56.10 spring.redis.port=6379
|
login.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>登录页</title> </head> <body> <form action="/doLogin" method="post"> 用户名:<input type="text" name="username" /><br /> 密码:<input type="password" name="password" /><br /> <input type="hidden" name="redirect_url" value="http://localhost:8081/employees" /> <input type="submit" value="登录" /> </form> </body> </html>
|
四、效果展示