SpringBoot自定义注解API数据加密和签名校验

api数据数据签名(MD5,SHA1)

签名枚举类SginEnum.java

package com.jx.app.api.framework.annotation.enums;

/**
* @ClassName: SginEnum
* @Description: TODO(这是一个签名枚举类)
* @author gangyu
* @date 2018年11月20日 下午4:30:44
*/
public enum SginEnum {
 //0不需要签名,1使用MD5数据加密 2 使用SHA数据加密
 ANY(0), MD5(1), SHA1(2);
 private final int value;

 private SginEnum(int value) {
  this.value = value;
 }

 public int getValue() {
  return value;
 }
}

签名注解类SginAnot.java

/**
* @Title: SginAnot.java
* @Package com.jxkj.app.api.framework
* @Description: TODO(用一句话描述该文件做什么)
* @author gangyu
* @date 2018年11月20日 下午4:07:58
* @version V1.0
*/
package com.jx.app.api.framework.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.jx.app.api.framework.annotation.enums.SginEnum;

/**
* @ClassName: SginAnot
* @Description: TODO(签名验证注解)
* @author gangyu
* @date 2018年11月20日 下午4:07:58
*
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SginAnot {
 SginEnum type() default SginEnum.ANY;//默认不需要签名
}

加密工具类MD5.java

package com.jx.common.entrypt;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jx.common.utils.BeanUtil;
import com.jx.common.utils.TestEntity;

/**
 * @ClassName: MD5
 * @Description: TODO(MD5加密工具)
 * @author gangyu
 * @date 2018年11月20日 下午2:12:14
 *
 */
public class MD5 {

 private static final Logger log = LoggerFactory.getLogger(MD5.class);

 public static String PRIVATE_KEY = "这是你的密钥";

    private static final String hexDigIts[] = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};

 public static String encrypt(String plainText) {
  try {
   return encrypt(plainText,true);
  } catch (UnsupportedEncodingException e) {
   e.printStackTrace();
   log.error("MD5加密异常:",e);
   return null;
  }
 }

 /**
  * @Title: encrypt
  * @Description: TODO(16位或32位密码)
  * @param @param
  *            plainText
  * @param @param
  *            flag true为32位,false为16位
  * @throws UnsupportedEncodingException
  */
 public static String encrypt(String plainText, boolean flag) throws UnsupportedEncodingException {
  try {
   if (StringUtils.isEmpty(plainText)) {
    return null;
   }
   MessageDigest md = MessageDigest.getInstance("MD5");
            String encrStr = byteArrayToHexString(md.digest(plainText.getBytes("UTF-8")));
   if (flag)
    return encrStr;
   else
    return encrStr.substring(8, 24);
  } catch (NoSuchAlgorithmException e) {
   e.printStackTrace();
   return null;
  }

 }

 @SuppressWarnings("unchecked")
 public static String encrypt(Object obj){
  if(obj==null){
   return null;
  }
  Map<String, Object> map = new HashMap<String,Object>();
  if(obj instanceof Map){
   map=(Map<String, Object>) obj;
  }else{
   map = BeanUtil.transBean2Map(obj);
  }
  return encrypt(map,true);
 }

 /**
  * @Title: encrypt
  * @Description: TODO(16位或32位密码)
  * @param @param
  *            plainText
  * @param @param
  *            flag true为32位,false为16位
  * @throws UnsupportedEncodingException
  */
 public static String encrypt(Map<String, Object> map, boolean flag) {
  String param = null;
  map.remove("sign");
  map.remove("encrypt");
  String result = BeanUtil.mapOrderStr(map);
  if (StringUtils.isEmpty(result)) {
   return null;
  }
  param = encrypt(encrypt(result)+PRIVATE_KEY);
  if (flag) {
   return param;
  } else {
   param = param.substring(8, 24);
  }
  return param;
 }

 public static Map<String, Object> resultMap = new HashMap<String, Object>();
 @SuppressWarnings("unchecked")
 public static Map<String, Object> mapFn(Map<String, Object> map) {
  for (String key : map.keySet()) {
   if (map.get(key) != null && map.get(key) != "" && (!key.equals("BTYPE") && !key.equals("SIGN"))) {
    if (key.equals("INPUT")) {
     if (map.get(key) != null) {
      mapFn((Map<String, Object>) map.get(key));
     }
    } else {
     resultMap.put(key, map.get(key));
    }
   }
  }
  return resultMap;
 }

 @SuppressWarnings("unchecked")
 public static boolean check(Object obj){
  Map<String,Object> map=new HashMap<String,Object>();
  if(obj==null){
   return false;
  }
  if(obj instanceof Map){
   map=(Map<String, Object>) obj;
  }else{
   map = BeanUtil.transBean2Map(obj);
  }
  String sign=(String)map.get("sign");
  if(sign==null){
   return false;
  }
  String str=encrypt(obj);
  return sign.equals(str)?true:false;
 }

    public static String byteArrayToHexString(byte b[]){
        StringBuffer resultSb = new StringBuffer();
        for(int i = 0; i < b.length; i++){
            resultSb.append(byteToHexString(b[i]));
        }
        return resultSb.toString();
    }

    public static String byteToHexString(byte b){
        int n = b;
        if(n < 0){
            n += 256;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigIts[d1] + hexDigIts[d2];
    }

 public static void main(String[] args) throws UnsupportedEncodingException {
  TestEntity test = new TestEntity();
  test.setId("1");
  test.setAge("20");
  test.setClaes("你好");
  test.setName("gyu");
  test.setCreateTime("2018-11-20");
  test.setSign("5189bd815c3850395f30779d0e59229e");
  System.out.println("MD5验签成功:"+check(test));
 }

}

