当前位置: 首页 > news >正文

认证中心:基于cookie和session实现单点登陆

流程图

在这里插入图片描述

参数

不同域名之下(不同父域名)
cookie+session+redis

流程追踪

用户访问系统1的受保护资源,系统1发现用户未登录,跳转至sso认证中心,并将自己的地址作为参数

sso认证中心发现用户未登录,将用户引导至登录页面

用户输入用户名密码提交登录申请s

so认证中心校验用户信息,创建用户与sso认证中心之间的会话,称为全局会话,同时创建授权令牌。

//client携带redirect_url来这里请求我们的认证//那么需要再认证页面上保存下来redirect_url//@CookieValue(value = "sso_token", required = false)@GetMapping("/login.html")public String loginPage(@RequestParam("redirect_url") String url, Model model, @CookieValue(value = "sso_token", required = false) String sso_token) {//如果存在sso_tokenif (!StringUtils.isEmpty(sso_token)) {return "redirect:" + url + "?token=" + sso_token;}//知道下个页面跳转的位置model.addAttribute("url", url);return "login";}@ResponseBody@GetMapping("/userinfo")public String userinfo(@RequestParam(value = "token") String token) {String s = stringRedisTemplate.opsForValue().get(token);return s;}@PostMapping("/doLogin")public String doLogin(@RequestParam("username") String username, @RequestParam("password") String password, @RequestParam("redirect_url") String url, HttpServletResponse response) {//如果想要退出登录那么sso_token失效if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)){//颁发token 并且将信息存放到redis中String uuid = UUID.randomUUID().toString().replaceAll("-","");stringRedisTemplate.opsForValue().set(uuid,username);//向客户端浏览器写入tokenCookie cookie = new Cookie("sso_token",uuid);response.addCookie(cookie);//将cookie写到浏览器//原因是如果第一个服务已经登录,第二个服务来登录,检测到没有session没有token来进行认证//login检测到cookie中有登录状态就应该通过return "redirect:" + url + "?token=" + uuid;}return "login";}

sso认证中心带着令牌跳转会最初的请求地址(系统1)

系统1拿到令牌,去sso认证中心校验令牌是否有效

sso认证中心校验令牌,返回有效,注册系统1

系统1使用该令牌创建与用户的会话,称为局部会话,返回受保护资源

    @GetMapping(value = "/employees")public String employees(Model model, HttpSession session, @RequestParam(value = "token", required = false) String token) {//如果token存在if (!StringUtils.isEmpty(token)) {RestTemplate restTemplate = new RestTemplate();//根据token获取其中的用户信息放到session当中ResponseEntity<String> forEntity = restTemplate.getForEntity("http://ssoserver.com:8080/userinfo?token=" + token, String.class);String body = forEntity.getBody();session.setAttribute("loginUser", body);}//session是否存在Object user = session.getAttribute("loginUser");if (user == null) {//进入认证中心进行登录 并且指定登录成功之后的重定向页面return "redirect:" + "http://ssoserver.com:8080/login.html" + "?redirect_url=http://client1.com:8082/employees";} else {//返回信息List<String> res = new ArrayList<>();res.add("张三");res.add("李四");model.addAttribute("emps", res);return "employees";}}

用户访问系统2的受保护资源

系统2发现用户未登录,跳转至sso认证中心,并将自己的地址作为参数

sso认证中心发现用户已登录,跳转回系统2的地址,并附上令牌

系统2拿到令牌,去sso认证中心校验令牌是否有效

sso认证中心校验令牌,返回有效,注册系统2

系统2使用该令牌创建与用户的局部会话,返回受保护资源用户登录成功之后,会与sso认证中心及各个子系统建立会话,用户与sso认证中心建立的会话称为全局会话

用户与各个子系统建立的会话称为局部会话,局部会话建立之后,用户访问子系统受保护资源将不再通过sso认证中心

分析

每个系统中都会存在一份cookie,并且在第一次登录的时候系统要去访问用户中心获取令牌,之后就是session。
当用户退出系统,需要做的是销毁局部会话以及cookie,重定向到认证中心的退出接口,认证中心从会话中获取令牌,销毁全局会话,清除redis中该token的用户信息,调用缓存中系统的退出接口,清除每个客户端的局部会话,接着跳转登录页面。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【后端开发实习】Python基于Quart框架实现SSE数据传输
  • 科普文:5种Linux下软件部署方式说明
  • 基于微信小程序+SpringBoot+Vue的自习室选座与门禁系统(带1w+文档)
  • git配置代理
  • 深入探索PHP框架:Symfony框架全面解析
  • 将Android Library项目发布到JitPack仓库
  • Android Studio导入源码
  • 使用PageHelper插件来分页查询
  • JavaScript实战 - 一个能够做圆周运动的模型
  • “微软蓝屏”全球宕机,敲响基础软件自主可控警钟
  • HTML:lang属性作用
  • 谷粒商城实战笔记-47-商品服务-API-三级分类-网关统一配置跨域
  • Transformer-Bert---散装知识点---mlm,nsp,较之经典tran的区别和实际应用方式
  • c++中的音乐
  • Linux火焰传感器驱动程序
  • [nginx文档翻译系列] 控制nginx
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • jdbc就是这么简单
  • Linux下的乱码问题
  • Redash本地开发环境搭建
  • SpringCloud集成分布式事务LCN (一)
  • supervisor 永不挂掉的进程 安装以及使用
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 盘点那些不知名却常用的 Git 操作
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 在Docker Swarm上部署Apache Storm:第1部分
  • 【云吞铺子】性能抖动剖析(二)
  • ​Java并发新构件之Exchanger
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • # 详解 JS 中的事件循环、宏/微任务、Primise对象、定时器函数,以及其在工作中的应用和注意事项
  • #stm32驱动外设模块总结w5500模块
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • (1)(1.13) SiK无线电高级配置(六)
  • (C#)if (this == null)?你在逗我,this 怎么可能为 null!用 IL 编译和反编译看穿一切
  • (LeetCode C++)盛最多水的容器
  • (补充):java各种进制、原码、反码、补码和文本、图像、音频在计算机中的存储方式
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (十)Flink Table API 和 SQL 基本概念
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (四) 虚拟摄像头vivi体验
  • (学习日记)2024.01.09
  • (一)python发送HTTP 请求的两种方式(get和post )
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • ****三次握手和四次挥手
  • ***详解账号泄露:全球约1亿用户已泄露
  • .NET CLR基本术语
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .NET Core 通过 Ef Core 操作 Mysql
  • .NET Reactor简单使用教程
  • .NET编程C#线程之旅:十种开启线程的方式以及各自使用场景和优缺点
  • .php结尾的域名,【php】php正则截取url中域名后的内容
  • @angular/cli项目构建--http(2)
  • @cacheable 是否缓存成功_让我们来学习学习SpringCache分布式缓存,为什么用?