简单聊一聊单点登录

article/2025/8/19 11:04:44

单点登录

  • 一、单点登录
  • 二、演示步骤
    • ①简单结构(域名的设置)
    • ②创建项目
      • 1.sso-server 模块代码
        • LoginController代码如下
        • GulimallTestSsoServerApplication启动类代码
        • login.html代码
        • application.properties配置文件
        • pom.xml文件
      • 2.sso-client1模块代码
        • HelloController代码
        • GulimallTestSsoClient1Application
        • list.html代码
        • application.properties
        • pom.xml文件
      • 3.sso-client2模块
        • HelloController代码
        • GulimallTestSsoClient2Application代码
        • list.html代码
        • application.properties配置文件
        • pom.xml文件
  • 三、演示流程

一、单点登录

  单点登录(SingleSignOn,SSO),就是通过用户的一次性鉴别登录。当用户在身份认证服务器上登录一次以后,就可以获得访问单点登录系统中其他关联系统和应用软件的权限,同时这种实现是不需要管理员对用户的登录状态或其他信息进行修改的,这意味着在多个应用系统中,用户只需一次登录就可以访问所有相互信任的应用系统。这种方式减少了由登录产生的时间消耗,辅助了用户管理,是比较流行的。总结就是一处登录,处处可用。

二、演示步骤

①简单结构(域名的设置)

 Windows里面修改域名的地方:C:\Windows\System32\drivers\etc下面的hosts文件里面,打开hosts文件,在最后加上以下的信息即可。

127.0.0.1  sso.com 
127.0.0.1  client1.com
127.0.0.1  client2.com

在这里插入图片描述
joke:双11的时候,害怕女朋友剁手,把 www.taobao域名映射到本机,一直访问就访问不到。
  核心:三个系统即使域名不一样,想办法给三个系统同步同一个用户的数据;
  1)中央认证服务器:sso.com;
  2)其他系统,想要登录去sso.com登录,登录成功跳转回来;
  3)只要有一个登录,其他都不用登录;
  4)全系统统一一个sso-sessionid;所有系统可能域名都不相同;

②创建项目

  1)利用Spring的初始化向导,创建单点登录服务器,将web、thymeleaf和lombok选中即可。以此创建三个模块。
在这里插入图片描述

1.sso-server 模块代码

在这里插入图片描述

LoginController代码如下