SHA加密工具类SHA1.java

package com.jx.common.entrypt;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jx.common.utils.BeanUtil;

/**
* @ClassName: Sha1Util
* @Description: TODO(SHA加密)
* @author gangyu
* @date 2018年11月20日 下午2:08:36
*
*/
public class Sha1 {
 private static final Logger log = LoggerFactory.getLogger(Sha1.class);
 public static String encrypt(String str){
     if (null == str || 0 == str.length()){
         return null;
     }
     char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
             'a', 'b', 'c', 'd', 'e', 'f'};
     try {
         MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
         mdTemp.update(new String(str.getBytes("iso8859-1"), "utf-8").getBytes());
         byte[] md = mdTemp.digest();
         int j = md.length;
         char[] buf = new char[j * 2];
         int k = 0;
         for (int i = 0; i < j; i++) {
             byte byte0 = md[i];
             buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
             buf[k++] = hexDigits[byte0 & 0xf];
         }
         return new String(buf);
     } catch (NoSuchAlgorithmException e) {
         e.printStackTrace();
   log.error("SHA1加密异常:",e);
     } catch (UnsupportedEncodingException e) {
         e.printStackTrace();
   log.error("SHA1加密异常:",e);
     }
  return str;
 }

 @SuppressWarnings("unchecked")
 public static String encrypt(Object obj) {
  if(obj==null){
   return null;
  }
  Map<String, Object> map = new HashMap<String,Object>();
  if(obj instanceof Map){
   map=(Map<String, Object>) obj;
  }else{
   map = BeanUtil.transBean2Map(obj);
  }
  map.remove("sign");
  map.remove("encrypt");
  String result = BeanUtil.mapOrderStr(map);
  if (StringUtils.isEmpty(result)) {
   return null;
  }
  return encrypt(result);
 }

 @SuppressWarnings("unchecked")
 public static boolean check(Object obj){
  Map<String,Object> map=new HashMap<String,Object>();
  if(obj==null){
   return false;
  }
  if(obj instanceof Map){
   map=(Map<String, Object>) obj;
  }else{
   map = BeanUtil.transBean2Map(obj);
  }
  String sign=(String)map.get("sign");
  if(sign==null){
   return false;
  }
  String str=encrypt(obj);
  return sign.equals(str)?true:false;

 }
}

返回数据对称加密DES.java

package com.jx.common.entrypt;

import java.security.Key;
import java.util.Map;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

import com.google.gson.Gson;
import com.jx.common.utils.Base64;

/**
* @ClassName: Des
* @Description: TODO(对称加密工具)
* @author gangyu
* @date 2018年11月20日 下午1:18:49
*/
public class DES {
 // 密钥
 private final static String secretKey = "123456789987654321";
 // 向量
 private final static String iv = "ggboy123";
 // 加解密统一使用的编码方式
 private final static String encoding = "utf-8";

