赞
踩
公司规范要求配置文件里不能出现明文的密码。最近项目引入了Nacos作为服务的配置中心,使用的是spring-cloud-starter-alibaba-nacos-config
这个包。
基本的bootstrap.yaml
配置如下:
- spring:
- cloud:
- nacos:
- config:
- server-addr: <host>:<port>
- prefix: application
- group: shared
- namespace: xxx
- file-extension: yaml
- username: user
- password: plain_text_password
- ......
那么如何将spring.cloud.nacos.config.password
换为公司内部加密算法加密后的密码呢?
打开spring-cloud-starter-alibaba-nacos-config
的jar包,我们可以在META-INF/spring.factories
这个文件中看到以下内容:
- org.springframework.cloud.bootstrap.BootstrapConfiguration=\
- com.alibaba.cloud.nacos.NacosConfigBootstrapConfiguration
- ......
Nacos在Spring Cloud的bootstrap阶段可以进行自动配置就是在这里指定的。接下来找到NacosConfigBootstrapConfiguration
这个类,发现它获取配置的地方如下:
- @Configuration(proxyBeanMethods = false)
- @ConditionalOnProperty(name = "spring.cloud.nacos.config.enabled", matchIfMissing = true)
- public class NacosConfigBootstrapConfiguration {
-
- @Bean
- @ConditionalOnMissingBean
- public NacosConfigProperties nacosConfigProperties() {
- return new NacosConfigProperties();
- }
- ......
- }
我们可以注意到,它的配置读取靠的是NacosConfigProperties
这个类,而且在注入的方法上还添加了@ConditionalOnMissingBean
,这就给我们自定义配置读取提供了可能。
按图索骥,我们观察NacosConfigProperties
的实现:
- @ConfigurationProperties(NacosConfigProperties.PREFIX)
- public class NacosConfigProperties {
-
- public static final String PREFIX = "spring.cloud.nacos.config";
-
- ......
-
- @Autowired
- @JsonIgnore
- private Environment environment;
-
- @PostConstruct
- public void init() {
- this.overrideFromEnv();
- }
-
- private void overrideFromEnv() {
- if (StringUtils.isEmpty(this.getServerAddr())) {
- String serverAddr = environment
- .resolvePlaceholders("${spring.cloud.nacos.config.server-addr:}");
- if (StringUtils.isEmpty(serverAddr)) {
- serverAddr = environment.resolvePlaceholders(
- "${spring.cloud.nacos.server-addr:localhost:8848}");
- }
- this.setServerAddr(serverAddr);
- }
- if (StringUtils.isEmpty(this.getUsername())) {
- this.setUsername(
- environment.resolvePlaceholders("${spring.cloud.nacos.username:}"));
- }
- if (StringUtils.isEmpty(this.getPassword())) {
- this.setPassword(
- environment.resolvePlaceholders("${spring.cloud.nacos.password:}"));
- }
- }
- ......
- }
这里的后处理方法init
调用了一个从Spring Environment中读取配置的overrideFromEnv
。我的想法简单粗暴,即继承这个NacosConfigProperties
,重写init,在调用完父类方法之后执行公司的密码解密逻辑。因为这已经是在bean的后处理方法中添加的逻辑了,可以说是最后一道配置处理。
话不多说,实现自己的配置类CustomNacosConfigProperties
。
- @ConfigurationProperties(NacosConfigProperties.PREFIX)
- public class CustomNacosConfigProperties extends NacosConfigProperties {
-
- @Override
- @PostConstruct
- public void init() {
- super.init();
- if (!StringUtils.isEmpty(this.getPassword())) {
- // 调用你的密码解密逻辑
- this.setPassword(yourDecryptAlgorithm(this.getPassword()));
- }
- }
- }
接下来我们需要将默认的配置类替换成我们自己的实现,编写一个CustomNacosBootstrapAutoConfig
。
- @Configuration
- @ConditionalOnProperty(name = "spring.cloud.nacos.config.enabled", matchIfMissing = true)
- @Order(Ordered.HIGHEST_PRECEDENCE)
- public class CustomNacosBootstrapAutoConfig {
-
- @Bean
- @ConditionalOnMissingBean
- public NacosConfigProperties nacosConfigProperties() {
- return new CustomNacosConfigProperties();
- }
- }
我们使用@Order(Ordered.HIGHEST_PRECEDENCE)
注解来保证这个配置类优先于Nacos默认的NacosConfigBootstrapConfiguration
。这样一来,Spring容器中的NacosConfigProperties
bean就替换成了能自动解密密码的实现。
之后,我们需要将CustomNacosBootstrapAutoConfig
注册到Spring Cloud的bootstrap流程中。在自己项目里创建一个文件resources/META-INF/spring.factories
,内容:
- org.springframework.cloud.bootstrap.BootstrapConfiguration=\
- your.package.CustomNacosBootstrapAutoConfig
最后,我们只需将bootstrap.yaml
中的spring.cloud.nacos.config.password
配置项换为加密后的密码即可。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。