Skip to content

JNDI数据库连接密码加密

  • 修改context.xml(src/main/webapp/META-INF文件夹下),其中factory指定了自定义数据源工厂的相对路径,password即为加密后的密码

    xml
    <?xml version="1.0" encoding="UTF-8"?>
    <Context>
          <Resource
                name="jdbc/mysql"
                auth="Container"
                type="javax.sql.DataSource"
                maxActive="100"
                maxIdle="30"
                maxWait="10000"
                username="root"
                password="cm9vdA=="
                factory="com.zhl.demo.factory.DataSourceSecurityFactory"
                driverClassName="com.mysql.jdbc.Driver"
                url="jdbc:mysql://localhost:3306/dbname" />
    </Context>
  • 自定义数据源工厂:实现BasicDataSourceFactory类并重写getObjectInstance方法

    java
    package com.zhl.demo.factory;
    
    import com.zhl.demo.util.CryptoUtil;
    import org.apache.commons.dbcp2.BasicDataSource;
    import org.apache.commons.dbcp2.BasicDataSourceFactory;
    
    import javax.naming.Context;
    import javax.naming.Name;
    import java.util.Hashtable;
    
    public class DataSourceSecurityFactory extends BasicDataSourceFactory {
        @Override
        public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
            Object o = super.getObjectInstance(obj, name, nameCtx, environment);
            if (o != null) {
                BasicDataSource ds = (BasicDataSource) o;
                if (ds.getPassword() != null && ds.getPassword().length() > 0) {
                    // 密码解密逻辑
                    String pwd = CryptoUtil.decrypt_Base64(ds.getPassword());
                    ds.setPassword(pwd);
                }
                return ds;
            } else {
                return null;
            }
        }
    }
  • 加解密工具类:以BASE64加解密为例

    xml
    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.12</version>
    </dependency>
    java
    package com.zhl.demo.util;
    
    import org.apache.commons.codec.binary.Base64;
    
    public class CryptoUtil {
        /***
         * Base64加密
         * @param str 需要加密的参数
         * @return
         * @throws Exception
         */
        public static String encrypt_Base64(String str) throws Exception {
            byte[] result = Base64.encodeBase64Chunked(str.getBytes("UTF-8"));
            //String result = Base64.getEncoder().encodeToString(str.getBytes("UTF-8"));
            return new String(result);
        }
    
        /***
         * Base64解密
         * @param str 需要解密的参数
         * @return
         * @throws Exception
         */
        public static String decrypt_Base64(String str) throws Exception {
            byte[] asBytes = Base64.decodeBase64(str.getBytes());
            //byte[] asBytes = Base64.getDecoder().decode(str);
            String result = new String(asBytes,"UTF-8");
            return result;
        }
    
        public static void main(String[] args) throws Exception {
            String encryptedPassword = encrypt_Base64("root");
            System.out.println(encryptedPassword); // cm9vdA==
        }
    }
  • 项目启动时,解密结果正确

    image-20250520110650190

上述改造是基于 SSM项目JNDI配置 改动的

项目地址 sso-demo

MIT版权,未经许可禁止任何形式的转载