 /**
 * @Title: encode
 * @Description: TODO(加密)
 * @param String
 * @author gangyu2
 * @date 2018年11月20日下午1:19:19
  */
 public static String encode(String plainText){
  Key deskey = null;
  DESedeKeySpec spec;
  try {
   spec = new DESedeKeySpec(secretKey.getBytes());
   SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
   deskey = keyfactory.generateSecret(spec);

   Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
   IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
   cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
   byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
   return Base64.encode(encryptData);
  } catch (Exception e) {
   e.printStackTrace();
   return "";
  }
 }

 /**
 * @Title: decode
 * @Description: TODO(解密)
 * @param String
 * @author gangyu2
 * @date 2018年11月20日下午1:19:37
  */
 public static String decode(String encryptText){
  try{

   Key deskey = null;
   DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
   SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
   deskey = keyfactory.generateSecret(spec);
   Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
   IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
   cipher.init(Cipher.DECRYPT_MODE, deskey, ips);

   byte[] decryptData = cipher.doFinal(Base64.decode(encryptText));

   return new String(decryptData, encoding);
  }catch(Exception e){
   e.printStackTrace();
   return "";
  }
 }
}

BeanUtil.java

package com.jx.common.utils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtilsBean;
import org.apache.commons.lang3.StringUtils;

public class BeanUtil {

 // Map --> Bean 2: 利用org.apache.commons.beanutils 工具类实现 Map --> Bean
 public static void transMap2Bean2(Map<String, Object> map, Object obj) {
  if (map == null || obj == null) {
   return;
  }
  try {
   BeanUtils.populate(obj, map);
  } catch (Exception e) {
   System.out.println("transMap2Bean2 Error " + e);
  }
 }

 // Map --> Bean 1: 利用Introspector,PropertyDescriptor实现 Map --> Bean
 public static void transMap2Bean(Map<String, Object> map, Object obj) {
  try {
   BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
   PropertyDescriptor[] propertyDescriptors = beanInfo
     .getPropertyDescriptors();

   for (PropertyDescriptor property : propertyDescriptors) {
    String key = property.getName();

    if (map.containsKey(key)) {
     Object value = map.get(key);
     // 得到property对应的setter方法
     Method setter = property.getWriteMethod();
     setter.invoke(obj, value);
    }

   }

  } catch (Exception e) {
   System.out.println("transMap2Bean Error " + e);
  }

  return;

 }

 // Bean --> Map 1: 利用Introspector和PropertyDescriptor 将Bean --> Map
 public static Map<String, Object> transBean2Map(Object obj) {
  if (obj == null) {
   return null;
  }
  Map<String, Object> map = new HashMap<String, Object>();
  try {
   BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
   PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
   for (PropertyDescriptor property : propertyDescriptors) {
    String key = property.getName();

    // 过滤class属性
    if (!key.equals("class")) {
     // 得到property对应的getter方法
     Method getter = property.getReadMethod();
     Object value = getter.invoke(obj);
     if(null !=value && !"".equals(value))
      map.put(key, value);
    }

   }
  } catch (Exception e) {
   System.out.println("transBean2Map Error " + e);
  }
  return map;

 }

 public static String mapOrderStr(Map<String, Object> map) {
  List<Map.Entry<String, Object>> list = new ArrayList<Map.Entry<String, Object>>(map.entrySet());
  Collections.sort(list, new Comparator<Map.Entry<String, Object>>() {
   public int compare(Entry<String, Object> o1, Entry<String, Object> o2) {
    return o1.getKey().compareTo(o2.getKey());
   }
  });

  StringBuilder sb = new StringBuilder();
  for (Map.Entry<String, Object> mapping : list) {
   sb.append(mapping.getKey() + "=" + mapping.getValue() + "&");
  }
  return sb.substring(0, sb.length() - 1);
 }

