Commit ef4a293f39226a685820ec3418783ec8d6279e1d

Authored by zhangdaiscott
1 parent 33adbc52

HW21-0499 表字典接口存在SQL注入漏洞,增加签名拦截器

online表单数据源配置,数据库类型识别错误 #2671
ant-design-vue-jeecg/src/api/manage.js
1 1 import Vue from 'vue'
2 2 import { axios } from '@/utils/request'
  3 +import signMd5Utils from '@/utils/encryption/signMd5Utils'
3 4  
4 5 const api = {
5 6 user: '/mock/api/user',
... ... @@ -13,19 +14,29 @@ export default api
13 14  
14 15 //post
15 16 export function postAction(url,parameter) {
  17 + let sign = signMd5Utils.getSign(url, parameter);
  18 + //将签名和时间戳,添加在请求接口 Header
  19 + let signHeader = {"X-Sign": sign,"X-TIMESTAMP": signMd5Utils.getDateTimeToString()};
  20 +
16 21 return axios({
17 22 url: url,
18 23 method:'post' ,
19   - data: parameter
  24 + data: parameter,
  25 + headers: signHeader
20 26 })
21 27 }
22 28  
23 29 //post method= {post | put}
24 30 export function httpAction(url,parameter,method) {
  31 + let sign = signMd5Utils.getSign(url, parameter);
  32 + //将签名和时间戳,添加在请求接口 Header
  33 + let signHeader = {"X-Sign": sign,"X-TIMESTAMP": signMd5Utils.getDateTimeToString()};
  34 +
25 35 return axios({
26 36 url: url,
27 37 method:method ,
28   - data: parameter
  38 + data: parameter,
  39 + headers: signHeader
29 40 })
30 41 }
31 42  
... ... @@ -40,10 +51,15 @@ export function putAction(url,parameter) {
40 51  
41 52 //get
42 53 export function getAction(url,parameter) {
  54 + let sign = signMd5Utils.getSign(url, parameter);
  55 + //将签名和时间戳,添加在请求接口 Header
  56 + let signHeader = {"X-Sign": sign,"X-TIMESTAMP": signMd5Utils.getDateTimeToString()};
  57 +
43 58 return axios({
44 59 url: url,
45 60 method: 'get',
46   - params: parameter
  61 + params: parameter,
  62 + headers: signHeader
47 63 })
48 64 }
49 65  
... ...
ant-design-vue-jeecg/src/utils/encryption/signMd5Utils.js 0 → 100644
  1 +import md5 from 'md5'
  2 +//签名密钥串(前后端要一致,正式发布请自行修改)
  3 +const signatureSecret = "dd05f1c54d63749eda95f9fa6d49v442a";
  4 +
  5 +export default class signMd5Utils {
  6 + /**
  7 + * json参数升序
  8 + * @param jsonObj 发送参数
  9 + */
  10 +
  11 + static sortAsc(jsonObj) {
  12 + let arr = new Array();
  13 + let num = 0;
  14 + for (let i in jsonObj) {
  15 + arr[num] = i;
  16 + num++;
  17 + }
  18 + let sortArr = arr.sort();
  19 + let sortObj = {};
  20 + for (let i in sortArr) {
  21 + sortObj[sortArr[i]] = jsonObj[sortArr[i]];
  22 + }
  23 + return sortObj;
  24 + }
  25 +
  26 +
  27 + /**
  28 + * @param url 请求的url,应该包含请求参数(url的?后面的参数)
  29 + * @param requestParams 请求参数(POST的JSON参数)
  30 + * @returns {string} 获取签名
  31 + */
  32 + static getSign(url, requestParams) {
  33 + let urlParams = this.parseQueryString(url);
  34 + let jsonObj = this.mergeObject(urlParams, requestParams);
  35 + //console.log("sign jsonObj: ",jsonObj)
  36 + let requestBody = this.sortAsc(jsonObj);
  37 + console.log("sign requestBody: ",requestBody)
  38 + return md5(JSON.stringify(requestBody) + signatureSecret).toUpperCase();
  39 + }
  40 +
  41 + /**
  42 + * @param url 请求的url
  43 + * @returns {{}} 将url中请求参数组装成json对象(url的?后面的参数)
  44 + */
  45 + static parseQueryString(url) {
  46 + let urlReg = /^[^\?]+\?([\w\W]+)$/,
  47 + paramReg = /([^&=]+)=([\w\W]*?)(&|$|#)/g,
  48 + urlArray = urlReg.exec(url),
  49 + result = {};
  50 +
  51 + // 获取URL上最后带逗号的参数变量 sys/dict/getDictItems/sys_user,realname,username
  52 + let lastpathVariable = url.substring(url.lastIndexOf('/') + 1);
  53 + if(lastpathVariable.includes(",")){
  54 + if(lastpathVariable.includes("?")){
  55 + lastpathVariable = lastpathVariable.substring(0, lastpathVariable.indexOf("?"));
  56 + }
  57 + result["x-path-variable"] = lastpathVariable;
  58 + }
  59 + if (urlArray && urlArray[1]) {
  60 + let paramString = urlArray[1], paramResult;
  61 + while ((paramResult = paramReg.exec(paramString)) != null) {
  62 + //数字值转为string类型,前后端加密规则保持一致
  63 + if(this.myIsNaN(paramResult[2])){
  64 + paramResult[2] = paramResult[2].toString()
  65 + }
  66 + result[paramResult[1]] = paramResult[2];
  67 + }
  68 + }
  69 + return result;
  70 + }
  71 +
  72 + /**
  73 + * @returns {*} 将两个对象合并成一个
  74 + */
  75 + static mergeObject(objectOne, objectTwo) {
  76 + if (objectTwo && Object.keys(objectTwo).length > 0) {
  77 + for (let key in objectTwo) {
  78 + if (objectTwo.hasOwnProperty(key) === true) {
  79 + //数字值转为string类型,前后端加密规则保持一致
  80 + if(this.myIsNaN(objectTwo[key])){
  81 + objectTwo[key] = objectTwo[key].toString()
  82 + }
  83 + objectOne[key] = objectTwo[key];
  84 + }
  85 + }
  86 + }
  87 + return objectOne;
  88 + }
  89 +
  90 + static urlEncode(param, key, encode) {
  91 + if (param == null) return '';
  92 + let paramStr = '';
  93 + let t = typeof (param);
  94 + if (t == 'string' || t == 'number' || t == 'boolean') {
  95 + paramStr += '&' + key + '=' + ((encode == null || encode) ? encodeURIComponent(param) : param);
  96 + } else {
  97 + for (let i in param) {
  98 + let k = key == null ? i : key + (param instanceof Array ? '[' + i + ']' : '.' + i);
  99 + paramStr += this.urlEncode(param[i], k, encode);
  100 + }
  101 + }
  102 + return paramStr;
  103 + };
  104 +
  105 + static getDateTimeToString() {
  106 + const date_ = new Date()
  107 + const year = date_.getFullYear()
  108 + let month = date_.getMonth() + 1
  109 + let day = date_.getDate()
  110 + if (month < 10) month = '0' + month
  111 + if (day < 10) day = '0' + day
  112 + let hours = date_.getHours()
  113 + let mins = date_.getMinutes()
  114 + let secs = date_.getSeconds()
  115 + const msecs = date_.getMilliseconds()
  116 + if (hours < 10) hours = '0' + hours
  117 + if (mins < 10) mins = '0' + mins
  118 + if (secs < 10) secs = '0' + secs
  119 + if (msecs < 10) secs = '0' + msecs
  120 + return year + '' + month + '' + day + '' + hours + '' + mins + '' + secs
  121 + }
  122 + // true:数值型的,false:非数值型
  123 + static myIsNaN(value) {
  124 + return typeof value === 'number' && !isNaN(value);
  125 + }
  126 +
  127 +}
0 128 \ No newline at end of file
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/DateUtils.java
... ... @@ -291,7 +291,7 @@ public class DateUtils extends PropertyEditorSupport {
291 291 Date dt = new Date();
292 292 DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
293 293 String nowTime = df.format(dt);
294   - java.sql.Timestamp buydate = java.sql.Timestamp.valueOf(nowTime);
  294 + Timestamp buydate = Timestamp.valueOf(nowTime);
295 295 return buydate;
296 296 }
297 297  
... ... @@ -616,6 +616,10 @@ public class DateUtils extends PropertyEditorSupport {
616 616 return 0;
617 617 }
618 618  
  619 + public static Long getCurrentTimestamp() {
  620 + return Long.valueOf(DateUtils.yyyymmddhhmmss.get().format(new Date()));
  621 + }
  622 +
619 623 /**
620 624 * String类型 转换为Date, 如果参数长度为10 转换格式”yyyy-MM-dd“ 如果参数长度为19 转换格式”yyyy-MM-dd
621 625 * HH:mm:ss“ * @param text String类型的时间值
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/interceptor/SignAuthConfiguration.java 0 → 100644
  1 +package org.jeecg.config.sign.interceptor;
  2 +
  3 +import org.springframework.context.annotation.Bean;
  4 +import org.springframework.context.annotation.Configuration;
  5 +import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
  6 +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  7 +
  8 +/**
  9 + * online 拦截器配置
  10 + */
  11 +@Configuration
  12 +public class SignAuthConfiguration implements WebMvcConfigurer {
  13 +
  14 + @Bean
  15 + public SignAuthInterceptor signAuthInterceptor() {
  16 + return new SignAuthInterceptor();
  17 + }
  18 +
  19 + @Override
  20 + public void addInterceptors(InterceptorRegistry registry) {
  21 + String[] inculudes = new String[] {"/sys/dict/getDictItems/*", "/sys/dict/loadDict/*",
  22 + "/sys/dict/loadDictOrderByValue/*", "/sys/dict/loadDictItem/*", "/sys/dict/loadTreeData",
  23 + "/sys/api/queryTableDictItemsByCode", "/sys/api/queryFilterTableDictInfo", "/sys/api/queryTableDictByKeys",
  24 + "/sys/api/translateDictFromTable", "/sys/api/translateDictFromTableByKeys"};
  25 + registry.addInterceptor(signAuthInterceptor()).addPathPatterns(inculudes);
  26 + }
  27 +}
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/interceptor/SignAuthInterceptor.java 0 → 100644
  1 +package org.jeecg.config.sign.interceptor;
  2 +
  3 +
  4 +import java.io.PrintWriter;
  5 +import java.util.SortedMap;
  6 +
  7 +import javax.servlet.http.HttpServletRequest;
  8 +import javax.servlet.http.HttpServletResponse;
  9 +
  10 +import org.jeecg.common.api.vo.Result;
  11 +import org.jeecg.common.util.DateUtils;
  12 +import org.jeecg.config.sign.util.BodyReaderHttpServletRequestWrapper;
  13 +import org.jeecg.config.sign.util.HttpUtils;
  14 +import org.jeecg.config.sign.util.SignUtil;
  15 +import org.springframework.web.servlet.HandlerInterceptor;
  16 +
  17 +import com.alibaba.fastjson.JSON;
  18 +
  19 +import lombok.extern.slf4j.Slf4j;
  20 +
  21 +/**
  22 + * 签名拦截器
  23 + * @author qinfeng
  24 + */
  25 +@Slf4j
  26 +public class SignAuthInterceptor implements HandlerInterceptor {
  27 + /**
  28 + * 5分钟有效期
  29 + */
  30 + private final static long MAX_EXPIRE = 5 * 60;
  31 +
  32 + @Override
  33 + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  34 + log.debug("request URI = " + request.getRequestURI());
  35 + HttpServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(request);
  36 + //获取全部参数(包括URL和body上的)
  37 + SortedMap<String, String> allParams = HttpUtils.getAllParams(requestWrapper);
  38 + //对参数进行签名验证
  39 + String headerSign = request.getHeader("X-Sign");
  40 + String timesTamp = request.getHeader("X-TIMESTAMP");
  41 +
  42 + //1.校验时间有消息
  43 + try {
  44 + DateUtils.parseDate(timesTamp, "yyyyMMddHHmmss");
  45 + } catch (Exception e) {
  46 + throw new IllegalArgumentException("签名验证失败:X-TIMESTAMP格式必须为:yyyyMMddHHmmss");
  47 + }
  48 + Long clientTimestamp = Long.parseLong(timesTamp);
  49 + //判断时间戳 timestamp=201808091113
  50 + if ((DateUtils.getCurrentTimestamp() - clientTimestamp) > MAX_EXPIRE) {
  51 + throw new IllegalArgumentException("签名验证失败:X-TIMESTAMP已过期");
  52 + }
  53 +
  54 + //2.校验签名
  55 + boolean isSigned = SignUtil.verifySign(allParams,headerSign);
  56 +
  57 + if (isSigned) {
  58 + log.debug("Sign 签名通过!Header Sign : {}",headerSign);
  59 + return true;
  60 + } else {
  61 + log.error("request URI = " + request.getRequestURI());
  62 + log.error("Sign 签名校验失败!Header Sign : {}",headerSign);
  63 +// //打印日志参数
  64 +// Set<String> keySet = allParams.keySet();
  65 +// Iterator<String> paramIt = keySet.iterator();
  66 +// while(paramIt.hasNext()){
  67 +// String pkey = paramIt.next();
  68 +// String pval = allParams.get(pkey);
  69 +// log.error(" ["+pkey+":"+pval+"] ");
  70 +// }
  71 +
  72 + //校验失败返回前端
  73 + response.setCharacterEncoding("UTF-8");
  74 + response.setContentType("application/json; charset=utf-8");
  75 + PrintWriter out = response.getWriter();
  76 + Result<?> result = Result.error("Sign签名校验失败!");
  77 + out.print(JSON.toJSON(result));
  78 + return false;
  79 + }
  80 + }
  81 +
  82 +}
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/util/BodyReaderHttpServletRequestWrapper.java 0 → 100644
  1 +package org.jeecg.config.sign.util;
  2 +
  3 +import javax.servlet.ReadListener;
  4 +import javax.servlet.ServletInputStream;
  5 +import javax.servlet.ServletRequest;
  6 +import javax.servlet.http.HttpServletRequest;
  7 +import javax.servlet.http.HttpServletRequestWrapper;
  8 +import java.io.*;
  9 +import java.nio.charset.Charset;
  10 +
  11 +/**
  12 + * 保存过滤器里面的流
  13 + *
  14 + * @author show
  15 + * @date 10:03 2019/5/30
  16 + */
  17 +public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
  18 +
  19 + private final byte[] body;
  20 +
  21 + public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) {
  22 +
  23 + super(request);
  24 + String sessionStream = getBodyString(request);
  25 + body = sessionStream.getBytes(Charset.forName("UTF-8"));
  26 + }
  27 +
  28 + /**
  29 + * 获取请求Body
  30 + *
  31 + * @param request
  32 + * @return
  33 + */
  34 + public String getBodyString(final ServletRequest request) {
  35 +
  36 + StringBuilder sb = new StringBuilder();
  37 + try (InputStream inputStream = cloneInputStream(request.getInputStream());
  38 + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")))) {
  39 + String line;
  40 + while ((line = reader.readLine()) != null) {
  41 + sb.append(line);
  42 + }
  43 + } catch (IOException e) {
  44 + e.printStackTrace();
  45 + }
  46 + return sb.toString();
  47 + }
  48 +
  49 + /**
  50 + * Description: 复制输入流</br>
  51 + *
  52 + * @param inputStream
  53 + * @return</br>
  54 + */
  55 + public InputStream cloneInputStream(ServletInputStream inputStream) {
  56 +
  57 + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
  58 + byte[] buffer = new byte[1024];
  59 + int len;
  60 + try {
  61 + while ((len = inputStream.read(buffer)) > -1) {
  62 + byteArrayOutputStream.write(buffer, 0, len);
  63 + }
  64 + byteArrayOutputStream.flush();
  65 + } catch (IOException e) {
  66 + e.printStackTrace();
  67 + }
  68 + return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
  69 + }
  70 +
  71 + @Override
  72 + public BufferedReader getReader() {
  73 +
  74 + return new BufferedReader(new InputStreamReader(getInputStream()));
  75 + }
  76 +
  77 + @Override
  78 + public ServletInputStream getInputStream() {
  79 +
  80 + final ByteArrayInputStream bais = new ByteArrayInputStream(body);
  81 + return new ServletInputStream() {
  82 +
  83 + @Override
  84 + public int read() {
  85 +
  86 + return bais.read();
  87 + }
  88 +
  89 + @Override
  90 + public boolean isFinished() {
  91 +
  92 + return false;
  93 + }
  94 +
  95 + @Override
  96 + public boolean isReady() {
  97 +
  98 + return false;
  99 + }
  100 +
  101 + @Override
  102 + public void setReadListener(ReadListener readListener) {
  103 +
  104 + }
  105 + };
  106 + }
  107 +}
