如何在Spring Cloud中实现Nacos客户端登录密码加密

Bluの妙妙天地 2024-07-14 08:09:00 阅读 65

背景

公司规范要求配置文件里不能出现明文的密码。最近项目引入了Nacos作为服务的配置中心,使用的是<code>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容器中的NacosConfigPropertiesbean就替换成了能自动解密密码的实现。

最后,我们只需将bootstrap.yaml中的spring.cloud.nacos.config.password配置项换为加密后的密码即可。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。