 /**
  *
  * 将源的属性复制到目标属性上去
  * @param src
  * @param dest
  * @lastModified
  * @history
  */
 public static void copyProperties(Object dest,Object src) {
  if (src == null || dest == null) {
   return;
  }
  // 获取所有的get/set 方法对应的属性
  PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();
  PropertyDescriptor[] descriptors = propertyUtilsBean.getPropertyDescriptors(src);

  for (int i = 0; i < descriptors.length; i++) {
   PropertyDescriptor propItem = descriptors[i];
   // 过滤setclass/getclass属性
   if ("class".equals(propItem.getName())) {
    continue;
   }

   try {
    Method method = propItem.getReadMethod();
    // 通过get方法获取对应的值
    Object val = method.invoke(src);
    // 如果是空,不做处理
    if (null == val) {
     continue;
    }
    if(val instanceof String) {
     if(StringUtils.isBlank(val.toString())) {
      continue;
     }
    }
    // 值复制
    PropertyDescriptor prop = propertyUtilsBean.getPropertyDescriptor(dest, propItem.getName());
    // 调用写方法,设置值
    if (null != prop && prop.getWriteMethod() != null) {
     prop.getWriteMethod().invoke(dest, val);
    }
   } catch (Exception e) {
   }

  }

 }

 public static <T> T mapToEntity(Map<String, Object> map, Class<T> entity) {
  T t = null;
  try {
   t = entity.newInstance();
   for(Field field : entity.getDeclaredFields()) {
    if (map.containsKey(field.getName())) {
     boolean flag = field.isAccessible();
              field.setAccessible(true);
              Object object = map.get(field.getName());
              if (object!= null && field.getType().isAssignableFrom(object.getClass())) {
                field.set(t, object);
     }
              field.setAccessible(flag);
    }
   }
   return t;
  } catch (InstantiationException e) {
   e.printStackTrace();
  } catch (IllegalAccessException e) {
   e.printStackTrace();
  }
  return t;

 } 

}

拦截器AppInterceptor.java

package com.jx.app.api.framework.interceptor;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import com.google.gson.Gson;
import com.jx.app.api.framework.annotation.LoginAnot;
import com.jx.app.api.framework.annotation.SginAnot;
import com.jx.app.api.framework.annotation.enums.Auth;
import com.jx.app.api.framework.annotation.enums.SginEnum;
import com.jx.common.entrypt.MD5;
import com.jx.common.entrypt.Sha1;
import com.jx.common.token.ServiceException;
import com.jx.common.token.TokenException;
import com.jx.common.token.TokenUtil;
import com.jx.common.utils.Constants;
import com.jx.common.utils.RequestUtil;
import com.jx.common.utils.Result;
import com.jx.common.utils.enums.CodeEnum;
import com.jx.core.api.model.BaseModel;

/**
* @ClassName: AppInterceptor
* @Description: TODO(拦截器)
* @author gangyu
* @date 2018年11月20日 下午4:10:55
*
*/
public class AppInterceptor implements HandlerInterceptor{
    private final static Logger LOGGER = LoggerFactory.getLogger(AppInterceptor.class);

 private static final String CONTENT_TYPE="text/json;charset=UTF-8";

 @Override
 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
   throws Exception {
    if (handler.getClass().isAssignableFrom(HandlerMethod.class)) {
      //签名验证注解
          SginAnot signAnot = ((HandlerMethod) handler).getMethodAnnotation(SginAnot.class);

          //验签
          if(signAnot!=null && !signCheck(request,signAnot.type())){
              response.setContentType(CONTENT_TYPE);
                 response.getWriter().print(new Gson().toJson(new Result(CodeEnum.SIGN_FAIL)));
                 return false;
          }
    return true;
    }else{
    return true;
    }
 }

 private boolean signCheck(HttpServletRequest request,SginEnum enumm){
  Map<String,Object> map=RequestUtil.parseRequset(request);
  if(enumm==SginEnum.MD5){
   return MD5.check(map);
  }else if(enumm==SginEnum.SHA1){
   return Sha1.check(map);
  }
  return false;
 }
 }
 }
}

统一返回对象Result.java

package com.jx.common.utils;

import java.io.Serializable;

import com.google.gson.Gson;
import com.jx.common.entrypt.DES;
import com.jx.common.utils.enums.CodeEnum;

/**
 * 结果DTO
 * @lastModified
 * @history
 */

public class Result implements Serializable{
 private static final long serialVersionUID = 1L;

 /**
  * 结果详细
  */
 private String msg;

 /**
  * 需要传回页面的数据
  */
 private Object data;

