OAuth2在内存、Redis方式下的多客户端配置

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: `Spring`所提供的`OAuth2`集成策略,支持多种方式存储`认证信息`以及`客户端信息`,由于在之前的文章中讲解使用时把知识点进行了拆分,有很多同学不太会组合使用,很多单独问我`ApiBoot`所提供的`OAuth2`的整合后,多个客户端该怎么配置?

Spring所提供的OAuth2集成策略,支持多种方式存储认证信息以及客户端信息,由于在之前的文章中讲解使用时把知识点进行了拆分,有很多同学不太会组合使用,很多单独问我ApiBoot所提供的OAuth2的整合后,多个客户端该怎么配置?

本章就来讲讲如果我们使用内存方式Redis方式OAuth2相关信息存储时,该如何配置多个客户端!!!

系列文章

ApiBoot针对每一个组件都提供一系列的拆分详解文章,详情请访问 ApiBoot开源框架各个组件的系列使用文章汇总

前言

ApiBoot集成OAuth2内存方式Redis方式的客户端配置都位于application.yml/application.properties配置文件内,通过源码发现Spring提供了一个接口 TokenStore 来定义操作认证信息的方法列表,实现该接口后就可以定义不同的存储方式具体的逻辑,当前我们也可以进行自定义,只需要将自定义实现类的实例交付给Spring IOC进行托管就即可,OAuth2内部就会调用自定义的实现类来处理业务(在内部都是通过接口来操作,不关心实例是哪个实现类)。

当然Spring在整合OAuth2后也提供了一些内置的TokenStore实现类,如下所示:

  • InMemoryTokenStore

    客户端信息以及生成的AccessToken存放在内存中,项目重启后之前生成的AccessToken就会丢失,而ApiBoot OAuth在项目启动时会自动加载application.yml配置文件的客户端列表,所以客户端信息不会丢失。

  • JdbcTokenStore

    客户端信息以及生成的AccessToken存放在数据库中,项目重启后不影响认证,表结构由OAuth2提供。

  • RedisTokenStore

    客户端信息以及生成的AccessToken存放在 Redis中,支持分布式部署,AccessToken默认过期时间为7200秒,过期后也会自动被删除,使用起来比较方便,ApiBoot OAuth只需要修改api.boot.oauth.away=redis就可以启用这种方式。

  • JwtTokenStore

    主要功能是使用Jwt进行转换AccessToken,并不做数据AccessToken的存储。

客户端配置源码分析

当我们使用ApiBoot OAuth2提供的内存方式Redis方式来集成使用时,客户端列表的配置都位于application.yml,使用api.boot.oauth.clients配置参数进行指定,那这个参数所对应的源码位于 ApiBootOauthProperties 属性配置类内。

ApiBoot最初发行版中客户端只允许配置一个,根据使用者的反馈进行了迭代更新后支持了多个客户端的配置,对应ApiBootOauthProperties属性配置类内的clientis字段,源码如下所示:

/**
  * configure multiple clients
  */
private List<Client> clients = new ArrayList() {{
  add(new Client());
}};

clients字段默认值为一个Client的对象实例,而Client则是为ApiBootOauthProperties的一个内部类,如下所示:

/**
 * Oauth2 Client
 * Used to configure multiple clients
 */
@Data
public static class Client {
    /**
     * oauth2 client id
     */
    private String clientId = "ApiBoot";
    /**
     * oauth2 client secret
     */
    private String clientSecret = "ApiBootSecret";
    /**
     * oauth2 client grant types
     * default value is "password,refresh_token"
     */
    private String[] grantTypes = new String[]{"password", "refresh_token"};
    /**
     * oauth2 client scope
     * default value is "api"
     */
    private String[] scopes = new String[]{"api"};
    /**
     * oauth2 application resource id
     * default value is "api"
     */
    private String[] resourceId = new String[]{"api"};
    /**
     * oauth2 access token validity seconds
     * default value is 7200 second
     */
    private int accessTokenValiditySeconds = 7200;
}

根据Client类我们也就可以明白了,为什么ApiBoot OAuth在集成时不配置客户端也可以使用ApiBoot:ApiBootSecret来进行获取AccessToken,因为在ApiBootOauthProperties属性配置类中有一个默认的Client对象实例。

注意事项:当我们配置 api.boot.oauth.clients参数时默认的客户端会被覆盖掉

示例项目

既然我们知道了使用api.boot.oauth.clients可以配置多个客户端,那么接下来我们创建一个测试的项目,使用IDEA创建一个SpringBoot项目,项目pom.xml文件内容如下所示:

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <!--ApiBoot Security OAuth-->
  <dependency>
    <groupId>org.minbox.framework</groupId>
    <artifactId>api-boot-starter-security-oauth-jwt</artifactId>
  </dependency>
</dependencies>

<dependencyManagement>
  <dependencies>
    <!--ApiBoot统一版本依赖-->
    <dependency>
      <groupId>org.minbox.framework</groupId>
      <artifactId>api-boot-dependencies</artifactId>
      <version>2.2.1.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

配置多客户端

看过ApiBoot OAuth2系列文章的同学都应该知道,默认使用内存方式进行存储生成的AccessToken,这一点我们就不做修改了,如果你项目不是使用默认,可以去参考 ApiBoot开源框架各个组件的系列使用文章汇总 内安全组件分类下的文章。

application.yml文件内添加客户端列表配置,如下所示:

api:
  boot:
    # ApiBoot OAuth 相关配置
    oauth:
      clients:
        - clientId: minbox
          clientSecret: chapter
        - clientId: hengboy
          clientSecret: 123123
    # ApiBoot Security 相关配置
    security:
      users:
        - username: yuqiyu
          password: 123456