0 108 \ No newline at end of file
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/util/HttpUtils.java 0 → 100644
  1 +package org.jeecg.config.sign.util;
  2 +
  3 +import java.io.BufferedReader;
  4 +import java.io.IOException;
  5 +import java.io.InputStreamReader;
  6 +import java.io.UnsupportedEncodingException;
  7 +import java.net.URLDecoder;
  8 +import java.util.HashMap;
  9 +import java.util.Map;
  10 +import java.util.SortedMap;
  11 +import java.util.TreeMap;
  12 +
  13 +import javax.servlet.http.HttpServletRequest;
  14 +
  15 +import org.jeecg.common.util.oConvertUtils;
  16 +import org.springframework.http.HttpMethod;
  17 +
  18 +import com.alibaba.fastjson.JSONObject;
  19 +
  20 +/**
  21 + * http 工具类 获取请求中的参数
  22 + *
  23 + * @author show
  24 + * @date 14:23 2019/5/29
  25 + */
  26 +public class HttpUtils {
  27 +
  28 + /**
  29 + * 将URL的参数和body参数合并
  30 + *
  31 + * @author show
  32 + * @date 14:24 2019/5/29
  33 + * @param request
  34 + */
  35 + public static SortedMap<String, String> getAllParams(HttpServletRequest request) throws IOException {
  36 +
  37 + SortedMap<String, String> result = new TreeMap<>();
  38 + // 获取URL上最后带逗号的参数变量 sys/dict/getDictItems/sys_user,realname,username
  39 + String pathVariable = request.getRequestURI().substring(request.getRequestURI().lastIndexOf("/")+1);
  40 + if(pathVariable.contains(",")){
  41 + result.put(SignUtil.xPathVariable,pathVariable);
  42 + }
  43 + // 获取URL上的参数
  44 + Map<String, String> urlParams = getUrlParams(request);
  45 + for (Map.Entry entry : urlParams.entrySet()) {
  46 + result.put((String)entry.getKey(), (String)entry.getValue());
  47 + }
  48 + Map<String, String> allRequestParam = new HashMap<>(16);
  49 + // get请求不需要拿body参数
  50 + if (!HttpMethod.GET.name().equals(request.getMethod())) {
  51 + allRequestParam = getAllRequestParam(request);
  52 + }
  53 + // 将URL的参数和body参数进行合并
  54 + if (allRequestParam != null) {
  55 + for (Map.Entry entry : allRequestParam.entrySet()) {
  56 + result.put((String)entry.getKey(), (String)entry.getValue());
  57 + }
  58 + }
  59 + return result;
  60 + }
  61 +
  62 + /**
  63 + * 获取 Body 参数
  64 + *
  65 + * @author show
  66 + * @date 15:04 2019/5/30
  67 + * @param request
  68 + */
  69 + public static Map<String, String> getAllRequestParam(final HttpServletRequest request) throws IOException {
  70 +
  71 + BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
  72 + String str = "";
  73 + StringBuilder wholeStr = new StringBuilder();
  74 + // 一行一行的读取body体里面的内容;
  75 + while ((str = reader.readLine()) != null) {
  76 + wholeStr.append(str);
  77 + }
  78 + // 转化成json对象
  79 + return JSONObject.parseObject(wholeStr.toString(), Map.class);
  80 + }
  81 +
  82 + /**
  83 + * 将URL请求参数转换成Map
  84 + *
  85 + * @author show
  86 + * @param request
  87 + */
  88 + public static Map<String, String> getUrlParams(HttpServletRequest request) {
  89 + Map<String, String> result = new HashMap<>(16);
  90 + if(oConvertUtils.isEmpty(request.getQueryString())){
  91 + return result;
  92 + }
  93 + String param = "";
  94 + try {
  95 + param = URLDecoder.decode(request.getQueryString(), "utf-8");
  96 + } catch (UnsupportedEncodingException e) {
  97 + e.printStackTrace();
  98 + }
  99 + String[] params = param.split("&");
  100 + for (String s : params) {
  101 + int index = s.indexOf("=");
  102 + result.put(s.substring(0, index), s.substring(index + 1));
  103 + }
  104 + return result;
  105 + }
  106 +}
