oauth2.0通过JdbcClientDetailsService从数据库读取相应的配置

Posted panchanggui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oauth2.0通过JdbcClientDetailsService从数据库读取相应的配置相关的知识,希望对你有一定的参考价值。

 

oauth2.0通过JdbcClientDetailsService从数据库读取相应的配置

在上一节我们讲述的配置是把授权码存储在redis中,把相应的请求的路径用使用in-memory存储 ,这个是放在了内存中,但是实际开发我们的数据希望是从数据表中查询的,那应该怎么做呢?

1.回顾in-memory存储

/**
         * inMemory是存储到内存中 并未到数据库
         */
        clients.inMemory()
                //client Id
                .withClient("normal-app")
                .authorizedGrantTypes("authorization_code", "implicit")
                .authorities("ROLE_CLIENT")
                .scopes("read","write")
                .resourceIds(resourceId)
                .accessTokenValiditySeconds(accessTokenValiditySeconds)//授权码存活时间
                .and()
                .withClient("trusted-app")
                .authorizedGrantTypes("client_credentials", "password")
                .authorities("ROLE_TRUSTED_CLIENT")
                .scopes("read", "write")
                .resourceIds(resourceId)
                .accessTokenValiditySeconds(accessTokenValiditySeconds)
                .secret("secret");

如果使用的是这种方式,我们对应的授权码的请求路径如下:

http://localhost:8787/oauth/authorize?client_id=normal-app&response_type=code&scope=read&redirect_uri=/resources/user

相应的参数请对照上

然后我们使用的是jwt的令牌方式,相应的请求路径如下:

http://localhost:8787/oauth/token?code=r8YBUL&grant_type=authorization_code&client_id=normal-app&redirect_uri=/resources/user

这个是放在内存中的存储方式

2.如果我需要从数据库读取相应的字段的参数 可如下配置:

  @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

        //默认值InMemoryTokenStore对于单个服务器是完全正常的(即,在发生故障的情况下,低流量和热备份备份服务器)。大多数项目可以从这里开始,也可以在开发模式下运行,以便轻松启动没有依赖关系的服务器。
        //这JdbcTokenStore是同一件事的JDBC版本,它将令牌数据存储在关系数据库中。如果您可以在服务器之间共享数据库,则可以使用JDBC版本,如果只有一个,则扩展同一服务器的实例,或者如果有多个组件,则授权和资源服务器。要使用JdbcTokenStore你需要“spring-jdbc”的类路径。

        //这个地方指的是从jdbc查出数据来存储
        clients.withClientDetails(clientDetails());


    }

这里可以看到我们是把之前的从内存读取的方式给去掉了,取而代之的是clientDetails()这个方法,然后我们看下这个方法:

 @Bean
    public ClientDetailsService clientDetails() {
        return new JdbcClientDetailsService(dataSource);
    }

只需配置这个bean即可 但是我们的datasource是在yml配置文件中配置好了的,只需要注入:

import javax.sql.DataSource;
@Resource
private DataSource dataSource;

使用DataSource注解需要引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
 

但是这里还没完,我们首先要讲下JdbcClientDetailsService是如何从数据库读取的,我们可以点击进入查看相应的源码,如下所示:

public JdbcClientDetailsService(DataSource dataSource) {
        this.updateClientDetailsSql = DEFAULT_UPDATE_STATEMENT;
        this.updateClientSecretSql = "update oauth_client_details set client_secret = ? where client_id = ?";
        this.insertClientDetailsSql = "insert into oauth_client_details (client_secret, resource_ids, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove, client_id) values (?,?,?,?,?,?,?,?,?,?,?)";
        this.selectClientDetailsSql = "select client_id, client_secret, resource_ids, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove from oauth_client_details where client_id = ?";
        this.passwordEncoder = NoOpPasswordEncoder.getInstance();
        Assert.notNull(dataSource, "DataSource required");
        this.jdbcTemplate = new JdbcTemplate(dataSource);
        this.listFactory = new DefaultJdbcListFactory(new NamedParameterJdbcTemplate(this.jdbcTemplate));
    }

我们可以看到,他自己是有一个默认的字段的表的,里面有相应的查询的方法,所以我们需要建立一个这样的表,sql如下:

-- ----------------------------
-- Table structure for oauth_client_details 将请求的路径存在数据表
-- ----------------------------
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;

这个是默认的类的表,一般用它默认的即可,我们这边就需要根据以上的字段配置相关的内容,如下:

技术图片

image.png

这里配置好了之后我们的访问路径为:

//步骤:客户端向认证服务器申请令牌
http://localhost:8787/oauth/token?client_id=normal-app&grant_type=authorization_code&code=1oCj8e&redirect_uri=http://localhost:8787/resources/user

然后令牌的访问路径为:

//拿到令牌后访问资源:
http://localhost:8787/resources/user?access_token=9d62c7b0-780e-4c6a-ad5a-56d79a089342

记得code要换成上一步生成的code

 

以上是关于oauth2.0通过JdbcClientDetailsService从数据库读取相应的配置的主要内容,如果未能解决你的问题,请参考以下文章

通过 Oauth2.0 向 Google Latitude API 发送用户新位置

授权命令行工具使用 Google API(通过 OAuth2.0 或其他任何方式)

通过OAuth2.0 获取授权访问SF 用户数据

实现 OAuth2.0 的简单示例 [关闭]

实现 OAuth2.0 的简单示例 [关闭]

oauth2.0通过JdbcClientDetailsService从数据库读取相应的配置