java - Springboot 与 Spring OAuth2

标签 java spring spring-boot spring-security oauth

我正在使用 Spring Boot 和 Spring Security OAuth 以及 JDBC 客户端支持在我的应用程序上实现 OAuth2。

当我向 http://localhost:8080/oauth/token 发出 POST 请求时,我可以生成 token 我得到了一个有效的回复,例如:

{
    "access_token": "359e93b2-555a-477b-9a65-e5062314fc23",
    "token_type": "bearer",
    "refresh_token": "6fd1ae31-8129-4729-a86b-e756c453a58a",
    "expires_in": 899,
    "scope": "read"
}

现在奇怪的是,我在数据库中的任何地方都找不到这个 token 。如果我向/oauth/token 发出另一个请求,我会得到相同的 token ,但 expires_in 的值低于预期。我得出的结论是,这个 token 信息必须存储在某个地方,但我找不到它。

01:24:41    SELECT * FROM dummy.oauth_access_token LIMIT 0, 1000    0 row(s) returned   0.000 sec / 0.000 sec

除了具有用于生成 token 的客户端详细信息的 oauth_client_details 之外,所有 OAuth 相关表都是空的。

这是我的代码。

AuthServerOAuth2Config

@Configuration
public class AuthServerOAuth2Config extends AuthorizationServerConfigurerAdapter {

    private final AuthenticationManager authenticationManager;
    private final AppConfig appConfig;

    @Autowired
    public AuthServerOAuth2Config(AuthenticationManager authenticationManager, AppConfig appConfig) {
        this.authenticationManager = authenticationManager;
        this.appConfig = appConfig;
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(appConfig.dataSource());
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.checkTokenAccess("permitAll()");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
    }
}

AppConfig 类

@Configuration
@PropertySource(value = "classpath:application.properties")
public class AppConfig {

    @Value("${spring.datasource.url}")
    private String datasourceUrl;

    @Value("${spring.database.driverClassName}")
    private String dbDriverClassName;

    @Value("${spring.datasource.username}")
    private String dbUsername;

    @Value("${spring.datasource.password}")
    private String dbPassword;

    @Bean
    public DataSource dataSource() {
        final DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName(dbDriverClassName);
        dataSource.setUrl(datasourceUrl);
        dataSource.setUsername(dbUsername);
        dataSource.setPassword(dbPassword);

        return dataSource;
    }

    @Bean
    public TokenStore tokenStore() {
        return new JdbcTokenStore(dataSource());
    }
}

这是我的 pom.xml,以防它对查找数据库中没有持久化 token 的原因有任何帮助。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.6.RELEASE</version>
    <relativePath/>
    <!-- lookup parent from repository -->
</parent>
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <!-- Defining which version of Spring Framework we are using -->
    <spring-cloud.version>Dalston.SR1</spring-cloud.version>
</properties>

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-oauth2</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-aws-context</artifactId>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.6.1</version>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.4.0</version>
    </dependency>
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
    </dependency>
</dependencies>

我的问题是,为什么生成的 token 没有保存到 mysql 数据库中,如何修复它?

最佳答案

Spring Security OAuth 2 默认使用 token 存储的内存中实现,请参阅 OAuth 2 Developers Guide :

When creating your AuthorizationServerTokenServices implementation, you may want to consider using the DefaultTokenServices which has many strategies that can be plugged in to change the format and storage of access tokens. By default it creates tokens via random value and handles everything except for the persistence of the tokens which it delegates to a TokenStore. The default store is an in-memory implementation, but there are some other implementations available. Here's a description with some discussion of each of them

  • The default InMemoryTokenStore is perfectly fine for a single server (i.e. low traffic and no hot swap to a backup server in the case of failure). Most projects can start here, and maybe operate this way in development mode, to make it easy to start a server with no dependencies.

您可以使用AuthorizationServerEndpointsConfigurer#tokenStore更改 token 存储的使用实现。 .

您修改后的授权服务器端点配置:

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints
         .authenticationManager(authenticationManager)
         .tokenStore(appConfig.tokenStore());
}

关于java - Springboot 与 Spring OAuth2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45395305/

相关文章:

java - 如何在 Spring 为 ScheduledTimerTask 设置服务器时间?

java - Spring Boot bootJar mysql 驱动程序 impl 没有被 ServiceLoader 注入(inject)

spring-boot - 具有 Azure AD 安全性和 CORS 的 Spring Boot 3.0 不起作用,但在 Spring Boot 2.6 中起作用

java - 将许多 'if else' 语句转换为更简洁的方法

java - 复合组件监听器仅在页面重新加载后工作

java - 这是什么算法?盒装/背包?

java - 硬编码 SQL 语句 VS。用于执行查询的 Web 服务

java - 如何避免需要将相同的参数传递给所有方法?

java - 无法使用 Spring 创建 java.util.concurrent.ThreadPoolExecutor 的 bean

java - 如何验证@PathVariable是否已设置?