0 107 \ No newline at end of file
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/util/SignUtil.java 0 → 100644
  1 +package org.jeecg.config.sign.util;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import lombok.extern.slf4j.Slf4j;
  5 +import org.springframework.util.DigestUtils;
  6 +import org.springframework.util.StringUtils;
  7 +
  8 +import java.util.SortedMap;
  9 +
  10 +/**
  11 + * 签名工具类
  12 + *
  13 + * @author show
  14 + * @date 10:01 2019/5/30
  15 + */
  16 +@Slf4j
  17 +public class SignUtil {
  18 + //签名密钥串(前后端要一致,正式发布请自行修改)
  19 + private static final String signatureSecret = "dd05f1c54d63749eda95f9fa6d49v442a";
  20 + public static final String xPathVariable = "x-path-variable";
  21 +
  22 + /**
  23 + * @param params
  24 + * 所有的请求参数都会在这里进行排序加密
  25 + * @return 验证签名结果
  26 + */
  27 + public static boolean verifySign(SortedMap<String, String> params,String headerSign) {
  28 + if (params == null || StringUtils.isEmpty(headerSign)) {
  29 + return false;
  30 + }
  31 + // 把参数加密
  32 + String paramsSign = getParamsSign(params);
  33 + log.info("Param Sign : {}", paramsSign);
  34 + return !StringUtils.isEmpty(paramsSign) && headerSign.equals(paramsSign);
  35 + }
  36 +
  37 + /**
  38 + * @param params
  39 + * 所有的请求参数都会在这里进行排序加密
  40 + * @return 得到签名
  41 + */
  42 + public static String getParamsSign(SortedMap<String, String> params) {
  43 + //去掉 Url 里的时间戳
  44 + params.remove("_t");
  45 + String paramsJsonStr = JSONObject.toJSONString(params);
  46 + log.info("Param paramsJsonStr : {}", paramsJsonStr);
  47 + return DigestUtils.md5DigestAsHex((paramsJsonStr+signatureSecret).getBytes()).toUpperCase();
  48 + }
  49 +}
