springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/model/dtos/community/ComMngPopulationDTO.java
@@ -1,5 +1,7 @@ package com.panzhihua.common.model.dtos.community; import com.panzhihua.common.model.helper.encrypt.EncryptQuery; import com.panzhihua.common.model.helper.encrypt.EncryptQueryClass; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; @@ -9,6 +11,7 @@ * 实有人口DTO */ @Data @EncryptQueryClass public class ComMngPopulationDTO implements Serializable { private static final long serialVersionUID = 1L; @@ -91,6 +94,7 @@ * 身份证号码 */ @ApiModelProperty(value="身份证号码") @EncryptQuery private String cardNo; /** * 街路巷 springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/model/helper/AESUtil.java
New file @@ -0,0 +1,161 @@ package com.panzhihua.common.model.helper; import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.spec.KeySpec; import java.util.Arrays; import java.util.Base64; /** * AES 工具类 */ public class AESUtil { /** * AES 256 加密 * @param strToEncrypt 要加密的字符串 * @param secKey 秘钥 * @param salt 盐 * @return 加密后的字符串 */ public static String encrypt256(String strToEncrypt, String secKey, String salt) { try { byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; IvParameterSpec ivspec = new IvParameterSpec(iv); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); KeySpec spec = new PBEKeySpec(secKey.toCharArray(), salt.getBytes(), 65536, 256); SecretKey tmp = factory.generateSecret(spec); SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec); return Base64.getEncoder() .encodeToString(cipher.doFinal(strToEncrypt.getBytes(StandardCharsets.UTF_8))); } catch (Exception e) { System.out.println("Error while encrypting: " + e.toString()); } return null; } /** * AES 256 解密 * @param strToDecrypt 要解密的字符串 * @param secKey 秘钥 * @param salt 盐 * @return 解密后的字符串 */ public static String decrypt256( String strToDecrypt, String secKey, String salt) { try { byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; IvParameterSpec ivspec = new IvParameterSpec(iv); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); KeySpec spec = new PBEKeySpec(secKey.toCharArray(), salt.getBytes(), 65536, 256); SecretKey tmp = factory.generateSecret(spec); SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); cipher.init(Cipher.DECRYPT_MODE, secretKey, ivspec); return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt))); } catch (Exception e) { System.out.println("Error while decrypting: " + e.toString()); } return null; } private static SecretKeySpec secretKey; private static byte[] key; public static void setKey(String myKey) { MessageDigest sha = null; try { key = myKey.getBytes("UTF-8"); sha = MessageDigest.getInstance("SHA-1"); key = sha.digest(key); key = Arrays.copyOf(key, 16); secretKey = new SecretKeySpec(key, "AES"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } /** * AES 128 加密 * @param strToEncrypt 要加密的字符串 * @param secret 秘钥 * @return 加密后的字符串 */ public static String encrypt128(String strToEncrypt, String secret) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException, BadPaddingException, IllegalBlockSizeException { setKey(secret); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8"))); } /** * AES 128 解密 * @param strToDecrypt 要解密的字符串 * @param secret 秘钥 * @return 解密后的字符串 */ public static String decrypt128(String strToDecrypt, String secret) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException { setKey(secret); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING"); cipher.init(Cipher.DECRYPT_MODE, secretKey); return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt))); } } class AES256Example { public static void main(String[] args) { String originalString = "howtodoinjava.com"; String secKey = "this is my super secrt key"; String salt = "salt for me!!!"; String encryptedString = AESUtil.encrypt256(originalString, secKey, salt); String decryptedString = AESUtil.decrypt256(encryptedString, secKey, salt); System.out.println(originalString); System.out.println(encryptedString); System.out.println(decryptedString); } } class AES128Example { public static void main(String[] args) { String[] originalString = new String[]{"51011234567892013", "13612345678", "四川省成都市高新区", "四川省成都市高新"}; String key = "5165465461dsfas"; Arrays.stream(originalString).forEach(os ->{ try { String encryptedString = AESUtil.encrypt128(os, key); String decryptedString = AESUtil.decrypt128(encryptedString, key); System.out.println(os); System.out.println(encryptedString); System.out.println(decryptedString); }catch (Exception e){ e.printStackTrace(); } }); } } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/model/helper/encrypt/DoEncrytDecrypt.java
New file @@ -0,0 +1,79 @@ package com.panzhihua.common.model.helper.encrypt; import com.panzhihua.common.model.helper.AESUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.lang.annotation.Annotation; import java.lang.reflect.Field; /*** * 默认实现: AES 128 加密、解密 * 可自定义实现{@link IEncryptDecrypt }接口 * * @author cedoo * @since 2021-4-1 10:40:52 */ @Slf4j @Component public class DoEncrytDecrypt implements IEncryptDecrypt{ @Value("${domain.aesKey:}") private String aesKey; @Override public <T> T encrypt(Field[] declaredFields, T parameterObject) throws IllegalAccessException { for (Field field : declaredFields) { if (field.getType() == String.class) { field.setAccessible(true); for (Annotation annotation : field.getAnnotations()) { if (annotation.annotationType() == EncryptDecryptField.class || annotation.annotationType() == EncryptQuery.class) { log.debug("加密字段:" + field.getName()); Object fieldVal = field.get(parameterObject); if(fieldVal!=null) { try { String encryptedStr = AESUtil.encrypt128(fieldVal.toString(), aesKey); field.set(parameterObject, encryptedStr); }catch (Exception e){ log.debug("加密失败"); } } } } } } return parameterObject; } @Override public <T> T decrypt(T result) throws IllegalAccessException { for (Field field : result.getClass().getDeclaredFields()) { try { field.setAccessible(true); if (field.get(result) != null) { for (Annotation annotation : field.getAnnotations()) { if (annotation.annotationType() == EncryptDecryptField.class) { log.debug("解密密字段:" + field.getName()); String fieldVal = field.get(result).toString(); try { String decryptVal = AESUtil.decrypt128(fieldVal, aesKey); field.set(result, decryptVal != null ? decryptVal : fieldVal); }catch (Exception e){ /** * 兼容原始未加密数据 */ field.set(result, fieldVal); } } } } } catch (IllegalAccessException e) { throw e; } } return result; } } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/model/helper/encrypt/EncryptDecryptClass.java
New file @@ -0,0 +1,14 @@ package com.panzhihua.common.model.helper.encrypt; import java.lang.annotation.*; /** * 需要加解密的类注解 */ @Documented @Inherited @Target({ ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) public @interface EncryptDecryptClass { } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/model/helper/encrypt/EncryptDecryptField.java
New file @@ -0,0 +1,15 @@ package com.panzhihua.common.model.helper.encrypt; import java.lang.annotation.*; /** * 加密字段注解 */ @Documented @Inherited @Target({ ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) public @interface EncryptDecryptField { } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/model/helper/encrypt/EncryptQuery.java
New file @@ -0,0 +1,15 @@ package com.panzhihua.common.model.helper.encrypt; import java.lang.annotation.*; /** * 加密字段搜索 */ @Documented @Inherited @Target({ ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) public @interface EncryptQuery { } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/model/helper/encrypt/EncryptQueryClass.java
New file @@ -0,0 +1,15 @@ package com.panzhihua.common.model.helper.encrypt; import java.lang.annotation.*; /** * 加密字段搜索 */ @Documented @Inherited @Target({ ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) public @interface EncryptQueryClass { } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/model/helper/encrypt/IEncryptDecrypt.java
New file @@ -0,0 +1,25 @@ package com.panzhihua.common.model.helper.encrypt; import java.lang.reflect.Field; public interface IEncryptDecrypt { /** * 加密方法 * @param declaredFields 反射bean成员变量 * @param parameterObject Mybatis入参 * @param <T> * @return */ public <T> T encrypt(Field[] declaredFields, T parameterObject) throws IllegalAccessException; /** * 解密方法 * @param result Mybatis 返回值,需要判断是否是ArrayList类型 * @param <T> * @return */ public <T> T decrypt(T result) throws IllegalAccessException; } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/model/helper/sensitive/Desensitizer.java
New file @@ -0,0 +1,8 @@ package com.panzhihua.common.model.helper.sensitive; import java.util.function.Function; public interface Desensitizer extends Function<String,String> { } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/model/helper/sensitive/Sensitive.java
New file @@ -0,0 +1,12 @@ package com.panzhihua.common.model.helper.sensitive; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Sensitive { SensitiveStrategy strategy(); } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/model/helper/sensitive/SensitiveStrategy.java
New file @@ -0,0 +1,51 @@ package com.panzhihua.common.model.helper.sensitive; /** * 脱敏策略. * * @author cedoo * @since 2021-4-1 10:40:52 */ public enum SensitiveStrategy { /** * Username sensitive strategy. */ USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")), /** * Id card sensitive type. */ ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")), /** * Phone sensitive type. */ PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")), /** * Address sensitive type. */ ADDRESS(s -> s.replaceAll("(\\S{8})\\S{4}(\\S*)\\S{4}", "$1****$2****")), /** * 中文地址 */ ADDRESS_CN(s -> { //List<Word> words = WordSegmenter.seg(s); //Arrays.toString(words.toArray()); return s.replaceAll("(\\S{8})(\\S*)\\S{4}", "$1****$2****"); }); private final Desensitizer desensitizer; SensitiveStrategy(Desensitizer desensitizer) { this.desensitizer = desensitizer; } /** * Gets desensitizer. * * @return the desensitizer */ public Desensitizer getDesensitizer() { return desensitizer; } } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/model/vos/community/ComMngPopulationVO.java
@@ -1,5 +1,9 @@ package com.panzhihua.common.model.vos.community; import com.panzhihua.common.model.helper.encrypt.EncryptDecryptClass; import com.panzhihua.common.model.helper.encrypt.EncryptDecryptField; import com.panzhihua.common.model.helper.sensitive.Sensitive; import com.panzhihua.common.model.helper.sensitive.SensitiveStrategy; import com.panzhihua.common.model.vos.user.ComMngFamilyInfoVO; import com.panzhihua.common.validated.AddGroup; import io.swagger.annotations.ApiModel; @@ -15,6 +19,7 @@ */ @Data @ApiModel("实有人口表") @EncryptDecryptClass public class ComMngPopulationVO { /** @@ -60,6 +65,8 @@ */ @ApiModelProperty("身份证号码") @NotBlank(groups = {AddGroup.class},message = "身份证号码不可为空") @EncryptDecryptField @Sensitive(strategy = SensitiveStrategy.ID_CARD) private String cardNo; /** * 街路巷 @@ -111,6 +118,8 @@ */ @ApiModelProperty("联系方式") @NotBlank(groups = {AddGroup.class},message = "联系方式不可为空") @EncryptDecryptField @Sensitive(strategy = SensitiveStrategy.PHONE) private String phone; /** * 备注 springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/utlis/ParamRegularUtil.java
New file @@ -0,0 +1,23 @@ package com.panzhihua.common.utlis; import java.util.regex.Pattern; /** * @Author: llming * @Description:参数正则匹配工具类 */ public class ParamRegularUtil { /** * 车牌号校验 * @param carNum */ public static boolean carNumRegular(String carNum) { String pattern = "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]{1}(([A-HJ-Z]{1}[A-HJ-NP-Z0-9]{5})|([A-HJ-Z]{1}(([DF]{1}[A-HJ-NP-Z0-9]{1}[0-9]{4})|([0-9]{5}[DF]{1})))|([A-HJ-Z]{1}[A-D0-9]{1}[0-9]{3}警)))|([0-9]{6}使)|((([沪粤川云桂鄂陕蒙藏黑辽渝]{1}A)|鲁B|闽D|蒙E|蒙H)[0-9]{4}领)|(WJ[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼·•]{1}[0-9]{4}[TDSHBXJ0-9]{1})|([VKHBSLJNGCE]{1}[A-DJ-PR-TVY]{1}[0-9]{5})"; return Pattern.matches(pattern, carNum); } public static void main(String[] args) { boolean cdsaf = carNumRegular("粤B12345"); System.out.println(cdsaf); } } springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/dao/ComMngCarDAO.java
@@ -41,15 +41,15 @@ " LEFT JOIN sys_user t3 ON t.create_by = t3.user_id " + " WHERE t.source =2 " + "<if test='pageComMngCarDTO.name != null and pageComMngCarDTO.name.trim() != ""'>" + " and t.user_name LIKE concat( #{pageComMngCarDTO.name}, '%' ) " + " and t.user_name LIKE concat( '%',#{pageComMngCarDTO.name}, '%' ) " + " </if> " + "<if test='pageComMngCarDTO.communityId != null and pageComMngCarDTO.communityId != 0'>" + " and t.community_id = #{pageComMngCarDTO.communityId} " + " </if> " + "<if test='pageComMngCarDTO.areaName != null and pageComMngCarDTO.areaName != 0'>" + " and t2.area_name LIKE concat( #{pageComMngCarDTO.areaName}, '%' ) " + "<if test='pageComMngCarDTO.areaName != null'>" + " and t2.area_name LIKE concat( '%',#{pageComMngCarDTO.areaName}, '%' ) " + " </if> " + " order by t.create_at desc"+ " order by t.create_at desc" + "</script>") IPage<ComMngCarVO> pageQueryComMngCar(Page page, @Param(value = "pageComMngCarDTO") PageComMngCarDTO pageComMngCarDTO); } springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/dao/ComMngStructAreaDAO.java
@@ -43,7 +43,7 @@ "AND community_id=#{comMngStructAreaVO.communityId} \n" + " </if> " + "<if test='comMngStructAreaVO.areaName != null and comMngStructAreaVO.areaName.trim() != ""'>" + "AND area_name = #{comMngStructAreaVO.areaName}" + "AND area_name = concat( '%',#{comMngStructAreaVO.areaName}, '%' )" + " </if> " + "</script>") IPage<ComMngStructAreaVO> pageArea(Page page, @Param("comMngStructAreaVO") ComMngStructAreaVO comMngStructAreaVO); springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/model/dos/ComMngPopulationDO.java
@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.panzhihua.common.model.helper.encrypt.EncryptDecryptClass; import com.panzhihua.common.model.helper.encrypt.EncryptDecryptField; import lombok.Data; import java.io.Serializable; @@ -11,6 +13,7 @@ @Data @TableName(value = "com_mng_population") @EncryptDecryptClass public class ComMngPopulationDO implements Serializable { private static final long serialVersionUID = 1L; @@ -46,6 +49,7 @@ /** * 身份证号码 */ @EncryptDecryptField private String cardNo; /** * 街路巷 @@ -82,6 +86,7 @@ /** * 联系方式 */ @EncryptDecryptField private String phone; /** * 备注 springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/model/helper/encrypt/ParammeterInterceptor.java
New file @@ -0,0 +1,115 @@ package com.panzhihua.service_community.model.helper.encrypt; import com.panzhihua.common.model.helper.encrypt.EncryptDecryptClass; import com.panzhihua.common.model.helper.encrypt.EncryptQuery; import com.panzhihua.common.model.helper.encrypt.EncryptQueryClass; import com.panzhihua.common.model.helper.encrypt.IEncryptDecrypt; import com.panzhihua.common.model.helper.sensitive.Sensitive; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.binding.BindingException; import org.apache.ibatis.binding.MapperMethod; import org.apache.ibatis.executor.parameter.ParameterHandler; import org.apache.ibatis.plugin.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.stereotype.Component; import java.lang.reflect.Field; import java.sql.PreparedStatement; import java.util.*; import java.util.stream.Stream; /** * 加密拦截器 * 包含加密字段查询时 的加密步骤 * @author cedoo * @since 2021-4-1 10:40:52 */ @Intercepts({ @Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class), }) @ConditionalOnProperty(value = "domain.encrypt", havingValue = "true") @Component @Slf4j public class ParammeterInterceptor implements Interceptor { @Autowired private IEncryptDecrypt encryptDecrypt; @Override public Object intercept(Invocation invocation) throws Throwable { //拦截 ParameterHandler 的 setParameters 方法 动态设置参数 if (invocation.getTarget() instanceof ParameterHandler) { ParameterHandler parameterHandler = (ParameterHandler) invocation.getTarget(); PreparedStatement ps = (PreparedStatement) invocation.getArgs()[0]; // 反射获取 参数对像 Field parameterField = parameterHandler.getClass().getDeclaredField("parameterObject"); parameterField.setAccessible(true); Object parameterObject = parameterField.get(parameterHandler); if (Objects.nonNull(parameterObject)) { Class<?> parameterObjectClass = parameterObject.getClass(); EncryptDecryptClass encryptDecryptClass = AnnotationUtils.findAnnotation(parameterObjectClass, EncryptDecryptClass.class); if (Objects.nonNull(encryptDecryptClass)) { Field[] declaredFields = parameterObjectClass.getDeclaredFields(); final Object encrypt = encryptDecrypt.encrypt(declaredFields, parameterObject); } /** * 通过加密字段查询时, 将查询参数中的加密字段加密后查询 */ if(parameterObjectClass == MapperMethod.ParamMap.class) { MapperMethod.ParamMap paramMap = (MapperMethod.ParamMap) parameterObject; boolean encrypted = false; try{ /** * 分页插件,会再分页查询时 进行多次查询,需要判断是否已对加密参数加密,防止多次加密后,查询失败 */ encrypted = paramMap.get("encrypted")!=null; }catch (BindingException be){ encrypted = false; } if(!encrypted) { Iterator iterator = paramMap.entrySet().iterator(); while(iterator.hasNext()){ Map.Entry<String, Object> entry = (Map.Entry<String, Object>) iterator.next(); if (entry.getKey().startsWith("param")) { Object v = entry.getValue(); EncryptQueryClass encryptQueryClass = AnnotationUtils.findAnnotation(v.getClass(), EncryptQueryClass.class); if (Objects.nonNull(encryptQueryClass)) { Field[] declaredFields = v.getClass().getDeclaredFields(); for (Field field : declaredFields) { if (field.isAnnotationPresent(EncryptQuery.class)) { try { final Object encrypt = encryptDecrypt.encrypt(new Field[]{field}, v); paramMap.put("encrypted", true); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } } } } } } } return invocation.proceed(); } @Override public Object plugin(Object o) { return Plugin.wrap(o, this); } @Override public void setProperties(Properties properties) { } } springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/model/helper/encrypt/ResultInterceptor.java
New file @@ -0,0 +1,75 @@ package com.panzhihua.service_community.model.helper.encrypt; import com.panzhihua.common.model.helper.encrypt.EncryptDecryptClass; import com.panzhihua.common.model.helper.encrypt.IEncryptDecrypt; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.executor.resultset.ResultSetHandler; import org.apache.ibatis.plugin.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.stereotype.Component; import java.sql.Statement; import java.util.ArrayList; import java.util.Objects; import java.util.Properties; /** * 解密拦截器 * * @author cedoo * @since 2021-4-1 10:40:52 */ @Intercepts({ @Signature(type = ResultSetHandler.class, method = "handleResultSets", args={Statement.class}) }) @ConditionalOnProperty(value = "domain.decrypt", havingValue = "true") @Component @Slf4j public class ResultInterceptor implements Interceptor { @Autowired private IEncryptDecrypt encryptDecrypt; @Override public Object intercept(Invocation invocation) throws Throwable { Object result = invocation.proceed(); if (Objects.isNull(result)){ return null; } if (result instanceof ArrayList) { ArrayList resultList = (ArrayList) result; if (resultList!=null && resultList.size()>0 && needToDecrypt(resultList.get(0))){ for (int i = 0; i < resultList.size(); i++) { encryptDecrypt.decrypt(resultList.get(i)); } } }else { if (needToDecrypt(result)){ encryptDecrypt.decrypt(result); } } return result; } public boolean needToDecrypt(Object object){ Class<?> objectClass = object.getClass(); EncryptDecryptClass encryptDecryptClass = AnnotationUtils.findAnnotation(objectClass, EncryptDecryptClass.class); if (Objects.nonNull(encryptDecryptClass)){ return true; } return false; } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { } } springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/model/helper/sensitive/SensitiveInterceptor.java
New file @@ -0,0 +1,71 @@ package com.panzhihua.service_community.model.helper.sensitive; import com.panzhihua.common.model.helper.sensitive.Sensitive; import com.panzhihua.common.model.helper.sensitive.SensitiveStrategy; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.executor.resultset.ResultSetHandler; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Signature; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.SystemMetaObject; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; import java.lang.reflect.Field; import java.sql.Statement; import java.util.List; import java.util.stream.Stream; /** * 字段脱敏拦截器 * @author cedoo * @since 2021-4-1 10:40:52 */ @Intercepts(@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})) @Slf4j @ConditionalOnProperty(value = "domain.sensitive", havingValue = "true") @Component public class SensitiveInterceptor implements Interceptor { @SuppressWarnings("unchecked") @Override public Object intercept(Invocation invocation) throws Throwable { //log.debug("脱敏拦截器"); List<Object> records = (List<Object>) invocation.proceed(); // 对结果集脱敏 records.forEach(this::sensitive); return records; } private void sensitive(Object source) { // 拿到返回值类型 Class<?> sourceClass = source.getClass(); // 初始化返回值类型的 MetaObject MetaObject metaObject = SystemMetaObject.forObject(source); // 捕捉到属性上的标记注解 @Sensitive 并进行对应的脱敏处理 Stream.of(sourceClass.getDeclaredFields()) .filter(field -> field.isAnnotationPresent(Sensitive.class)) .forEach(field -> doSensitive(metaObject, field)); } private void doSensitive(MetaObject metaObject, Field field) { // 拿到属性名 String name = field.getName(); // 获取属性值 Object value = metaObject.getValue(name); // 只有字符串类型才能脱敏 而且不能为null if (String.class == metaObject.getGetterType(name) && value != null) { Sensitive annotation = field.getAnnotation(Sensitive.class); // 获取对应的脱敏策略 并进行脱敏 SensitiveStrategy type = annotation.strategy(); Object o = type.getDesensitizer().apply((String) value); // 把脱敏后的值塞回去 metaObject.setValue(name, o); } } } springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/service/impl/ComMngCarServiceImpl.java
@@ -13,6 +13,7 @@ import com.panzhihua.common.model.vos.community.ComMngCarVO; import com.panzhihua.common.model.vos.user.SysUserVO; import com.panzhihua.common.service.user.UserService; import com.panzhihua.common.utlis.ParamRegularUtil; import com.panzhihua.service_community.dao.ComMngCarDAO; import com.panzhihua.service_community.dao.ComMngStructAreaDAO; import com.panzhihua.service_community.model.dos.ComCvtServeDO; @@ -84,13 +85,17 @@ pageSize = 10l; } page.setSize(pageSize); page.setCurrent(pageNum); page.setCurrent(pageNum.longValue()); IPage<ComMngCarVO> iPage = comMngCarDAO.pageQueryComMngCar(page, pageComMngCarDTO); return R.ok(iPage); } @Override public R saveComMngCar(ComMngCarSaveDTO comMngCarSaveDTO) { boolean carResult = ParamRegularUtil.carNumRegular(comMngCarSaveDTO.getPlateNum()); if(!carResult){ return R.fail("车牌号有误!"); } ComMngCarDO exist= comMngCarDAO.selectOne(new QueryWrapper<ComMngCarDO>() .lambda().eq(ComMngCarDO::getPlateNum, comMngCarSaveDTO.getPlateNum()).and(wrapper->wrapper.eq(ComMngCarDO::getSource,2))); /*if (comMngCarSaveDTO.getId()!=0 && exist.getId()!=comMngCarSaveDTO.getId()) { springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/resources/bootstrap.yml
@@ -21,6 +21,10 @@ service-url: defaultZone: http://${EUREKA_URL:localhost}:8192/eureka #实体加密、解密、字段脱敏拦截设置 domain: decrypt: true encrypt: true aesKey: Ryo7M3n8loC5 sensitive: true