【问题标题】:Springboot with Spring OAuth2使用 Spring OAuth2 的 Spring Boot
【发布时间】:2018-01-05 19:27:43
【问题描述】:

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

我可以生成令牌,当我向http://localhost:8080/oauth/token 发出 POST 请求时,我会收到如下有效响应:

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

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

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

除了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,以防它有助于找出为什么没有令牌保留在数据库中。

<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>

我的问题是,为什么生成的令牌没有被持久化到 mysql 数据库中,我该如何解决?

【问题讨论】:

  • (1) 您声明自己的DataSource bean 是否有特殊原因? (2) 不要指定application.properties——这是默认值,如果要覆盖它,请在启动时执行。 (3) 你确定你的AppConfig 正在加载吗? (在 tokenStore 方法中放置一个断点。)
  • (1) 我正在学习教程,他们创建了自己的DataSource,我也尝试引导应用程序。 (2) 如果我没有指定它,AppConfig 由于某种我不知道的原因不会被加载。 (3) 是的,它已加载。 tokenStore 上的断点已加载/命中 - 指定 application.properties 否则断点未加载/命中

标签: java spring spring-boot spring-security oauth


【解决方案1】:

默认情况下,配置了内存令牌存储。如果你想在重启之间保留令牌,那么你需要配置一个持久令牌存储​​。

请找到以下工作示例。 : https://github.com/spring-projects/spring-security-oauth/tree/master/tests/annotation/jdbc

【讨论】:

    【解决方案2】:

    Spring Security OAuth 2 默认使用令牌存储的内存实现,参见OAuth 2 Developers Guide

    在创建AuthorizationServerTokenServices 实现时,您可能需要考虑使用DefaultTokenServices,它有许多可以插入的策略来更改访问令牌的格式和存储。默认情况下,它通过随机值创建令牌并处理除了它委托给TokenStore 的令牌的持久性之外的所有内容。默认存储是内存中的实现,但还有其他一些可用的实现。以下是对它们中的每一个的一些讨论的描述

    • 默认的InMemoryTokenStore 非常适合单台服务器(即低流量并且在发生故障时不会热交换到备份服务器)。大多数项目都可以从这里开始,并且可能在开发模式下以这种方式运行,以便轻松启动没有依赖关系的服务器。

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

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

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

    【讨论】:

      猜你喜欢
      • 2017-09-11
      • 2017-02-12
      • 2018-08-13
      • 2020-10-25
      • 1970-01-01
      • 2022-11-03
      • 1970-01-01
      • 2017-08-01
      • 2019-02-10
      相关资源
      最近更新 更多