springcloud gateway auth2.0 security nacos 项目集成实践

2,318 阅读6分钟

成熟是一种明亮而不刺眼的光辉,一种圆润而不腻耳的音响。

1 前言

OAuth2.0(开发授权) 是一个开发的标准,主要是解决第三方应用访问存在在该服务的用户信息,而不需要将用户账户密码同步给第三方,解决了用户登录的问题,在公众号、小程序、H5等应用服务越来越多的情况下,能够很好的解决用户的体验问题。基于此有必要总结一下相关的内容。OAuth2.0 只是解决了一个授权的问题,但是用户还是需要一次的登录,而这个权限需要依赖安全管理框架,而 OAuth2.0 一般是和 SpringSecurity 一起使用。在本文中还将引入 gateway 网关,只介绍授权码的方式,通过应用回调来处理授权问题。

2 项目结构

在项目中主要有四个部分:

  • 1 网关服务,负责请求的鉴权和请求分发。
  • 2 授权服务,负责用户的授权和用户登录。
  • 3 商品服务和订单服务,具体的业务系统。

3 授权码模式

3.1 授权流程

OAuth2.0 授权码模式是应用十分广泛的模式,具体流程如下时序图所示:

再使用 OAuth2.0 之前,需要先引入相关的依赖,这里采用的是 springboot 2.7.0, springcloud 2021.0.3, springcloud-alibaba 2021.0.1.0,oauth 2.2.5.RELEASE, security 2.7.0 这里采用的都是比较最新的版本,核心的依赖如下所示:

  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
      <version>2.7.0</version>
  </dependency>
  
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-oauth2</artifactId>
      <version>2.2.5.RELEASE</version>
  </dependency>
3.2 授权配置信息

关于 OAuth2.0 的相关配置,主要是 AuthorizationServerConfigurerAdapter 相关的内容,其中有一下几个重要的配置内容:

  • 1 AuthorizationServerSecurityConfigurer 权限的配置信息,这里的配置信息包括表单提交权限验证信息,可以对 /oauth/check_token/oauth/token_key 进行授权,前者用来资源服务器校验token 信息, 后者在使用jwt令牌时提供公有密钥端点。在这里需要再介绍一下, /oauth/authorizeAuthenticationEndpoint 用来处理认证请求的。/oauth/tokenTokenEndpoint 是处理访问令牌请求的。

  • 2 AuthorizationServerEndpointsConfigurer 令牌和端点的配置信息, 这里需要的配置有 authenticationManager,是 springsecurity 的鉴权管理器,refresh_token 是否重用,以及用户的登录查询 UserDetailsServiceaccessTokenConverter 用来生成 token 信息,以及 allowedTokenEndpointRequestMethods 用来配置接口访问的方法。tokenEnhancer 则是 token 的增强信息配置。endpoints.pathMapping 则是自定义接口的,对接口进行重写。

  • 3 ClientDetailsServiceConfigurer 客户端信息的初始化配置,这里有两种方式存储,可以使用数据库配置也可以使用内存的方式进行处理。其中关键的配置有 client_id 用来标识客户id, secret 是客户端的安全码配置, scope 是用来限制客户端的访问范围,如果是空或者all 则可以访问全部范围。authorizedGrantTyoes 标识客户端的授权类型,此处使用的是授权码模式,为 authorization_codeauthorities 为该客户端的使用权限范围。autoApprove 是标识自动授权,默认为 false, 最后还有一个回调地址 redirectUris。这里采用的是数据库配置,在数据库中的配置如下所示:

在下图中,也可以看到 inMemory 的配置信息

3.3 token 信息增强

默认情况下 jwt 返回的内容不足以获取全部的信息,一般情况下需要对 token 的信息进行增强,以边传输信息。

进行增强配置后,获取到的 OAuth2AccessToken 到的结构信息如下图所示:

默认的返回信如下图: 增强后的 token 结构信息如下所示:

3.4 重写 oauth 2.0的授权页面

在 3.2 中,我们已经知道了通过 endpoints.pathMapping 来处理授权页面的重写,那么在web 层就可以自定义授权页面的控制器,不过在这里要注意,加上这个 SessionAttributes 注解,这里的视图层采用的是 freemaker 进行渲染,传入前端的参数有 clientId 和授权范围 scope。

重写后的页面如下图所示:

3.5 重写登录认证接口

默认情况下,/oauth/token 可以使用 OAuth 的接口,但是可以根据需要重写认证接口,这里注入的是 TokenEndpoint ,使用 tokenEndpoint.postAccessToken 方法进行处理,获取 OAuth2AccessToken 信息。

4 授权模式回调

在授权码模式下,授权服务器会生成一个code 码,回调资源服务器的回调地址,资源服务器根据code码和client 的配置信息去授权服务器获取 token 信息。 在这里介绍一下几个比较重要的接口。

# 获取以及刷新 token 信息, 获取授权信息以及检查token 信息
/oauth/token
/oauth/authorize
/oauth/check_token

回调是资源服务器向授权服务器进行获取 token 的接口,一个授权码只能使用一次,这样最大限度的保证了用户数据的安全性以及数据获取的便利性。

5 SpringSecurity 相关配置

针对 SpringSecurity 的配置大家都不陌生,主要是继承 WebSecurityConfigurerAdapter 重写 configure 方法即可。

这里需要强调一下,需要声明用户的登录地址,否则当用户访问授权时,需要登录跳转时,会报404 的错误或者登录地址配置失效。

关于 security 的其它配置,不是本文的重点,这里就不展开讲述了。重写后的登录页面如下图所示:

6 网关配置

关于网关 gateway 的配置信息,需要先引入以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

这里采用的是响应式编程,使用 webflux 而不是 webmvc, gateway 的配置包含基本的路由配置规则以及权限验证。

下图是 gateway 相关的配置信息,主要是配置相关的过滤器以及鉴权处理。 ReactiveAuthorizationManager 主要用来判断用户是否有资源访问权限,ServerAuthenticationEntryPoint 用来处理成功的返回结果,ServerAccessDeniedHandler 用来处理无权限的情况。

下图是 ReactiveAuthorizationManager 的配置信息,主要是控制用户对资源的访问权限,只有用户有访问资源的权限才可以访问资源内容。

此外还可以对 ServerHttpSecurity.addFilterBefore 进行配置,添加过滤器,控制过滤器的访问顺序,这里实现的都是 WebFilter , 此外还可以配置全局过滤器 GlobalFilter

7 接口访问

在完成了授权服务和网关配置后,还有两个微服务的项目需要创建,这里比较简单就不展开讲述了,在文末的项目源码中可以获取。

项目使用了 nacos 作为配置中心和注册中心,如下图所示:

访问接口如下图所示:

刷新 token 如下图所示:

8 总结

在本文中,主要介绍了 Oauth2.0springsecurity 进行鉴权和开放授权,使用了 springcloud-gateway 作为网关, nacos 作为注册中心和配置中心,采用 redis 进行接口权限的配置,使用 mysql 存储 oauth2.0 的配置信息以及用户信息,在后续的文章中将继续分享网关相关的内容。

项目代码已经上传到 github 上。 springboot-auth

【项目参考及推荐】

本文正在参加 「金石计划 . 瓜分6万现金大奖」