0 50 \ No newline at end of file
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/init/CodeGenerateDbConfig.java
1 1 package org.jeecg.config.init;
2 2  
  3 +import com.alibaba.druid.filter.config.ConfigTools;
3 4 import lombok.extern.slf4j.Slf4j;
4 5 import org.apache.commons.lang3.StringUtils;
5 6 import org.jeecgframework.codegenerate.database.CodegenDatasourceConfig;
... ... @@ -25,11 +26,21 @@ public class CodeGenerateDbConfig {
25 26 private String password;
26 27 @Value("${spring.datasource.dynamic.datasource.master.driver-class-name:}")
27 28 private String driverClassName;
  29 + @Value("${spring.datasource.dynamic.datasource.master.druid.public-key:}")
  30 + private String publicKey;
28 31  
29 32  
30 33 @Bean
31 34 public CodeGenerateDbConfig initCodeGenerateDbConfig() {
32 35 if(StringUtils.isNotBlank(url)){
  36 + if(StringUtils.isNotBlank(publicKey)){
  37 + try {
  38 + password = ConfigTools.decrypt(publicKey, password);
  39 + } catch (Exception e) {
  40 + e.printStackTrace();
  41 + log.error(" 代码生成器数据库连接,数据库密码解密失败!");
  42 + }
  43 + }
33 44 CodegenDatasourceConfig.initDbConfig(driverClassName,url, username, password);
34 45 log.info(" 代码生成器数据库连接,使用application.yml的DB配置 ###################");
35 46 }
... ...
jeecg-boot/pom.xml
... ... @@ -39,7 +39,7 @@
39 39 <shiro.version>1.7.1</shiro.version>
40 40 <java-jwt.version>3.11.0</java-jwt.version>
41 41 <shiro-redis.version>3.1.0</shiro-redis.version>
42   - <codegenerate.version>1.3.2</codegenerate.version>
  42 + <codegenerate.version>1.3.3</codegenerate.version>
43 43 <autopoi-web.version>1.3.2</autopoi-web.version>
44 44 <minio.version>8.0.3</minio.version>
45 45 <justauth-spring-boot-starter.version>1.3.4</justauth-spring-boot-starter.version>
... ...