druiddatasource 动态修改密码参数____配置************可用 restart()

 

1. 注入

@Autowired

private DruidDataSource  druidDataSource   ;

 2.修改属性

druidDataSource .setPassword('newpassword');

druidDataSource .restart();

 

________________________________________________

 

1. 利用 DruidPasswordCallback 接口动态修改密码

Druid passwordcallback失效

springboot利用druid连接池做数据库密码加密

引入依赖

<dependency>

    <groupId>com.alibaba</groupId>

    <artifactId>druid</ artifactId>

    <version>1.1.21</version>

</ dependency> 


配置如下:

spring:

    datasource:

        driverClassName: com.mysql.cj.jdbc.Driver

        url: jdbc:mysql://127.0.0.1:3306/test

        username: root

        druid:

            connectionProperties: password=加密后的密码     #自定义加密方式

            passwordCallbackClassName: com.sgcc.psr.DBPasswordCallback #回调类的路径


回调类DBPasswordCallback 代码如下:

/** *需要继承DruidPasswordCallback 并重写setProperties 方法 **/

public class DBPasswordCallback extends DruidPasswordCallback {

@Override

public void setProperties(Properties properties) {

super.setProperties(properties);

//获取配置文件中加密后的密码,和xml中的connectionProperties属性配置相关

String password = (String) properties.get("password");

try {

//解密过程,ConfigTools为druid自带,提供一些好用的函数

String dbpassword= ConfigTools.decrypt(publicKey,password);

//设置密码

setPassword(dbpassword.toCharArray());

}catch (Exception e){

    e.printStackTrace();

        }

    }

}

启动失败,报错提示密码错误。

猜想是密码解密失败,进入到druid.jar断点调试,发现没有进入druidDatasource中的passwordCallback方法。

解决办法:

换成springboot集成的druid依赖

<dependency>

    <groupId>com.alibaba</groupId>

    <artifactId>druid-spring-boot-starter</ artifactId>

       <version>1.1.21</version>

</ dependency> 

 ______________________________________________________________________________________________________

 

2. 利用  datasource.init() 方法修改密码后重新初始化

Druid源码阅读1-DruidDataSource之init()

https://blog.csdn.net/suxiao_21/article/details/124679504

Druid源码阅读2-DruidDataSource的init过程

https://blog.csdn.net/dhaibo1986/article/details/121233998

  ______________________________________________________________________________________________________

 

动态密码修改参考方案:

//1.配置
new DBPasswordCallback(sourceKey, username)
package cn.com.wind.wstockactivity.infrastructure.core.database.mysqldatasource;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter;
import cn.com.wind.wstockactivity.infrastructure.core.database.DBPasswordCallback;
import cn.com.wind.wstockactivity.infrastructure.core.windtools.dbpwdService.PasswordServiceHelper;

@Configuration
public class MasterMySqlDataSourceConfig {
   
   @Value("${spring.datasource.master.sourceKey}")
   private String  sourceKey;
   
   @Value("${spring.datasource.master.jdbc-url}")
   private String  dbUrl;
   
   @Value("${spring.datasource.master.username}")
   private String  username;
   
   @Value("${spring.datasource.master.password}")
   private String  password;
   
   @Value("${spring.datasource.master.driver-class-name}")
   private String  driverClassName;
   
   @Value("${spring.datasource.master.initialSize}")
   private int     initialSize;
   
   @Value("${spring.datasource.master.minIdle}")
   private int     minIdle;
   
   @Value("${spring.datasource.master.maxActive}")
   private int     maxActive;
   
   @Value("${spring.datasource.master.maxWait}")
   private int     maxWait;
   
   @Value("${spring.datasource.master.timeBetweenEvictionRunsMillis}")
   private int     timeBetweenEvictionRunsMillis;
   
   @Value("${spring.datasource.master.minEvictableIdleTimeMillis}")
   private int     minEvictableIdleTimeMillis;
   
   @Value("${spring.datasource.master.validationQuery}")
   private String  validationQuery;
   
   @Value("${spring.datasource.master.testWhileIdle}")
   private boolean testWhileIdle;
   
   @Value("${spring.datasource.master.testOnBorrow}")
   private boolean testOnBorrow;
   
