今天这篇文章介绍一下Spring Cloud Gateway整合OAuth2.0实现认证授权,涉及到的知识点有点多,有不清楚的可以看下陈某的往期文章。

文章目录如下:

微服务认证方案

微服务认证方案目前有很多种,每个企业也是大不相同,但是总体分为两类,如下:

  1. 网关只负责转发请求,认证鉴权交给每个微服务控制

  2. 统一在网关层面认证鉴权,微服务只负责业务

你们公司目前用的哪种方案?

先来说说第一种方案,有着很大的弊端,如下:

  • 代码耦合严重,每个微服务都要维护一套认证鉴权

  • 无法做到统一认证鉴权,开发难度太大

第二种方案明显是比较简单的一种,优点如下:

  • 实现了统一的认证鉴权,微服务只需要各司其职,专注于自身的业务

  • 代码耦合性低,方便后续的扩展

下面陈某就以第二种方案为例,整合Spring Cloud Gateway+Spring Cloud Security 整合出一套统一认证鉴权案例。

案例架构

开始撸代码之前,先来说说大致的认证鉴权流程,架构如下图:

大致分为四个角色,如下:

  • 客户端:需要访问微服务资源

  • 网关:负责转发、认证、鉴权

  • OAuth2.0授权服务:负责认证授权颁发令牌

  • 微服务集合:提供资源的一系列服务。

大致流程如下:

1、客户端发出请求给网关获取令牌

2、网关收到请求,直接转发给授权服务

3、授权服务验证用户名、密码等一系列身份,通过则颁发令牌给客户端

4、客户端携带令牌请求资源,请求直接到了网关层

5、网关对令牌进行校验(验签、过期时间校验....)、鉴权(对当前令牌携带的权限)和访问资源所需的权限进行比对,如果权限有交集则通过校验,直接转发给微服务

6、微服务进行逻辑处理

针对上述架构需要新建三个服务,分别如下:

案例源码目录如下:

认证授权服务搭建

很多企业是将认证授权服务直接集成到网关中,这么做耦合性太高了,这里陈某直接将认证授权服务抽离出来。

新建一个oauth2-cloud-auth-server模块,目录如下:

和上篇文章不同的是创建了JwtTokenUserDetailsService这个类,用于从数据库中加载用户,如下:

为了演示只是模拟了从数据库中查询,其中存了两个用户,如下:

  • user:具有ROLE_user权限

  • admin:具有ROLE_admin、ROLE_user权限

要想这个生效,还要在security的配置文件SecurityConfig中指定,如下图:

另外还整合了注册中心Nacos,详细配置就不贴了,可以看源码。

网关服务搭建

网关使用的是Spring Cloud Gateway

新建一个oauth2-cloud-gateway模块,目录如下图:

1、添加依赖

需要添加几个OAuth2.0相关的依赖,如下:

2、JWT令牌服务配置

使用JWT令牌,配置要和认证服务的令牌配置相同,代码如下:

3、认证管理器自定义

新建一个JwtAuthenticationManager,需要实现ReactiveAuthenticationManager这个接口。

认证管理的作用就是获取传递过来的令牌,对其进行解析、验签、过期时间判定。

详细代码如下:

逻辑很简单,就是通过JWT令牌服务解析客户端传递的令牌,并对其进行校验,比如上传三处校验失败,抛出令牌无效的异常。

抛出的异常如何处理?如何定制返回的结果?

这里抛出的异常可以通过Spring Cloud Gateway的全局异常进行捕获。下面只贴出关键代码,如下:

4、鉴权管理器自定义

经过认证管理器JwtAuthenticationManager认证成功后,就需要对令牌进行鉴权,如果该令牌无访问资源的权限,则不允通过。

新建JwtAccessManager,实现ReactiveAuthorizationManager,代码如下:

这里的逻辑很简单,就是取出令牌中的权限和当前请求资源URI的权限对比,如果有交集则通过。

①处的代码什么意思?

这里是直接从Redis中取出资源URI对应的权限集合,因此实际开发中需要维护资源URI和权限的对应关系,这里不细说,为了演示,陈某直接在项目启动的时候向Redis中添加了两个资源的权限,代码如下:

注意:实际开发中需要维护资源URI和权限的对应关系。

②处的代码什么意思?

这处代码就是取出令牌中的权限集合

③处的代码什么意思?