由于 api-boot-starter-security-oauth-jwt依赖是 Spring SecurityOAuth2的整合,所以我们想要获取 AccessToken需要配置 Spring Security的用户列表,即 api.boot.security.users参数,默认同样是内存方式存储,详见: ApiBoot实现零代码整合Spring Security & OAuth2

运行测试

通过XxxApplication方式启动本章项目,通过Curl命令测试获取AccessToken,如下所示:

➜  ~ curl -X POST minbox:chapter@localhost:8080/oauth/token -d 'grant_type=password&username=yuqiyu&password=123456'
{"access_token":"bf2d67b8-c7a4-4f5c-846e-a6f1c7e44a9d","token_type":"bearer","refresh_token":"522507a2-30e5-4d86-a997-c991c3cb0807","expires_in":7191,"scope":"api"}

在上面命令行中,我们通过minbox:chapter客户端进行测试获取AccessToken,接下来我们验证是否两个客户端都已经生效,下面使用hengboy:123123客户端尝试:

➜  ~ curl -X POST hengboy:123123@localhost:8080/oauth/token -d 'grant_type=password&username=yuqiyu&password=123456'                    
{"access_token":"62b8da93-27cd-4963-8612-8e94036c4d78","token_type":"bearer","refresh_token":"4e516a7f-db52-4f40-ab92-c6b43cd62294","expires_in":7200,"scope":"api"}

根据输出来看,是可以获取到AccessToken的,多客户端配置都已经生效。

敲黑板,划重点

其实ApiBoot Security OAuth有很多配置都可以组合使用,不过跨越存储方式的配置有的是无法相互组合使用的,比如:当你使用Jdbc方式来存储认证信息时,即使我们配置了api.boot.oauth.clients参数,这时也是没有任何作用的,因为使用数据库方式来读取客户端信息时,OAuth2通过JdbcClientDetailsService类从数据库的oauth_client_details表内查询客户端列表,我们如果想要添加客户端,这时就需要向oauth_client_details表内添加一条数据。

代码示例

如果您喜欢本篇文章请为源码仓库点个Star,谢谢!!!
本篇文章示例源码可以通过以下途径获取,目录为apiboot-oauth-multiple-client-config

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
9天前
|
缓存 监控 NoSQL
阿里面试让聊一聊Redis 的内存淘汰(驱逐)策略
大家好,我是 V 哥。粉丝小 A 面试阿里时被问到 Redis 的内存淘汰策略问题,特此整理了一份详细笔记供参考。Redis 的内存淘汰策略决定了在内存达到上限时如何移除数据。希望这份笔记对你有所帮助!欢迎关注“威哥爱编程”,一起学习与成长。
|
5天前
|
JSON NoSQL Java
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
这篇文章介绍了在Java中使用Redis客户端的几种方法,包括Jedis、SpringDataRedis和SpringBoot整合Redis的操作。文章详细解释了Jedis的基本使用步骤,Jedis连接池的创建和使用,以及在SpringBoot项目中如何配置和使用RedisTemplate和StringRedisTemplate。此外,还探讨了RedisTemplate序列化的两种实践方案,包括默认的JDK序列化和自定义的JSON序列化,以及StringRedisTemplate的使用,它要求键和值都必须是String类型。
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
|
9天前
|
存储 Prometheus NoSQL
Redis 内存突增时,如何定量分析其内存使用情况
【9月更文挑战第21天】当Redis内存突增时,可采用多种方法分析内存使用情况:1)使用`INFO memory`命令查看详细内存信息;2)借助`redis-cli --bigkeys`和RMA工具定位大键;3)利用Prometheus和Grafana监控内存变化;4)优化数据类型和存储结构;5)检查并调整内存碎片率。通过这些方法,可有效定位并解决内存问题,保障Redis稳定运行。
|
2月前
|
存储 NoSQL 算法
Redis内存回收
Redis 基于内存存储,性能卓越,但单节点内存不宜过大,以免影响持久化或主从同步。可通过配置 `maxmemory` 限制最大内存。内存达到上限时,Redis采用两种策略:内存过期策略和内存淘汰策略。过期策略包括惰性删除和周期删除,后者分为 SLOW 和 FAST 模式。内存淘汰策略有八种,如 LRU、LFU 和随机淘汰等,用于在内存不足时释放空间。官方推荐使用 LFU 算法。
Redis内存回收
|
2天前
|
缓存 NoSQL 算法
14)Redis 在内存用完时会怎么办?如何处理已过期的数据?
14)Redis 在内存用完时会怎么办?如何处理已过期的数据?
7 0
|
2天前
|
存储 缓存 NoSQL
Redis 过期删除策略与内存淘汰策略的区别及常用命令解析
Redis 过期删除策略与内存淘汰策略的区别及常用命令解析
9 0
|
2月前
|
NoSQL Redis 容器
【Azure Cache for Redis】Redis的导出页面无法配置Storage SAS时通过az cli来完成
【Azure Cache for Redis】Redis的导出页面无法配置Storage SAS时通过az cli来完成
|
2月前
|
NoSQL 网络协议 Linux
【AKS+Redis】AKS中客户端(ioredis)遇见Azure Redis服务Failover后链接中断的可能性
【AKS+Redis】AKS中客户端(ioredis)遇见Azure Redis服务Failover后链接中断的可能性
|
2月前
|
NoSQL 网络协议 Linux
【Azure Redis】Lettuce客户端遇见连接Azure Redis长达15分钟的超时
【Azure Redis】Lettuce客户端遇见连接Azure Redis长达15分钟的超时
|
2月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。