1

问题陈述: java.sql.SQLSyntaxErrorException: 无法连接到地址=(host=127.0.0.1)(port=3306)(type=master) : (conn=1058) Access denied for user ''@'localhost' to database 'my-db' 用户在启动期间不可用。

保险柜配置:

vault write database/config/my-db \     
plugin_name=mysql-database-plugin \
connection_url="{{username}}:{{password}}@tcp(127.0.0.1:3306)/" \                                                     
allowed_roles="healthy-role-r-wr" \
username="root" \
password="myrootpassword"

vault write database/roles/healthy-role-r-wr \
db_name=my-db \
creation_statements="CREATE USER '{{name}}'@'localhost' IDENTIFIED BY '{{password}}'; GRANT ALL PRIVILEGES ON my-db.* TO '{{name}}'@'localhost'; FLUSH PRIVILEGES;" \default_ttl="1h" \
max_ttl="24h"

我不得不提到主机@localhost,但在测试mysql命令时我无法连接到mysql。

vault read database/creds/healthy-role-r-wr                                
Key                Value
---                -----
lease_id           database/creds/healthy-role-r-wr/DugI5aIeYPUg0lmjtcNSM87L
lease_duration     1h
lease_renewable    true
password           C1yN7Tl-00XlwkOwbFCh
username           v_root_healthy-ro_7nl7RPTqb6QkAJ

mysql -uv_root_healthy-ro_7nl7RPTqb6QkAJ -pC1yN7Tl-00XlwkOwbFCh my-db

MariaDB [my-db]> select count(*) from my_table;
1 row in set (0.025 sec)

看来 Vault 的配置是正确的。

应用程序.yml

spring:
  application:
    name: my-springboot-app
  cloud:
    vault:
      host: 127.0.0.1
      port: 8200
      scheme: http
      authentication: token
      token: TOKEN
      generic:
        enabled: true
      database:
        backend: mysql
      kv:
        enabled: true
        backend: tcds/kv/my-springboot-app
        application-name: my-springboot-app
  config:
    import: vault://secret/my-springboot-app
  datasource:
    url: jdbc:mariadb://127.0.0.1:3306/my-db
    driver-class-name: org.mariadb.jdbc.Driver
    platform: mariadb
    role: healthy-role-r-wr
    #username: ${dbusername} 
    #password: ${dbpassword}
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update

聚甲醛:

<parent>
<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.4</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>11</java.version>
    <spring-cloud.version>2020.0.1</spring-cloud.version>
</properties>

依赖项:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-vault-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-vault-config-databases</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>org.mariadb.jdbc</groupId>
    <artifactId>mariadb-java-client</artifactId>
</dependency>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

在保险库中,我创建了一个秘密,本质上是使用用户名和密码创建一个 KV,如上面的 application.yml 所示。如果我像这样通过:

#username: ${dbusername}
#password: ${dbpassword}

然后应用程序干净启动,我可以调用 API 来获取用户列表。但这不是它应该的方式。由于用户名和密码是动态生成的,并且必须由应用程序使用。

似乎我缺少一些配置,因为 Spring Boot 应用程序可以识别保险库并且可以与之通信,只是它无法找到读取动态凭据的方法。

4

2 回答 2

0

您创建的角色应列在 spring.cloud.vault.database 下,如下所示

database:
  enabled: true
  role: healthy-role-r-wr
  backend: database # not mysql as you have it in your config

如果您想深入了解它,我已经详细制作了一个视频。

于 2021-11-02T12:57:13.393 回答
0

您的问题听起来与我遇到的问题相似,并且已经解决了几天,所以我在这里发帖以防它对您或其他任何人有帮助。

如果您将用户名和/或密码存储在您的 kv 中,其属性名称与数据库插件将动态加载的名称匹配,则将存在具有相同键的重复属性加载器,并且 kv 值将优先。

例如,在我的情况下,我已经完成了

vault kv put secret/foo spring.datasource.password=wrongpassword

(数据库插件用来加载密码的默认密钥是spring.datasource.password

虽然我可以打电话

vault read database/creds/some-role

并获得有效的凭据,当我运行我的 SpringBoot 应用程序时,我发现正在使用的密码是 kv 值。调试时,我看到这是由于属性加载器优先级。

如果您清除数据库插件将使用的任何键/值对的 kv,它应该使用您定义的角色生成的动态凭据。

另外,我的理解是,要配置数据源,您需要一个 bootstrap.yml 文件,其中包含您的保管库信息来修改 SpringBoot 应用程序的启动行为。

spring:
   application:
      name: <app name>
   cloud:
      vault:
         database:
            enabled: true
            role: <role>
            backend: database
         host: <host>
         port: <port>
         scheme: https
         authentication: token
         token: <your vault token>
         uri: <vault URL>

这个其他答案对我也有帮助。它让我可以看到我的应用程序的属性值spring cloud - bootstrap.properties 在我的 jar 之外

于 2021-07-12T17:38:52.990 回答