启动期间,Spring启动MariaDB vault用户名凭据不可用



问题语句:java.sql.SQLSyntaxErrorException:无法连接到地址=(host=127.0.0.1((port=3306((type=master(:(conn=1058(拒绝用户'''localhost'访问数据库'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"

我不得不提到host@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配置正确。

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

POM:

<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应用程序可以识别vault,并且可以与它通信,只是它无法找到读取动态凭据的方法。

你的问题听起来与我遇到的问题相似,我已经处理了几天了,所以我在这里发帖,以防对你或其他人有帮助。

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

例如,在我的案例中,我做了

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

(DB插件用于从中加载密码的密码的默认密钥是spring.datasource.password(

虽然我可以打电话给

vault read database/creds/some-role

当我运行SpringBoot应用程序时,我发现使用的密码是kv值。在调试时,我发现这是由于属性加载程序的优先级造成的。

如果您清除了DB插件将使用的任何密钥/值对的kv,那么它应该使用您定义的角色生成的动态凭据。

此外,我的理解是,要配置数据源,您需要一个bootstrap.yml文件,该文件将包含您的vault信息,以修改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>

另一个答案对我也很有帮助。它允许我在我的jar 之外查看我的应用程序的属性值spring-cloud-bootstrap.properties

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

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

如果你想深入了解,我已经为此制作了一个详细的视频。

最新更新