这处代码就是比较两者权限了,有交集,则放行。

5、令牌无效或者过期时定制结果

在第4步,如果令牌失效或者过期,则会直接返回,这里需要定制提示信息。

新建一个RequestAuthenticationEntryPoint,实现ServerAuthenticationEntryPoint,代码如下:

6、无权限时定制结果

在第4步鉴权的过程中,如果无该权限,也是会直接返回,这里也需要定制提示信息。

新建一个RequestAccessDeniedHandler,实现ServerAccessDeniedHandler,代码如下:

7、OAuth2.0相关配置

经过上述6个步骤,相关组件已经准备就绪,现在直接配置到OAuth2.0中。

新建SecurityConfig这个配置类,标注注解 @EnableWebFluxSecurity,注意不是 @EnableWebSecurity,因为Spring Cloud Gateway是基于Flux实现的。详细代码如下:

需要配置的内容如下:

  • 认证过滤器,其中利用了认证管理器对令牌的校验

  • 鉴权管理器、令牌失效异常处理、无权限访问异常处理

  • 白名单配置

  • 跨域过滤器的配置

8、全局过滤器定制

试想一下:网关层面认证鉴权成功后,下游微服务如何获取到当前用户的详细信息?

陈某这里是将令牌携带的用户信息解析出来,封装成JSON数据,然后通过Base64加密,放入到请求头中,转发给下游微服务。

这样一来,下游微服务只需要解密请求头中的JSON数据,即可获取用户的详细信息。

因此需要在网关中定义一个全局过滤器,用来拦截请求,解析令牌,关键代码如下:

上述代码逻辑如下:

  • 检查是否是白名单,白名单直接放行

  • 检验令牌是否存在

  • 解析令牌中的用户信息

  • 封装用户信息到JSON数据中

  • 加密JSON数据

  • 将加密后的JSON数据放入到请求头中

好了,经过上述8个步骤,完整的网关已经搭建成功了。

订单微服务搭建

由于在网关层面已经做了鉴权了(细化到每个URI),因此微服务就不用集成Spring Security单独做权限控制了。

因此这里的微服务也是相对比较简单了,只需要将网关层传递的加密用户信息解密出来,放入到Request中,这样微服务就能随时获取到用户的信息了。

新建一个oauth2-cloud-order-service模块,目录如下:

新建一个过滤器AuthenticationFilter,用于解密网关传递的用户数据,代码如下:

新建两个接口,返回当前登录的用户信息,如下:

注意:以上两个接口所需要的权限已经放入到了Redis中,权限如下:

  • /order/login/info:ROLE_admin和ROLE_user都能访问

  • /order/login/admin:ROLE_admin权限才能访问

为什么要将URI和权限放入Redis?

在网关的鉴权管理器那里是直接从Redis中获取URI对应的权限,然后和令牌中的权限比较,为什么要这样做?

这也是目前企业中比较常用的一种方式,将鉴权完全放在了网关层面,也实现了动态权限校验。当然有些是直接将接口的权限控制在每个微服务中。

采用陈某的这种方案需要另外维护URI和权限的对应关系,当然这种难度很低,便于实现。

只是一种方案,具体是否选用还要考虑到架构层面。

测试

同时启动上述三个服务,如下:

1、用密码模式登录user,获取令牌,如下:

2、使用user用户的令牌访问/order/login/info接口,如下:

可以看到成功返回了,因为具备ROLE_user权限。

3、使用user用户的令牌访问/order/login/admin接口,如下:

可以看到直接返回了无权限访问,直接在网关层被拦截了。

有道无术,术可成;有术无道,止于术

欢迎大家关注Java之道公众号

好文章,我在看❤️

