问题陈述: 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 应用程序可以识别保险库并且可以与之通信,只是它无法找到读取动态凭据的方法。