 /**
  * 状态码
  */
 private String code;

 /**
  * 加密
  */
 private boolean encrypt;

 /**
  * 图标
  */
 private Integer icon;

 public boolean isEncrypt() {
  return encrypt;
 }

 public void setEncrypt(boolean encrypt) {
  this.encrypt = encrypt;
 }

 public String getMsg() {
  return msg;
 }

 public void setMsg(String msg) {
  this.msg = msg;
 }

 public Result() {

 }

 public Result(CodeEnum enums) {
  this.msg = enums.getMsg();
  this.encrypt = enums.getEncrypt();
  this.code = enums.getCode();
  this.icon = enums.getIcon();
 }

 public Result(CodeEnum enums,Object data) {
  this.msg = enums.getMsg();
  this.encrypt = enums.getEncrypt();
  this.code = enums.getCode();
  this.icon=enums.getIcon();
  if(enums.getEncrypt()){
   this.data=DES.encode(new Gson().toJson(data));
  }else{
   this.data=data;
  }
 }

 public Object getData() {
  return data;
 }

 public void setData(Object data) {
  this.data = data;
 }

 public String getCode() {
  return code;
 }

 public void setCode(String code) {
  this.code = code;
 }

 public Integer getIcon() {
  return icon;
 }

 public void setIcon(Integer icon) {
  this.icon = icon;
 }

 public static Result success(CodeEnum enums) {
  Result dto = new Result();
  dto.setMsg(enums.getMsg());
  dto.setEncrypt(enums.getEncrypt());
  dto.setCode(enums.getCode());
  dto.setIcon(enums.getIcon());
  return dto;
 }

 public static Result success(CodeEnum enums,Object data) {
  Result dto = new Result();
  dto.setData(data);
  dto.setEncrypt(enums.getEncrypt());
  dto.setCode(enums.getCode());
  dto.setIcon(enums.getIcon());
  if(enums.getEncrypt()){
   dto.setData(DES.encode(new Gson().toJson(data)));
  }else{
   dto.setData(data);
  }
  return dto;
 }

 public static Result fail(String msg) {
  Result dto = new Result();
  dto.setMsg(msg);
  dto.setEncrypt(false);
  dto.setCode("1");
  dto.setIcon(SysCode.ICON.ICON_FAIL);
  return dto;
 }
}

状态码枚举类CodeEnum.java

package com.jx.common.utils.enums;
/**
* @ClassName: ExceptionEnum
* @Description: TODO(系统编码)
* @author gangyu
* @date 2018年11月21日 下午5:22:32
*/
public enum CodeEnum {
 //系统编码
    SYS_EXCEPTION("999",false,"系统异常",'fail'),
    SUCCESS("0",false,"成功",'success'),
    ENCRYPT("0",true,"成功",'success'),
    FAIL("1",false,"失败",'fail'),
    SIGN_FAIL("1",false,"签名不正确",'fail'),
    DATA_EMPTY("0",false,"暂无数据",'success'),
    ;

    private String code;

    private String msg;

    private Boolean encrypt;

    private Integer icon;

    CodeEnum(String code,Boolean encrypt, String msg,Integer icon) {
        this.code = code;
        this.encrypt = encrypt;
        this.msg = msg;
        this.icon = icon;
    }

    public Integer getIcon() {
  return icon;
 }

 public String getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

 public Boolean getEncrypt() {
  return encrypt;
 }
}

Controller层使用签名注解

 @RequestMapping(value="encryptEntity",produces = "application/json;charset=UTF-8",method=RequestMethod.POST)
    @SginAnot(type = SginEnum.MD5)
    public  Object encryptEntity(TestEntity test){
        return businessService.encryptEntity(test);
    }
  • 验签加密排序根据ASII表进行排序在BeanUtil.java类里已经实现
  • url?a=1&c=2&b=3。。。->排序后 a=1&b=3&c=2 然后进行数据加密 俩边排序方式要一致当然为了安全可以排完序加入自己的密钥在进行一次加密
  • Result.java提供了返回数据加密方法CodeEnum.ENCRYPT这里使用的是DES对称加密