   @Value("${spring.datasource.master.testOnReturn}")
   private boolean testOnReturn;
   
   @Value("${spring.datasource.master.poolPreparedStatements}")
   private boolean poolPreparedStatements;
   
   @Value("${spring.datasource.master.maxPoolPreparedStatementPerConnectionSize}")
   private int     maxPoolPreparedStatementPerConnectionSize;
   
   @Value("${spring.datasource.master.filters}")
   private String  filters;
   
   @Value("${spring.datasource.master.connectionProperties}")
   private String  connectionProperties;
   
   @Value("${spring.datasource.master.useGlobalDataSourceStat}")
   private boolean useGlobalDataSourceStat;
   
   @Bean(name = "primaryMasterDataSource")
   // 声明其为Bean实例
   public DataSource dataSource() {       
       DruidDataSource datasource = new DruidDataSource();
       
       // 密码信息
       password = PasswordServiceHelper.getPassword(sourceKey, username);
       datasource.setUrl(this.dbUrl);
       datasource.setUsername(username);
       datasource.setPassword(password);
       datasource.setDriverClassName(driverClassName);
       datasource.setPasswordCallback(new DBPasswordCallback(sourceKey, username));
       
       // configuration
       datasource.setInitialSize(initialSize);
       datasource.setMinIdle(minIdle);
       datasource.setMaxActive(maxActive);
       datasource.setMaxWait(maxWait);
       datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
       datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
       datasource.setValidationQuery(validationQuery);
       datasource.setTestWhileIdle(testWhileIdle);
       datasource.setTestOnBorrow(testOnBorrow);
       datasource.setTestOnReturn(testOnReturn);
       datasource.setPoolPreparedStatements(poolPreparedStatements);
       datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
       datasource.setUseGlobalDataSourceStat(useGlobalDataSourceStat);
try {
           datasource.setFilters(filters);
       }
       catch (SQLException e) {
           System.err.println(" MasterMySqlDataSourceConfig, druid configuration initialization filter: " + e);
       }
       
       WallConfig wallconfig = new WallConfig();
       wallconfig.setMultiStatementAllow(true);// 允许多SQL
       wallconfig.setNoneBaseStatementAllow(true); // 允许非基础SQL
       
       WallFilter wallFilter = new WallFilter();
       wallFilter.setConfig(wallconfig);
       
       List<Filter> filterList = new ArrayList<Filter>();
       filterList.add(wallFilter);
       datasource.setProxyFilters(filterList);
       
       datasource.setConnectionProperties(connectionProperties);
       return datasource;
   }
   
   public String getSourceKey() {
       
       return sourceKey;
   }
   
   public String getUsername() {
       
       return username;
   }
}


//2.配置 DBPasswordCallback
package cn.com.wind.wstockactivity.infrastructure.core.database;
import java.util.Properties;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.druid.util.DruidPasswordCallback;
import cn.com.wind.wstockactivity.infrastructure.core.windtools.dbpwdService.PasswordServiceHelper;


public class DBPasswordCallback extends DruidPasswordCallback {
   
   private static final long serialVersionUID = 6540791084537255345L;
   
   private String            userName;
   
   private String            pwdDbName;
   
   private Logger            logger           = LoggerFactory.getLogger(getClass());
   
   public DBPasswordCallback(String pwdDbName, String userName) {

       this.pwdDbName = pwdDbName;
       this.userName = userName;

   }
   
   @Override
   public void setProperties(Properties properties) {
       
       super.setProperties(properties);
       String pwd = properties.getProperty("password");
       
       try {
           String cryptoPwd = PasswordServiceHelper.getLastedPassword(pwdDbName, userName);
           
           logger.info("Crypto " + cryptoPwd);
           
           if (StringUtils.isBlank(cryptoPwd)) {
               setPassword(pwd.toCharArray());
           }
           else {
               setPassword(cryptoPwd.toCharArray());
           }
           
       }
       catch (Exception e) {
           logger.error(e.getMessage());
           setPassword(pwd.toCharArray());
       }
       
   }
}

 

 

 

posted @ 2022-01-21 16:04  kelelipeng  阅读(1048)  评论(0编辑  收藏  举报