现在有一个项目,客户要求在配置文件中的数据库连接信息是密文的,当时还以为很是个简单的事。但是这个由于项目使用到了Spring框架,而对数据库的连接信息是在Spring启动时就装入内存的,因此要在加载后对文件进行解密,几乎不太可能。后面分析了Spring 的源码,发现Spring属性文件的加载都是通过PropertyPlaceholderConfigurer 里面的loadProperties(Properties props)方法实现的,因此想到了重载此类,并且复写loadProperties(Properties props)方法来实现对加密文件的解密,并在这个方法中将明文传递给Spring框架。
1.编写类一个属性文件加载类,此类重载PropertyPlaceholderConfigurer
public class DecryptPropertyPlaceholderConfigurer extends
PropertyPlaceholderConfigurer {
private Resource[] locations;
private Resource keyLocation;
private String fileEncoding;
public void setKeyLocation(Resource keyLocation) {
this.keyLocation = keyLocation;
}
public void setLocations(Resource[] locations) {
this.locations = locations;
}
public void setFileEncoding(String fileEncoding) {
this.fileEncoding = fileEncoding;
}
public void loadProperties(Properties props) throws IOException {
if (this.locations != null) {
PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();
for (int i = 0; i < this.locations.length; i++) {
Resource location = this.locations[i];
if (logger.isInfoEnabled()) {
logger.info("Loading properties file from " + location);
}
InputStream is = null;
try {
is = location.getInputStream();
Key key = DESEncryptUtil.getKey(keyLocation
.getInputStream());
if (location.getFilename().startsWith("key")) {
key = DESEncryptUtil.getKey(location.getInputStream());
}
if (location.getFilename().startsWith("acl")) {
is = DESEncryptUtil.doDecrypt(key, is);
}
if (this.fileEncoding != null) {
propertiesPersister.load(props, new InputStreamReader(
is, this.fileEncoding));
} else {
propertiesPersister.load(props, is);
}
} finally {
if (is != null)
is.close();
}
}
}
}
}
注:红色部分是加解密工具类,考虑到加解密的方法很多,读者可以自己编写适合自己应用的 。
2.在Spring配置文件中引如上面的类
<bean id="placeholderConfig"
class="com.tminfo.system.common.DecryptPropertyPlaceholderConfigurer"
lazy-init="default" autowire="default" dependency-check="default">
<property name="locations">
<list>
<value>classpath:db.properties</value>
<value>classpath:acl.properties</value>
</list>
</property>
<property name="keyLocation">
<value>classpath:key.properties</value>
</property>
</bean>
如有问题可以留言讨论。