到此这篇关于SpringBoot自定义注解API数据加密和签名校验的文章就介绍到这了,更多相关SpringBoot 数据加密和签名校验内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Springboot项目对数据库用户名密码实现加密过程解析

    pom.xml文件中引入如下内容 <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>1.16</version> </dependency> 保存pom.xml文件,更新jar 将当前路径切换到jasypt包目录下: 使用如下命

  • springboot对数据库密码加密的实现

    我是黑帽子K,话不多说直接上加密.如有不对,欢迎指正. 开发的同学们都知道,例如项目依赖的信息,数据库信息一般是保存在配置文件中,而且都是明文,因此需要进行加密处理,今天在这里介绍下jasypt集成springboot加密的配置. 首先,这些都是建立在你的springboot项目是能正常运行的前提下. 第一步:pom文件加入依赖,如图: 这里提供一个版本, <dependency> <groupId>com.github.ulisesbocchio</groupId>

  • SpringBoot配置文件中数据库密码加密两种方案(推荐)

    SpringBoot项目经常将连接数据库的密码明文放在配置文件里,安全性就比较低一些,尤其在一些企业对安全性要求很高,因此我们就考虑如何对密码进行加密. 介绍两种加密方式:jasypt 可加密配置文件中所有属性值; druid 自带了加解密,可对数据库密码进行加密. jasypt 加解密 jasypt 是一个简单易用的加解密Java库,可以快速集成到 Spring 项目中.可以快速集成到 Spring Boot 项目中,并提供了自动配置,使用非常简单. 步骤如下: 1)引入maven依赖 <de

  • SpringBoot配置数据库密码加密的实现

    你在使用 MyBatis 的过程中,是否有想过多个数据源应该如何配置,如何去实现?出于这个好奇心,我在 Druid Wiki 的数据库多数据源中知晓 Spring 提供了对多数据源的支持,基于 Spring 提供的 AbstractRoutingDataSource,可以自己实现数据源的切换. 一.配置动态数据源 下面就如何配置动态数据源提供一个简单的实现: org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource,

  • Springboot Druid 自定义加密数据库密码的几种方案

    前言 开发过程中,配置的数据库密码通常是明文形式,这样首先第一个安全性不好(相对来说),不符合一个开发规范(如项目中不能出现明文账号密码),其实就是当出现特殊需求时,比如要对非运维人员开方服务器部分权限,但是又涉及项目部署的目录时,容易泄漏数据库密码,虽然一般生产环境中,数据库往往放入内网,访问只能通过内网访问,但是不管怎么说账号密码直接让人知道总归不好,甚至有些项目需要部署到客户环境中,但是可能共用一个公共数据库(数据库只向指定服务器开放外网端口或组建内网环境),这样的情况下,如果数据库密码再

  • jasypt 集成SpringBoot 数据库密码加密操作

    昨天看到一片文章,说是某某旗下酒店数据库因为程序员不小心,把数据库明文密码上传到了GitHub上,导致酒店数据注册资料.入住信息,开房记录被下载倒卖的消息. 作为程序员,开发的时候为了简单,账户明明都设置很简单,基本上数据库密码都是明文的,没做什么操作,至少我待过的公司都是这样,无论是测试环境还是线上环境,想想,这个也是一大安全隐患,在此,趁现在不忙,做些基于springboot的数据库密码加密. 1.pom.xml添加jar包(不同jdk选择不同的版本): <!-- jdk8 版本 整合jas

  • springboot数据库密码加密的配置方法

    前言 由于系统安全的考虑,配置文件中不能出现明文密码的问题,本文就给大家详细介绍下springboot配置数据库密码加密的方法,下面话不多说了,来一起看看详细的介绍吧 1.导入依赖 <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>2.1.2</

  • SpringBoot自定义注解API数据加密和签名校验

    api数据数据签名(MD5,SHA1) 签名枚举类SginEnum.java package com.jx.app.api.framework.annotation.enums; /** * @ClassName: SginEnum * @Description: TODO(这是一个签名枚举类) * @author gangyu * @date 2018年11月20日 下午4:30:44 */ public enum SginEnum { //0不需要签名,1使用MD5数据加密 2 使用SHA数

  • SpringBoot自定义注解实现Token校验的方法

    1.定义Token的注解,需要Token校验的接口,方法上加上此注解 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementTyp

  • SpringBoot中自定义注解实现参数非空校验的示例

    前言 由于刚写项目不久,在写 web 后台接口时,经常会对前端传入的参数进行一些规则校验,如果入参较少还好,一旦需要校验的参数比较多,那么使用 if 校验会带来大量的重复性工作,并且代码看起来会非常冗余,所以我首先想到能否通过一些手段改进这点,让 Controller 层减少参数校验的冗余代码,提升代码的可阅读性. 经过阅读他人的代码,发现使用 annotation 注解是一个比较方便的手段,SpringBoot 自带的 @RequestParam 注解只会校验请求中该参数是否存在,但是该参数是

  • SpringBoot 自定义注解异步记录复杂日志详解

    目录 1.背景 2.技术方案-自定义注解 2.1 注解介绍 2.2 元注解 2.3 实现自定义注解 3.技术方案-AOP切面 3.1 AOP术语解析 3.2 切入点表达式 3.3 ADVICE通知类型 3.4 技术实现 3.5 相关操作 4.高级操作 1.背景 最近接手一个任务,需要给当前项目加一个较为复杂的日志.有多复杂呢? 要有日志类型.不同日志类型要有不同的操作和备注等.作为小白的我最开始的做法是在业务层写代码记录日志,好处就是方便,坏处就是这种做法直接侵袭Service层,Service

  • java SpringBoot自定义注解,及自定义解析器实现对象自动注入操作

    # java-SpringBoot自定义参数解析器实现对象自动注入 解析器逻辑流程图表 后台解析注解的解析器 首先,我在java后台编写了一个解析器,代码如下 import com.ruoyi.framework.interceptor.annotation.LoginUser; import com.ruoyi.project.WebMoudle.WebUser.domain.WebUser; import com.ruoyi.project.WebMoudle.WebUser.service

  • SpringBoot自定义注解使用读写分离Mysql数据库的实例教程

    需求场景 为了防止代码中有的SQL慢查询,影响我们线上主数据库的性能.我们需要将sql查询操作切换到从库中进行.为了使用方便,将自定义注解的形式使用. mysql导入的依赖 <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency&

  • 使用Springboot自定义注解,支持SPEL表达式

    目录 Springboot自定义注解,支持SPEL表达式 1.自定义注解 2.使用AOP拦截方法,解析注解参数 自定义注解结合切面和spel表达式 自定义一个注解 自定义一个service类,在需要拦截的方法上加上@Log注解 写一个自定义切面 pom文件的依赖 测试 增加内容 Springboot自定义注解,支持SPEL表达式 举例,自定义redis模糊删除注解 1.自定义注解 import java.lang.annotation.ElementType; import java.lang.

  • SpringBoot自定义注解开发指南

    目录 一.Java注解(Annotation) 1.JDK基本注解 2.JDK元注解 二.自定义注解开发 1.含义 2.演示 三.完成切面日志操作 四.完成前端响应反应 总结 一.Java注解(Annotation) 含义:Java注解是附加在代码中的一些元信息,用于一些工具在编译. 运行时进行解析和使用,起到说明.配置的功能. 1.JDK基本注解 @Override ——>重写 @Deprecated ——>已过时 @SuppressWarnings(value = "unchec

  • SpringBoot 自定义注解实现涉密字段脱敏

    目录 1. 创建隐私数据类型枚举:PrivacyTypeEnum 2. 创建自定义隐私注解:PrivacyEncrypt 3. 创建自定义序列化器:PrivacySerializer 4. 隐私数据隐藏工具类:PrivacyUtil 5. 注解使用 关于数据脱敏,网上的文章都是硬编码规则,比如对身份证,手机号,邮件地址等固定写法脱敏.本文在此基础上,拓展动态从数据库查出涉密关键字执行脱敏操作. 数据脱敏:把系统里的一些敏感数据进行加密处理后再返回,达到保护隐私作用,实现效果图如下: 其实要实现上

  • SpringBoot自定义注解之实现AOP切面日志详解

    通过自定义注解的方式(如:@SysLog(obj = "操作对象", text = "操作内容"),在 SpringBoot 中来实现 AOP 切面统一打印出入参日志. 一.先看下项目结构 二.Maven JAR依赖 <!-- AOP -->     <dependency>             <groupId>org.springframework.boot</groupId>             <

随机推荐