package com.atguigu.gulimall.ssoserver.controller;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.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;@Controller
public class LoginController {@AutowiredStringRedisTemplate redisTemplate;@ResponseBody@GetMapping("/userInfo")public String userInfo(@RequestParam("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 (!ObjectUtils.isEmpty(sso_token)){//说明之前有人登录过,浏览器留下了痕迹return "redirect:"+url+"?token="+sso_token;}model.addAttribute("url",url);return "login";}@PostMapping("/doLogin")public String doLogin(@RequestParam("username") String username,@RequestParam("password") String password,@RequestParam("url") String url,HttpServletResponse response){if(!ObjectUtils.isEmpty(username) && !ObjectUtils.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";}
}

GulimallTestSsoServerApplication启动类代码

package com.atguigu.gulimall.ssoserver;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class GulimallTestSsoServerApplication {public static void main(String[] args) {SpringApplication.run(GulimallTestSsoServerApplication.class, args);}}

login.html代码

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>登录页</title>
</head>
<body><form action="/doLogin" method="post">用户名:<input name="username" /><br/>密码:<input name="password" type="password"/><br/><input type="hidden" name="url" th:value="${url}"/><input type="submit" value="登录"/></form>
</body>
</html>

application.properties配置文件

server.port=8080spring.redis.host=127.0.0.1

pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.5</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.atguigu</groupId><artifactId>gulimall-test-sso-server</artifactId><version>0.0.1-SNAPSHOT</version><name>gulimall-test-sso-server</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</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><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

2.sso-client1模块代码

在这里插入图片描述

HelloController代码

package com.atguigu.gulimall.ssoclient1.controller;import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ObjectUtils;
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 javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;@Controller
public class HelloController {@Value("${sso.server.url}")String ssoServerUrl;/*** 无需登录就可访问* @return*/@ResponseBody@GetMapping("/hello")public String hello() {return "hello world";}/*** 感知是在登录之后跳转回来的,而不是我们直接访问的* @param model* @param session* @Param token 只要去sso登录成功跳回来就会带上* @return*/@GetMapping("/employees")public String employees(Model model, HttpSession session,@RequestParam(value = "token",required = false) String token){if(!ObjectUtils.isEmpty(token)){//去sso登录成功跳回来就会带上//TODO 1.去sso获取当前token真正对应的用户信息RestTemplate restTemplate = new RestTemplate();ResponseEntity<String> forEntity = restTemplate.getForEntity("http://sso.com:8080/userInfo?token=" + token, String.class);String body = forEntity.getBody();session.setAttribute("loginUser",body);}Object loginUser = session.getAttribute("loginUser");if (loginUser==null) {//没有登录,就跳转到登录服务器进行登录//跳转过去以后,使用url上的查询参数表示我们自己是哪一个页面//redirect_url=http://client1.com:8081/employeesreturn "redirect:"+ssoServerUrl+"?redirect_url=http://client1.com:8081/employees";}else{List<String> emps = new ArrayList<>();emps.add("张三");emps.add("李四");model.addAttribute("emps",emps);return "list";}}
}

GulimallTestSsoClient1Application

package com.atguigu.gulimall.ssoclient1;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class GulimallTestSsoClient1Application {public static void main(String[] args) {SpringApplication.run(GulimallTestSsoClient1Application.class, args);}}

list.html代码

<!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>

application.properties

server.port=8081sso.server.url=http://sso.com:8080/login.html

pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.5</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.atguigu</groupId><artifactId>gulimall-test-sso-client1</artifactId><version>0.0.1-SNAPSHOT</version><name>gulimall-test-sso-client1</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><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.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><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

3.sso-client2模块

在这里插入图片描述

HelloController代码

package com.atguigu.gulimall.ssoclient2.controller;import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ObjectUtils;
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 javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;@Controller
public class HelloController {@Value("${sso.server.url}")String ssoServerUrl;/*** 无需登录就可访问* @return*/@ResponseBody@GetMapping("/hello")public String hello() {return "hello";}/*** 感知是在登录之后跳转回来的,而不是我们直接访问的* @param model* @param session* @Param token 只要去sso登录成功跳回来就会带上* @return*/@GetMapping("/boss")public String employees(Model model, HttpSession session,@RequestParam(value = "token",required = false) String token){if(!ObjectUtils.isEmpty(token)){//去sso登录成功跳回来就会带上//TODO 1.去sso获取当前token真正对应的用户信息RestTemplate restTemplate = new RestTemplate();ResponseEntity<String> forEntity = restTemplate.getForEntity("http://sso.com:8080/userInfo?token=" + token, String.class);String body = forEntity.getBody();session.setAttribute("loginUser",body);}Object loginUser = session.getAttribute("loginUser");if (loginUser==null) {//没有登录,就跳转到登录服务器进行登录//跳转过去以后,使用url上的查询参数表示我们自己是哪一个页面//redirect_url=http://client1.com:8081/employeesreturn "redirect:"+ssoServerUrl+"?redirect_url=http://client2.com:8082/boss";}else{List<String> emps = new ArrayList<>();emps.add("张三");emps.add("李四");model.addAttribute("emps",emps);return "list";}}
}

GulimallTestSsoClient2Application代码

package com.atguigu.gulimall.ssoclient2;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class GulimallTestSsoClient2Application {public static void main(String[] args) {SpringApplication.run(GulimallTestSsoClient2Application.class, args);}}

list.html代码

<!DOCTYPE html>
<html 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>

application.properties配置文件

server.port=8082sso.server.url=http://sso.com:8080/login.html

pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.5</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.atguigu</groupId><artifactId>gulimall-test-sso-client2</artifactId><version>0.0.1-SNAPSHOT</version><name>gulimall-test-sso-client2</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><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.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><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

三、演示流程

测试视频

单点登录

视频地址:https://www.bilibili.com/video/BV1Wa411Y7cr/


http://chatgpt.dhexx.cn/article/gEa0iJBK.shtml

相关文章

聊一聊俞敏洪

2009年&#xff0c;CCTV颁发中国经济年度人物&#xff0c;给出了这样的颁奖词&#xff1a; “一个曾经的留级生&#xff0c;让无数学子的人生升级&#xff1b;他从未留过洋&#xff0c;却组建了一支跨国的船队。他用26个字母拉近了此岸和彼岸的距离。胸怀世界&#xff0c;志在东…

闲暇聊一聊

大家好&#xff0c;我是Tom哥 非常庆幸&#xff0c;早毕业了几年&#xff0c;那时的互联网还没有像现在这么卷&#xff0c;甚至没有 内卷 这个网络流行词 一切都是那么美好&#xff0c;可以自由享受学习技术的快乐 Tom哥是校招进的阿里&#xff0c;当时的技术资料可不像现在…

聊一聊数据库的行存与列存

目录 存储方式比较 优缺点比较 行存与列存实验 选择建议 注意事项 好多人最开始学习数据库的时候&#xff0c;是关系数据库&#xff0c;数据以表格形式存储&#xff0c;一行表示一条记录。其实这种就是典型的行存储&#xff08;Row-based store&#xff09;&#xff0c;将…

聊一聊 AS 的一些好用的功能

聊一聊 AS 的一些好用的功能 文章开始前先墨迹几句&#xff0c;好久没写文章了&#xff0c;这段时间公司确实挺忙&#xff0c;也没抽出时间&#xff0c;上一篇文章还是三月初写的&#xff0c;距今已经两个多月啦&#xff0c;不能再这样下去了&#xff0c;虽然我不能像一些大佬…

聊一聊罗振宇

小灰是得到平台的重度用户&#xff0c;也是罗振宇的粉丝。 罗振宇&#xff0c;人称“罗胖子”&#xff0c;非常有趣的是&#xff0c;人们常常把另一个姓罗的胖子和他混为一谈。 今天&#xff0c;我们就来聊一聊他。 罗振宇是个特别复杂的人。 很多人认识罗振宇&#xff0c;是从…

聊一聊我的2020

回顾2020 &#xff08;接下来是一大段唠叨&#xff0c;可以直接到文末&#xff0c;有小安利和经验总结&#xff09; 还有几天2020年就结束并迎来新的一年。这一年中总是能听到有人在感慨2020是不平凡的一年。仔细想想&#xff0c;确实如此&#xff0c;至少对我来说是这样的。 作…

聊一聊 gRPC 中的拦截器

今天我们继续 gRPC 系列。 前面松哥跟大家聊了 gRPC 的简单案例&#xff0c;也说了四种不同的通信模式&#xff0c;感兴趣的小伙伴可以戳这里&#xff1a; 一个简单的案例入门 gRPC 聊一聊 gRPC 的四种通信模式 今天我们来继续聊一聊 gRPC 中的拦截器。 有请求的发送、处理&…

聊一聊微博新知博主这件事,看看赚钱方式有哪些?

从今天开始&#xff0c;准备将我付费星球内的精华文章&#xff0c;在每周六和周日以付费文章的方式在公众号分享给大家&#xff0c;如果你不想加入我的星球&#xff0c;还想看的话&#xff0c;可以在这里付费看。当然&#xff0c;加入星球会更划算&#xff0c;因为星球内内容更…

【QGIS入门实战精品教程】2.1:初识QGIS软件

从今天开始&#xff0c;我们一起来学习一款免费开源、对机器要求低、功能强大的GIS软件&#xff1a;QGIS &#xff01; 一、QGIS简介 QGIS&#xff08;原称Quantum GIS&#xff09;是一个自由软件的桌面GIS软件。它提供数据的显示、编辑和分析功能。 QGIS是一个用户界面友好的…

QGIS教程01:为什么要用QGIS?

从去年开始抛弃ArcGIS转用QGIS以来&#xff0c;发现QGIS越来越好用&#xff0c;功能也相当强大。而且我发现身边好多朋友也在开始使用QGIS&#xff0c;但目前国内这方面的学习资料还比较少&#xff0c;国外的原版资料又相对比较啰嗦&#xff0c;所以我和几位GISer入门知识星球的…

qgis教程

qgis教程 一、导入点云文件 1、新建图层 2、视图-》创建3d视图 3、添加标注工具&#xff0c;创建 shape

【QGIS入门实战精品教程】3.4:QGIS创建、连接、打包GeoPackage数据库及数据入库案例详解

GeoPackage(以下简称gpkg),内部使用SQLite实现的一种单文件、与操作系统无关的地理数据库。在QGIS中可以很方便的实现GeoPackage的创建与连接等操作。 文章目录 一、QGIS创建GeoPackage1. 创建数据库2. 数据入库二、矢量数据打包为GeoPackage1. 加载shp文件2. 使用QGIS打包图…

【QGIS入门实战精品教程】3.3:QGIS如何打开ArcGIS创建的文件数据库(GDB)?

在行业应用中,GIS地理空间数据往往存储在ESRI ArcGIS的文件地理数据库(File GeodataBase),因此,ArcGIS与QGIS的数据交互、共享就显得非常重要。QGIS3可以直接打开File GDB数据,并对数据进行显示、查看、处理等操作。具体的步骤如下: 相关阅读:【QGIS入门实战精品教程】3…

【QGIS入门实战精品教程】1.2:QGIS与ArcGIS的区别和联系

「刘一哥GIS」系列专栏《QGIS入门实战精品教程(配套案例数据)》目录 以下是GISGeography官方给出的两者之间的27点比较(译): 官方网址:https://gisgeography.com/qgis-arcgis-differences/ 1.QGIS容纳更多的数据格式 ArcGIS没有支持所有的数据格式,毫无疑问,QGIS在处…

Qgis教程1:添加在线地图

自学Qgis小结1 一、作为应届生小白&#xff0c;进入公司得知要学习Qgis&#xff0c;可谓是对此一点也不了解&#xff0c;从来没接触过Qgis的我也不得不沉下心来去学习&#xff0c;取取经&#xff0c;下面是我学习Qgis过程的一点理解&#xff0c;希望对广大网友有所帮助&#x…

【QGIS入门实战精品教程】5.2:QGIS自定义坐标系案例教程

我国全国版图常用的投影为双标准纬线圆锥投影,如等积Albers投影或者等角Lambert投影,所使用的地理坐标参照系则依据数据生产时间而有所不同,如早期的北京54坐标系和西安80坐标系,以及近年来所普遍采用的国家2000大地坐标系。本文以全国四百万基础植被数据所采用的Albers投影…

【QGIS入门实战精品教程】14.1:QGIS如何加载各种在线地图?

文章目录 一、XYZ Tiles连接方式二、插件添加三、WMS/WMTS/OWS连接方式一、XYZ Tiles连接方式 1. 加载OpenStreetMap QGIS默认可以加载OpenStreetMap地图。在左侧点击XYZ Tiles,默认下面有个OpenStreetMap选项,双击打右侧会显示地图,如下图所示: 在OpenStreetMap上右键→…