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

【Oauth2整合gateway网关实现微服务单点登录】

文章目录

    • 一.什么是单点登录?
    • 二.Oauth2整合网关实现微服务单点登录
    • 三.时序图
    • 四.代码实现思路
      • 1.基于OAuth2独立一个认证中心服务出来
      • 2.网关微服务
      • 3产品微服务
      • 4.订单微服务
      • 5.开始测试单点登录

一.什么是单点登录?

单点登录(Single Sign On),简称为 SSO,是比较流行的企业业务整合的解决方案之一。它的用途在于,不管多么复杂的应用群,只要在用户权限范围内,那么就可以做到用户只需要登录一次就可以访问权限范围内的所有应用子系统。

二.Oauth2整合网关实现微服务单点登录

网关整合 OAuth2.0 有两种思路:

  • 一种是授权服务器生成令牌, 所有请求统一在网关层验证,判断权限等操作;
  • 另一种是由各资源服务处理,网关只做请求转发。

比较常用的是第一种,把API网关作为OAuth2.0的资源服务器角色,实现接入客户端权限拦截、令牌解析并转发当前登录用户信息给微服务,这样下游微服务就不需要关心令牌格式解析以及OAuth2.0相关机制了。

网关在认证授权体系里主要负责两件事:
(1)作为OAuth2.0的资源服务器角色,实现接入方权限拦截。
(2)令牌解析并转发当前登录用户信息(明文token)给微服务

微服务拿到明文token(明文token中包含登录用户的身份和权限信息)后也需要做两件事:
(1)用户授权拦截(看当前用户是否有权访问该资源)
(2)将用户信息存储进当前线程上下文(有利于后续业务逻辑随时获取当前用户信息)

三.时序图

在这里插入图片描述

四.代码实现思路

1.基于OAuth2独立一个认证中心服务出来

  • 启动OAuth2认证授权中心:需要定义配置类重新AuthorizationServerConfigurerAdapter认证服务配置适配器类的3个configure方法。
    以及需要用到spring-security的WebSecurityConfigurerAdapter类等等,这里不贴代码了,只讲思路。
  • 比如我认证中心服务配置完,端口启动为:8888。

2.网关微服务

我们要自定义认证过滤器。认证过滤器里面需要做:

  1. 获取请求头里面的token信息
  2. 然后传入参数token信息通过rpc调用认证服务 http://auth-server/oauth/check_token进行token认证。
    也可以定义授权过滤器:进行token信息里面的自定义权限校验等等,需要使用@Order(1)注解,值越小优先级越高,指定这个过滤器在认证过滤器之后。
  3. 然后向下游业务系统传递解析后的token信息。

我启动端口为:8880,下面是认证过滤器核心代码:

/*** 认证过滤器*/
@Component
@Order(0)
public class AuthenticationFilter implements GlobalFilter, InitializingBean {@Autowiredprivate RestTemplate restTemplate;private static Set<String> shouldSkipUrl = new LinkedHashSet<>();@Overridepublic void afterPropertiesSet() throws Exception {// 不拦截认证的请求shouldSkipUrl.add("/oauth/token");shouldSkipUrl.add("/oauth/check_token");shouldSkipUrl.add("/user/getCurrentUser");}@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String requestPath = exchange.getRequest().getURI().getPath();//不需要认证的urlif(shouldSkip(requestPath)) {return chain.filter(exchange);}//获取请求头String authHeader = exchange.getRequest().getHeaders().getFirst("Authorization");//请求头为空if(StringUtils.isEmpty(authHeader)) {throw new RuntimeException("请求头为空");}TokenInfo tokenInfo=null;try {//获取token信息tokenInfo = getTokenInfo(authHeader);}catch (Exception e) {throw new RuntimeException("校验令牌异常");}// tokenInfoexchange.getAttributes().put("tokenInfo",tokenInfo);return chain.filter(exchange);}private boolean shouldSkip(String reqPath) {for(String skipPath:shouldSkipUrl) {if(reqPath.contains(skipPath)) {return true;}}return false;}private TokenInfo getTokenInfo(String authHeader) {// 往授权服务发请求 /oauth/check_token// 获取token的值String token = StringUtils.substringAfter(authHeader, "bearer ");HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);//必须 basicAuth clienId clientSecretheaders.setBasicAuth(MDA.clientId, MDA.clientSecret);MultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("token", token);HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(params, headers);ResponseEntity<TokenInfo> response = restTemplate.exchange(MDA.checkTokenUrl, HttpMethod.POST, entity, TokenInfo.class);return response.getBody();}
}

常量类:

public class MDA {public static final String clientId = "gateway-server";public static final String clientSecret = "123123";public static final String checkTokenUrl = "http://auth-server/oauth/check_token";}

3产品微服务

我启动端口为:8084

4.订单微服务

我启动端口为:8082

5.开始测试单点登录

  1. 比如哪个单点登录接口处理完业务相关逻辑等,然后请求我们的授权服务-通过密码模式获取到access_token
    在这里插入图片描述
  2. 使用同一access_token,请求网关获取订单信息
    在这里插入图片描述
    3.使用同一access_token,请求网关获取商品信息
    在这里插入图片描述
    这样就完成我们的单点登录啦。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • pycharm恢复两边侧边栏常驻显示
  • 【QML 基础】QML ——描述性脚本语言,用于用户界面的编写
  • [深度学习]Pytorch框架
  • Windows11系统安装,配置CUDA、cuDNN等
  • 力扣206.反转链表
  • 【既约分数 / B】
  • 虚拟摄像头抓屏
  • Go语言中的Mutex实现探讨
  • Blender软件三大渲染器Eevee、Cycles、Workbench对比解析
  • 仿黑神话悟空跑动-脚下波纹特效(键盘wasd控制走动)
  • V3s pinctrl与gpio的耦合问题
  • 大数据新视界 --大数据大厂之 Reactjs 在大数据应用开发中的优势与实践
  • 我们一般使用的家庭宽带支持udp吗
  • sv标准解读第九章-进程
  • Python和C++及R相关系数数学统计学可视化和神经模型及评估指标
  • Angular数据绑定机制
  • IndexedDB
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • KMP算法及优化
  • scala基础语法(二)
  • SpringBoot 实战 (三) | 配置文件详解
  • ⭐ Unity + OpenCV 实现实时图像识别与叠加效果
  • 后端_MYSQL
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 浏览器缓存机制分析
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • ​zookeeper集群配置与启动
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • ‌移动管家手机智能控制汽车系统
  • ###STL(标准模板库)
  • #etcd#安装时出错
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (day 12)JavaScript学习笔记(数组3)
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (待修改)PyG安装步骤
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (牛客腾讯思维编程题)编码编码分组打印下标题目分析
  • (学习日记)2024.01.19
  • (一)基于IDEA的JAVA基础1
  • (转)nsfocus-绿盟科技笔试题目
  • .aanva
  • .Net Core 微服务之Consul(二)-集群搭建
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .NET牛人应该知道些什么(2):中级.NET开发人员
  • .Net小白的大学四年,内含面经
  • .NET中两种OCR方式对比
  • [ Algorithm ] N次方算法 N Square 动态规划解决
  • [8] CUDA之向量点乘和矩阵乘法
  • [BetterExplained]书写是为了更好的思考(转载)
  • [C++]AVL树怎么转
  • [ffmpeg] x264 配置参数解析
  • [GESP202312 四级] 田忌赛马
  • [IE技巧] IE 中打开Office文件的设置
  • [IMX6DL] CPU频率调节模式以及降频方法