实战干货!Spring Cloud Gateway 整合 OAuth2.0 实现分布式统一认证授权!相关推荐

  1. Spring Cloud Gateway 整合阿里 Sentinel网关限流实战!

    前一篇文章介绍了Spring Cloud Gateway的一些基础知识点,今天陈某就来唠一唠网关层面如何做限流? 文章目录如下: 网关如何限流? Spring Cloud Gateway本身自带的限流 ...

  2. Spring Cloud Gateway 整合阿里 Sentinel网关限流实战

    文章目录如下: 网关如何限流? Spring Cloud Gateway本身自带的限流实现,过滤器是RequestRateLimiterGatewayFilterFactory,不过这种上不了台面的就 ...

  3. Spring Cloud Gateway 整合 knife4j 聚合接口文档

    当系统中微服务数量越来越多时,如果任由这些服务散落在各处,那么最终管理每个项目的接口文档将是一件十分麻烦的事情,单是记住所有微服务的接口文档访问地址就是一件苦差事了.当如果能够将所有微服务项目的接口文 ...

  4. Spring Cloud Gateway 结合 OAuth2 提供 UAA 服务,来袭。

    微服务做用户认证和授权一直都是一个难点,随着 OAuth2.0 的密码模式被作废,更是难上加难了.今天胖哥群里的一个群友搭建用户认证授权体系的时候遇到了一些棘手的问题,这让胖哥觉得是时候分享一些思路出 ...

  5. Spring Cloud Gateway 结合OAuth2提供UAA服务

    微服务做用户认证和授权一直都是一个难点,随着OAuth2.0的密码模式被作废,更是难上加难了.今天胖哥群里的一个群友搭建用户认证授权体系的时候遇到了一些棘手的问题,这让胖哥觉得是时候分享一些思路出来了 ...

  6. Spring Cloud Gateway 2.1.0 中文官网文档

    目录 1. How to Include Spring Cloud Gateway 2. Glossary 3. How It Works 4. Route Predicate Factories 5 ...

  7. Spring Cloud Gateway(二):Spring Cloud Gateway整合Eureka应用

    Spring Cloud Gateway 应用概述 下面的示例启动两个服务:gataway-server 和 user-service 都注册到注册中心 Eureka上,客户端请求后端服务[user- ...

  8. 【项目实战】Spring Cloud Gateway入门介绍 - 网关过滤器工厂

    一.全局过滤器GlobalFilter 全局过滤器是针对于网关而言通用的功能组件实现,采用全局来实现. 以下是两个如何全局过滤器GlobalFilter的实例 1.1 实例1:定义ForwardAut ...

  9. Spring Cloud Gateway整合Nacos实现服务路由及集群负载均衡

    目录 一.序言 二.代码示例 1.父工程spring-cloud-gateway-learning 2.子工程spring-cloud-api-gateway (1) pom.xml (2) 配置文件 ...

最新文章

  1. Android TextView 去除顶部和底部留白(上下的间距有空白问题处理)
  2. 4.3.6 无分类编址CIDR(构成超网)
  3. 基于Redis的分布式锁实现
  4. Python笔记-使用cython生成dll,C++进行调用
  5. postgresql fdw mysql_mysql同步数据到PostgreSQL(使用mysql_fdw)
  6. 【IJCAI 2020】篇章要素识别和篇章结构评分(下)
  7. qesat/java,QESatJava白盒测试工具
  8. fedora mysql gui,fedora 14 启用无线网卡 | 勤奋的小青蛙
  9. 自动驾驶汽车传感器融合系统及多传感器数据融合算法浅析
  10. 计算机专业文献阅读报告,文献阅读报告范本.doc
  11. 谷歌高级搜索技巧之高级语法查询指令
  12. 【开发经验】mysql有效防止删库跑路!
  13. 一个好玩的小游戏——麻神之战
  14. 【微信小程序】video视频(77/100)
  15. (转)一位计算机牛人的心得,谈到计算机和数学,很实用
  16. ESP32实验-自建web服务器配网01
  17. 图解Adobe Flash Player 浏览器插件安装
  18. HTML/CSS学习笔记(1)
  19. 银行手机APP安全评估报告【转载】
  20. OpenNI2的下载与安装

热门文章

  1. 2.1线性表的类型定义
  2. c语言键盘按f1显示f1,windows10键盘f1变成功能键的两种解决方法
  3. 腾讯Light·公益创新挑战赛获奖名单揭晓!看“创意+公益+科技”融合的力量
  4. php+当前+日期+函数是,php时间日期的处理函数
  5. 微信小程序上传大于4m_微信定制小程序开发
  6. LoadRunner小技巧集锦
  7. 计组之存储系统:7、Cache替换算法(随机算法RAND、先进先出算法FIFO、近期最少使用LRU、最近不经常使用LFU)
  8. 3-3:常见任务和主要工具之网络
  9. 面试题 03.04. 化栈为队/面试题09. 用两个栈实现队列/232. 用栈实现队列
  10. poj1753 Flip Game