美文网首页ApiBoot 核心技术Spring Boot 核心技术Springboot
OAuth2在内存、Redis、JDBC方式下的多客户端配置

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

作者: 恒宇少年 | 来源:发表于2020-01-01 10:02 被阅读0次

    知识改变命运,撸码使我快乐,祝大家2020年元旦快乐!!!

    点赞再看,养成习惯

    本篇文章对应源码码云(Gitee)仓库

    https://gitee.com/minbox-projects/api-boot-chapter,您的Star是给我最大动力

    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

    作者个人 博客
    使用开源框架 ApiBoot 助你成为Api接口服务架构师

    相关文章

      网友评论

        本文标题:OAuth2在内存、Redis、JDBC方式下的多客户端配置

        本文链接:https://www.haomeiwen.com/subject/uruwoctx.html