文章目录
- 原由:
- 方法一:PropertyPlaceholderConfigurer
- 方法二:DruidPasswordCallback
- 小结
原由:
提示:最近,公司内部开始项目安全方面的整改,其中有写老项目是SSM的,其中数据库的一些配置信息直接写在config.properties文件里面,还是明文,所以需要将密码改成加密后的字符串,话不多说,直接上方案。
加密解密的方法我就不写了,网上很多工具类
方法一:PropertyPlaceholderConfigurer
提示:PropertyPlaceholderConfigurer
是spring中用来读取配置文件信息中的类
- 配置文件config.properties
jdbc.url=jdbc:mysql:/127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
# 加密后的数据库密码
jdbc.password=4220c1f30cdbf9c54dd5ccd5d71857bc1111
- java实现PropertyPlaceholderConfigurer
public class EncryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
public EncryptPropertyPlaceholderConfigurer() {
}
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException {
try {
String password = props.getProperty("jdbc.password");
if (password != null) {
// 将加密的password解密后塞到props, 加密解密方法是我自定义的
String decrypt = Cryptos.aesDecrypt(password);
logger.info("password:" + decrypt);
props.setProperty("jdbc.password", decrypt);
}
} catch (Exception e) {
e.printStackTrace();
}
super.processProperties(beanFactory, props);
}
}
- 配置文件指定EncryptPropertyPlaceholderConfigurer
<!--class填写刚才那段代码的类路径-->
<bean
class="com.**********.EncryptPropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:config.properties</value>
</property>
</bean>
- 结论:
这个方案在大部分项目里面是可以,而且网上这个解决方案也是主流吗,但公司有个项目不行,只能使用方案二。
方法二:DruidPasswordCallback
提示:公司有个比较来就的项目,spring用的还是4.3版本的,用方法已发现不行,方法一中props.setProperty执行了,但是DruidAbstractDataSource读取的数据库密码还是加密过后的字符串
- 配置文件config.properties
jdbc.url=jdbc:mysql:/127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
# 加密后的数据库密码
jdbc.password=4220c1f30cdbf9c54dd5ccd5d71857bc1111
- java实现DruidPasswordCallback
public class DBPasswordCallback extends DruidPasswordCallback {
@Override
public void setProperties(Properties properties) {
super.setProperties(properties);
//获取配置文件中加密后的密码,和xml中的connectionProperties属性配置相关
String password = (String) properties.get("password");
try {
//解密过程,自定义解密方法
String dbpassword= Cryptos.aesDecrypt(password);
//设置密码
setPassword(dbpassword.toCharArray());
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 配置文件指定EncryptPropertyPlaceholderConfigurer
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${jdbc.driver}"/>
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${jdbc.pool.init}"/>
<property name="minIdle" value="${jdbc.pool.minIdle}"/>
<property name="maxActive" value="${jdbc.pool.maxActive}"/>
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000"/>
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000"/>
<!-- 超过时间限制是否回收 -->
<property name="removeAbandoned" value="true"/>
<!-- 超时时间;单位为秒。180秒=3分钟 -->
<property name="removeAbandonedTimeout" value="1200"/>
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true"/>
<property name="validationQuery" value="${jdbc.testSql}"/>
<property name="testWhileIdle" value="true"/>
<property name="testOnBorrow" value="false"/>
<property name="testOnReturn" value="false"/>
<!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用)
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> -->
<!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat"/>
<!-- 这里是重点 -->
<property name="connectionProperties" value="password=${jdbc.password}"/>
<property name="passwordCallback" ref="dbPasswordCallback"/>
</bean>
<!-- 自定义的设置数据库密码类 -->
<bean id = "dbPasswordCallback" class="com.*******.DBPasswordCallback"/>
小结
spring版本的不同,也影响了解决方案。