返回介绍

15.7 客户端信息存入数据库

发布于 2025-04-26 13:16:51 字数 4184 浏览 0 评论 0 收藏

在 15.5.2.1 小节搭建的授权服务器中,客户端信息是直接存储在内存中的。然而在实际项目中,这种方式并不可取,一方面客户端信息无法实现动态添加与删除,另一方面硬编码的客户端信息也不好维护,所以我们需要将客户端信息存入数据库中。

涉及客户端信息保存的接口主要是 ClientDetailsService,这个接口主要有两个实现类,如图 15-18 所示。

图 15-18 ClientDetailsService 的实现类

InMemoryClientDetailsService 就是将客户端信息存入内存中,也就是我们之前案例所采用的存储方式;JdbcClientDetailsService 则是将客户端信息存入数据库中。

由于官方没有给出使用 JdbcClientDetailsService 存储客户端信息时的数据库脚本,所以我们可以根据 JdbcClientDetailsService 中定义的 SQL 来分析出数据库表结构。JdbcClientDetailsService 部分源码:

       private static final String CLIENT_FIELDS_FOR_UPDATE =
    "resource_ids, scope, "    + "authorized_grant_types, web_server_redirect_uri,
       authorities, access_token_validity, "+"refresh_token_validity,
                                                 additional_information, autoapprove";
       private static final String CLIENT_FIELDS = "client_secret, " +
                                                              CLIENT_FIELDS_FOR_UPDATE;

根据这两个属性就能确定数据库字段名,最终分析出来的 SQL 如下:

    DROP TABLE IF EXISTS `oauth_client_details`;
    CREATE TABLE `oauth_client_details` (
     `client_id` varchar(48) NOT NULL,
     `resource_ids` varchar(256) DEFAULT NULL,
     `client_secret` varchar(256) DEFAULT NULL,
     `scope` varchar(256) DEFAULT NULL,
     `authorized_grant_types` varchar(256) DEFAULT NULL,
     `web_server_redirect_uri` varchar(256) DEFAULT NULL,
     `authorities` varchar(256) DEFAULT NULL,
     `access_token_validity` int(11) DEFAULT NULL,
     `refresh_token_validity` int(11) DEFAULT NULL,
     `additional_information` varchar(4096) DEFAULT NULL,
     `autoapprove` varchar(256) DEFAULT NULL,
     PRIMARY KEY (`client_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

在数据库中执行该段 SQL 脚本,并将一开始配置在代码中的客户端信息录入数据库中,如图 15-19 所示。

图 15-19 客户端信息

然后在授权服务器 auth-server 中添加如下依赖:

    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
    </dependency>

在 application.properties 中配置一下数据库连接信息:

    spring.datasource.url=jdbc:mysql:///security15?useUnicode=true&characterEncod
ing=UTF-8&serverTimezone=Asia/Shanghai
    spring.datasource.password=123
    spring.datasource.username=root
    spring.main.allow-bean-definition-overriding=true

最后一条配置是允许 Bean 的覆盖,否则我们自己创建的 ClientDetailsService 将会和系统创建的 ClientDetailsService 实例相冲突。

接下来配置 ClientDetailsService 实例,代码如下:

    @EnableAuthorizationServer
    @Configuration
    public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
       @Autowired
       DataSource dataSource;
       @Bean
       ClientDetailsService clientDetailsService() {
           return new JdbcClientDetailsService(dataSource);
       }
       @Bean
       AuthorizationServerTokenServices tokenServices() {
           DefaultTokenServices services = new DefaultTokenServices();
           services.setClientDetailsService(clientDetailsService());
           services.setSupportRefreshToken(true);
           services.setTokenStore(tokenStore);
           return services;
       }
       @Override
       public void configure(ClientDetailsServiceConfigurer clients)
                                                                   throws Exception {
           clients.withClientDetails(clientDetailsService());
       }
       //省略其他
    }

和 15.5.2.1 小节中的案例相比,这里的变化主要在四个方面:

(1)注入 DataSource 实例。

(2)向 Spring 容器注册一个 JdbcClientDetailsService 实例。

(3)在 AuthorizationServerTokenServices 实例中除去令牌有效期设置,令牌有效期将从数据库中加载。

(4)在 configure(ClientDetailsServiceConfigurer) 方法中直接配置 JdbcClientDetailsService 实例即可,项目启动后会自动从数据库中加载客户端信息。

配置完成后,重启授权服务器再去进行授权测试即可。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。