乐趣区

关于spring-cloud:实战干货Spring-Cloud-Gateway-整合-OAuth20-实现分布式统一认证授权

大家好,我是不才陈某~

这是《Spring Cloud 进阶》第 15 篇 文章,往期文章如下:

  • 五十五张图通知你微服务的灵魂摆渡者 Nacos 到底有多强?
  • openFeign 夺命连环 9 问,这谁受得了?
  • 阿里面试这样问:Nacos、Apollo、Config 配置核心如何选型?这 10 个维度通知你!
  • 阿里面试败北:5 种微服务注册核心如何选型?这几个维度通知你!
  • 阿里限流神器 Sentinel 夺命连环 17 问?
  • 比照 7 种分布式事务计划,还是偏爱阿里开源的 Seata,真香!(原理 + 实战)
  • Spring Cloud Gateway 夺命连环 10 问?
  • Spring Cloud Gateway 整合阿里 Sentinel 网关限流实战!
  • 分布式链路追踪之 Spring Cloud Sleuth 夺命连环 9 问?
  • 链路追踪自从用了 SkyWalking,睡的真香!
  • 3 本书了,7 万 + 字,10 篇文章,《Spring Cloud 进阶》根底版 PDF
  • 妹子始终没搞懂 OAuth2.0,明天整合 Spring Cloud Security 一次说明确!
  • OAuth2.0 实战!应用 JWT 令牌认证!
  • OAuth2.0 实战!玩转认证、资源服务异样自定义这些骚操作!

明天这篇文章介绍一下 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 OAuth2.0 认证受权服
oauth2-cloud-gateway 网关服务
oauth2-cloud-order-service 订单资源服务

案例源码目录如下:

认证受权服务搭建

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

认证服务的搭建这里就不再细说了,上一篇文章中曾经介绍的很分明了:OAuth2.0 实战!应用 JWT 令牌认证!

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

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

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

  • user:具备 ROLE_user 权限
  • admin:具备 ROLE_admin、ROLE_user 权限

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

另外还整合了注册核心 Nacos,具体配置就不贴了,能够看源码。有不分明 Nacos,能够看之前文章:五十五张图通知你微服务的灵魂摆渡者 Nacos 到底有多强?

案例源码曾经上传 GitHub,关注公众号:码猿技术专栏,回复关键词:9529 获取!

网关服务搭建

网关应用的是Spring Cloud Gateway,网关如何搭建这里就不再细说了,有不分明的能够看之前文章:Spring Cloud Gateway 夺命连环 10 问?

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

1、增加依赖

须要增加几个 OAuth2.0 相干的依赖,如下:

2、JWT 令牌服务配置

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

3、认证管理器自定义

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

认证治理的作用就是获取传递过去的令牌,对其进行 解析 验签 过期工夫 断定。

具体代码如下:

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

抛出的异样如何解决?如何定制返回的后果?

这里抛出的异样能够通过 Spring Cloud Gateway 的全局异样进行捕捉,这个内容在 Spring Cloud Gateway 夺命连环 10 问?这篇文章有具体介绍。上面只贴出要害代码,如下:

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 个步骤,残缺的网关曾经搭建胜利了。

案例源码曾经上传 GitHub,关注公号:码猿技术专栏,回复关键词:9529 获取!

订单微服务搭建

因为在网关层面曾经做了鉴权了(细化到每个 URI),因而微服务就不必集成 Spring Security 独自做权限管制了。

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

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

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

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

留神:以上两个接口所须要的权限曾经放入到了 Redis 中,权限如下:

  • /order/login/info:ROLE_admin 和 ROLE_user 都能拜访
  • /order/login/admin:ROLE_admin 权限能力拜访

案例源码曾经上传 GitHub,关注公号:码猿技术专栏,回复关键词:9529 获取!

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

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

这也是目前企业中比拟罕用的一种形式,将鉴权齐全放在了网关层面,也实现了 动静权限 校验。当然有些是间接将接口的权限管制在每个微服务中。

采纳陈某的这种计划须要另外保护 URI 和权限的对应关系,当然这种难度很低,便于实现。

只是一种计划,具体是否选用还要思考到架构层面。

测试

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

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

2、应用 user 用户的令牌拜访 /order/login/info 接口,如下

能够看到胜利返回了,因为具备 ROLE_user 权限。

3、应用 user 用户的令牌拜访 /order/login/admin 接口,如下

能够看到间接返回了无权限拜访,间接在网关层被拦挡了。

总结

本篇文章只是简略的整合了 网关 +OAuth2.0,理论开发中还有一些细节待欠缺,因为文章篇幅限度,后续介绍 ……

案例源码曾经上传 GitHub,关注公号:码猿技术专栏,回复关键词:9529 获取!

最初说一句(别白嫖,求关注)

陈某每一篇文章都是精心输入,曾经写了 3 个专栏,整顿成PDF,获取形式如下:

  1. 《Spring Cloud 进阶》PDF:关注公号:【码猿技术专栏】回复关键词 Spring Cloud 进阶 获取!
  2. 《Spring Boot 进阶》PDF:关注公号:【码猿技术专栏】回复关键词 Spring Boot 进阶 获取!
  3. 《Mybatis 进阶》PDF:关注公号:【码猿技术专栏】回复关键词 Mybatis 进阶 获取!
退出移动版