嵌入式自配置Spring-如果配置包含加密条目,Cloud-Config 服务器启动失败
Embedded self-configuring Spring-Cloud-Config server startup fails if configuration contains encrypted entries
我目前正在使用 Spring-Cloud-Config 并在尝试 运行 嵌入式配置服务器从其存储库配置自身时偶然发现了一个问题。
一切正常,直到我将加密值添加到服务器的配置文件中。一旦我这样做,服务器启动就会失败并出现以下异常:
java.lang.IllegalStateException: Cannot decrypt: key=config-server.test.prop
at org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer.decrypt(EnvironmentDecryptApplicationInitializer.java:201) ~[spring-cloud-context-1.1.5.RELEASE.jar:1.1.5.RELEASE]
at org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer.decrypt(EnvironmentDecryptApplicationInitializer.java:165) ~[spring-cloud-context-1.1.5.RELEASE.jar:1.1.5.RELEASE]
at org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer.initialize(EnvironmentDecryptApplicationInitializer.java:95) ~[spring-cloud-context-1.1.5.RELEASE.jar:1.1.5.RELEASE]
at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:635) [spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:349) [spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:313) [spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186) [spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175) [spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
at test.configserver.Application.main(Application.java:13) [classes/:na]
Caused by: java.lang.UnsupportedOperationException: No decryption for FailsafeTextEncryptor. Did you configure the keystore correctly?
at org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration$FailsafeTextEncryptor.decrypt(EncryptionBootstrapConfiguration.java:152) ~[spring-cloud-context-1.1.5.RELEASE.jar:1.1.5.RELEASE]
at org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer.decrypt(EnvironmentDecryptApplicationInitializer.java:193) ~[spring-cloud-context-1.1.5.RELEASE.jar:1.1.5.RELEASE]
... 8 common frames omitted
密钥库配置应该是正确的,因为加密值是使用服务器的 /encrypt
端点创建的。
此外,当我启动嵌入式服务器时其配置中没有加密值,然后更改配置添加
加密值,服务器检测配置更改并调用 /<name>/<profile>
显示正确解密的值。
我的测试应用程序如下所示:
Application.java
@SpringBootApplication
@EnableConfigServer
public class Application {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
bootstrap.yml
server:
port: 8888
spring:
application:
name: config-server
cloud:
config:
server:
bootstrap: true
git:
uri: file:///config_server/repo
application.yml
encrypt:
keyStore:
location: classpath:/configserver.jks
alias: configserver
(encrypt.keyStore.password
通过 -D
选项设置)
有效的示例配置
config-server:
test:
prop: testvalue
使服务器失败的示例配置
config-server:
test:
prop: '{cipher}AQBsAuCDKbDgmFMkxcNPbbDMiLq4SZbBgrHX73KSBJAgisTC2O3iTxXyHhY1MWxXhuzYX4EMy2v9enV3iY3IQz4O2GprO/GjQSggW+jHE1TV7MOcvH01nvg6SUKDkAmWHQqWiqQI0G9NPp2KzOHNcMeKm+q8wbvwFSBhA4A8y8F+++mgC8XK1Kc942jepppI17dCSV25/+iUrDDVdBv6rAqu2D9eyuTZmLl6Q2/SLOGBc+Il8B8L3ylyDHrBdQD92C0aAdh6HcY5Jze1wQSNSxTIzT3nKi22DTF69ilwq9SPz5re4Hm+Y1S+be10wHh34L+fdexrdcpFz9ApqsSKDv2TzXiTCNJIKo3xsOWb6QVIL1DjyKexPri/FZWtBu4EX0dWY2OxiMDmkFf+xVIkE4kw'
我在 Java 8 上使用 Spring-Framework 4.3.4,Spring-Boot 1.4.2 和 Spring-Cloud Camden.SR2。 =36=]
编辑
要设置示例项目来重现问题,只需使用上述 Application.java
、bootstrap.yml
和 application.yml
.
的代码片段
这里是项目的pom.xml
:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>config-server</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>config-server</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<compiler-plugin.version>3.5.1</compiler-plugin.version>
<spring-framework.version>4.3.4.RELEASE</spring-framework.version>
<spring-boot.version>1.4.2.RELEASE</spring-boot.version>
<spring-cloud.version>Camden.SR2</spring-cloud.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring-framework.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
</project>
对于 git 存储库,只需创建一个文件夹,在其中调用 git init
并添加一个名为 config-server.yml
的文件,其中包含描述的示例配置作为内容。
可以使用 keytool
生成密钥库,如 Spring-Cloud-Config docs 中所述(对于我的测试,我没有设置 -secret
)。
然后您应该能够从 IDE 启动项目并访问 localhost:8888
上的配置服务器。
重现问题的步骤
启动配置服务器
curl localhost:8888/config-server/default
- 应该输出添加到 git repo
的配置
加密一个值:curl localhost:8888/encrypt -d test
将加密值添加到config-server.yml(前缀为{cipher}
并用单引号括起来)
curl localhost:8888/config-server/default
- 应该输出解密后的值
重新启动配置服务器 - 失败并出现错误
将密钥库加密配置放入bootstrap.yml。
我目前正在使用 Spring-Cloud-Config 并在尝试 运行 嵌入式配置服务器从其存储库配置自身时偶然发现了一个问题。 一切正常,直到我将加密值添加到服务器的配置文件中。一旦我这样做,服务器启动就会失败并出现以下异常:
java.lang.IllegalStateException: Cannot decrypt: key=config-server.test.prop
at org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer.decrypt(EnvironmentDecryptApplicationInitializer.java:201) ~[spring-cloud-context-1.1.5.RELEASE.jar:1.1.5.RELEASE]
at org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer.decrypt(EnvironmentDecryptApplicationInitializer.java:165) ~[spring-cloud-context-1.1.5.RELEASE.jar:1.1.5.RELEASE]
at org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer.initialize(EnvironmentDecryptApplicationInitializer.java:95) ~[spring-cloud-context-1.1.5.RELEASE.jar:1.1.5.RELEASE]
at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:635) [spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:349) [spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:313) [spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186) [spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175) [spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
at test.configserver.Application.main(Application.java:13) [classes/:na]
Caused by: java.lang.UnsupportedOperationException: No decryption for FailsafeTextEncryptor. Did you configure the keystore correctly?
at org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration$FailsafeTextEncryptor.decrypt(EncryptionBootstrapConfiguration.java:152) ~[spring-cloud-context-1.1.5.RELEASE.jar:1.1.5.RELEASE]
at org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer.decrypt(EnvironmentDecryptApplicationInitializer.java:193) ~[spring-cloud-context-1.1.5.RELEASE.jar:1.1.5.RELEASE]
... 8 common frames omitted
密钥库配置应该是正确的,因为加密值是使用服务器的 /encrypt
端点创建的。
此外,当我启动嵌入式服务器时其配置中没有加密值,然后更改配置添加
加密值,服务器检测配置更改并调用 /<name>/<profile>
显示正确解密的值。
我的测试应用程序如下所示:
Application.java
@SpringBootApplication
@EnableConfigServer
public class Application {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
bootstrap.yml
server:
port: 8888
spring:
application:
name: config-server
cloud:
config:
server:
bootstrap: true
git:
uri: file:///config_server/repo
application.yml
encrypt:
keyStore:
location: classpath:/configserver.jks
alias: configserver
(encrypt.keyStore.password
通过 -D
选项设置)
有效的示例配置
config-server:
test:
prop: testvalue
使服务器失败的示例配置
config-server:
test:
prop: '{cipher}AQBsAuCDKbDgmFMkxcNPbbDMiLq4SZbBgrHX73KSBJAgisTC2O3iTxXyHhY1MWxXhuzYX4EMy2v9enV3iY3IQz4O2GprO/GjQSggW+jHE1TV7MOcvH01nvg6SUKDkAmWHQqWiqQI0G9NPp2KzOHNcMeKm+q8wbvwFSBhA4A8y8F+++mgC8XK1Kc942jepppI17dCSV25/+iUrDDVdBv6rAqu2D9eyuTZmLl6Q2/SLOGBc+Il8B8L3ylyDHrBdQD92C0aAdh6HcY5Jze1wQSNSxTIzT3nKi22DTF69ilwq9SPz5re4Hm+Y1S+be10wHh34L+fdexrdcpFz9ApqsSKDv2TzXiTCNJIKo3xsOWb6QVIL1DjyKexPri/FZWtBu4EX0dWY2OxiMDmkFf+xVIkE4kw'
我在 Java 8 上使用 Spring-Framework 4.3.4,Spring-Boot 1.4.2 和 Spring-Cloud Camden.SR2。 =36=]
编辑
要设置示例项目来重现问题,只需使用上述 Application.java
、bootstrap.yml
和 application.yml
.
这里是项目的pom.xml
:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>config-server</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>config-server</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<compiler-plugin.version>3.5.1</compiler-plugin.version>
<spring-framework.version>4.3.4.RELEASE</spring-framework.version>
<spring-boot.version>1.4.2.RELEASE</spring-boot.version>
<spring-cloud.version>Camden.SR2</spring-cloud.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring-framework.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
</project>
对于 git 存储库,只需创建一个文件夹,在其中调用 git init
并添加一个名为 config-server.yml
的文件,其中包含描述的示例配置作为内容。
可以使用 keytool
生成密钥库,如 Spring-Cloud-Config docs 中所述(对于我的测试,我没有设置 -secret
)。
然后您应该能够从 IDE 启动项目并访问 localhost:8888
上的配置服务器。
重现问题的步骤
启动配置服务器
curl localhost:8888/config-server/default
- 应该输出添加到 git repo 的配置
加密一个值:
curl localhost:8888/encrypt -d test
将加密值添加到config-server.yml(前缀为
{cipher}
并用单引号括起来)curl localhost:8888/config-server/default
- 应该输出解密后的值重新启动配置服务器 - 失败并出现错误
将密钥库加密配置放入bootstrap.yml。