这篇“SpringBoot怎么新增脱敏功能”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“springBoot怎么新增脱敏功能
这篇“SpringBoot怎么新增脱敏功能”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“springBoot怎么新增脱敏功能”文章吧。
目前正在开发一个SpringBoot项目,此项目有WEB端和微信小程序端。web端提供给工作人员使用,微信小程序提供给群众进行预约操作。项目中有部分敏感数据需要脱敏传递给微信小程序,给与群众查看。
项目中,由于使用端有两个,对于两个端的数据权限并不一样。Web端可以查看所有数据,小程序端只能查看脱敏后的数据。
需要开发一个通用脱敏功能
手动进行脱敏操作
支持多种对象,
支持不同字段,并脱敏指定字段
字段的脱敏方式多样
字段的脱敏方式可自定义
使用注解方式
,来支持对指定字段,不同字段,多种脱敏操作,并可以脱离对象。
使用工具对象,通过泛型传参,来支持对不同对象的脱敏操作。
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 { SensitiveType type() default SensitiveType.CUSTOMER; int prefixNoMaskLen() default 0; int suffixNoMaskLen() default 0; String symbol() default "*";}
public enum SensitiveType { CUSTOMER, CHINESE_NAME, ID_CARD_NUM, MOBILE_PHONE, FIXED_PHONE, PASSWord, BANKCARD, EMaiL, ADDRESS,}
import com.ruoyi.common.annotation.Sensitive;import com.ruoyi.common.constant.httpstatus;import com.ruoyi.common.core.domain.ajaxResult;import com.ruoyi.common.enums.SensitiveType;import lombok.extern.slf4j.Slf4j;import java.lang.reflect.Field;import java.util.*;@Slf4jpublic class DesensitizedUtils<T> { private List<T> list; private List<Object[]> fields; public Class<T> clazz; public DesensitizedUtils(Class<T> clazz) { this.clazz = clazz; } public void init(List<T> list){ if (list == null) { list = new ArrayList<T>(); } this.list = list; // 得到所有定义字段 createSensitiveField(); } public void init(T t){ list = new ArrayList<T>(); if (t != null) { list.add(t); } // 得到所有定义字段 createSensitiveField(); } private void createSensitiveField() { this.fields = new ArrayList<Object[]>(); List<Field> tempFields = new ArrayList<>(); tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); for (Field field : tempFields) { // 单注解 if (field.isAnnotationPresent(Sensitive.class)) { putToField(field, field.getAnnotation(Sensitive.class)); } // 多注解// if (field.isAnnotationPresent(excels.class))// {// Excels attrs = field.getAnnotation(Excels.class);// Excel[] excels = attrs.value();// for (Excel excel : excels)// {// putToField(field, excel);// }// } } } public AjaxResult desensitizedList(List<T> list){ if (list == null){ return AjaxResult.error("脱敏数据为空"); } // 初始化数据 this.init(list); int failTimes = 0; for (T t: this.list) { if ((Integer)desensitization(t).get("code") != HttpStatus.SUCCESS){ failTimes++; } } if (failTimes >0){ return AjaxResult.error("脱敏操作中出现失败",failTimes); } return AjaxResult.success(); } private void putToField(Field field, Sensitive attr) { if (attr != null) { this.fields.add(new Object[] { field, attr }); } } public AjaxResult desensitization(T t) { if (t == null){ return AjaxResult.error("脱敏数据为空"); } // 初始化数据 init(t); try { // 遍历处理需要进行 脱敏的字段 for (Object[] os : fields) { Field field = (Field) os[0]; Sensitive sensitive = (Sensitive) os[1]; // 设置实体类私有属性可访问 field.setAccessible(true); desensitizeField(sensitive,t,field); } return AjaxResult.success(t); } catch (Exception e) { e.printStackTrace(); log.error("日志脱敏处理失败,回滚,详细信息:[{}]", e); return AjaxResult.error("脱敏处理失败",e); } } private void desensitizeField(Sensitive attr, T vo, Field field) throws IllegalAccessException { if (attr == null || vo == null || field == null){ return ; } // 读取对象中的属性 Object value = field.get(vo); SensitiveType sensitiveType = attr.type(); int prefixNoMaskLen = attr.prefixNoMaskLen(); int suffixNoMaskLen = attr.suffixNoMaskLen(); String symbol = attr.symbol(); //获取属性后现在默认处理的是String类型,其他类型数据可扩展 Object val = convertByType(sensitiveType, value, prefixNoMaskLen, suffixNoMaskLen, symbol); field.set(vo, val); } private Object getValue(Object o, String name) throws Exception { if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name)) { Class<?> clazz = o.getClass(); Field field = clazz.getDeclaredField(name); field.setAccessible(true); o = field.get(o); } return o; } private Object convertByType(SensitiveType sensitiveType, Object value, int prefixNoMaskLen, int suffixNoMaskLen, String symbol) { switch (sensitiveType) { case CUSTOMER: value = customer(value, prefixNoMaskLen, suffixNoMaskLen, symbol); break; case CHINESE_NAME: value = chineseName(value, symbol); break; case ID_CARD_NUM: value = idCardNum(value, symbol); break; case MOBILE_PHONE: value = mobilePhone(value, symbol); break; case FIXED_PHONE: value = fixedPhone(value, symbol); break; case PASSWORD: value = password(value, symbol); break; case BANKCARD: value = bankCard(value, symbol); break; case EMAIL: value = email(value, symbol); break; case ADDRESS: value = address(value, symbol); break; } return value; } public Object customer(Object value, int prefixNoMaskLen, int suffixNoMaskLen, String symbol) { //针对字符串的处理 if (value instanceof String){ return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol); } return value; } private String handleString(String s, int prefixNoMaskLen, int suffixNoMaskLen, String symbol){ // 是否为空 if (StringUtils.isBlank(s)) { return ""; } // 如果设置为空之类使用 * 代替 if (StringUtils.isBlank(symbol)){ symbol = "*"; } // 对长度进行判断 int length = s.length(); if (length > prefixNoMaskLen + suffixNoMaskLen){ String namePrefix = StringUtils.left(s, prefixNoMaskLen); String nameSuffix = StringUtils.right(s, suffixNoMaskLen); s = StringUtils.rightPad(namePrefix, StringUtils.length(s) - suffixNoMaskLen, symbol).concat(nameSuffix); } return s; } public String chineseName(Object value, String symbol) { //针对字符串的处理 if (value instanceof String){ // 对前后长度进行设置 默认 开头只展示一个字符 int prefixNoMaskLen = 1; int suffixNoMaskLen = 0; return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol); } return ""; } public String idCardNum(Object value, String symbol) { //针对字符串的处理 if (value instanceof String){ // 对前后长度进行设置 默认 结尾只展示四个字符 int prefixNoMaskLen = 0; int suffixNoMaskLen = 4; return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol); } return ""; } public String fixedPhone(Object value, String symbol) { //针对字符串的处理 if (value instanceof String){ // 对前后长度进行设置 默认 结尾只展示四个字符 int prefixNoMaskLen = 0; int suffixNoMaskLen = 4; return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol); } return ""; } public String mobilePhone(Object value, String symbol) { //针对字符串的处理 if (value instanceof String){ // 对前后长度进行设置 默认 开头只展示三个字符 结尾只展示四个字符 int prefixNoMaskLen = 3; int suffixNoMaskLen = 4; return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol); } return ""; } public String address(Object value, String symbol) { //针对字符串的处理 if (value instanceof String){ // 对前后长度进行设置 默认 开头只展示九个字符 int prefixNoMaskLen = 9; int suffixNoMaskLen = 0; return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol); } return ""; } public String email(Object value, String symbol) { //针对字符串的处理 if (value instanceof String){ // 对前后长度进行设置 默认 开头只展示一个字符 结尾只展示@及后面的地址 int prefixNoMaskLen = 1; int suffixNoMaskLen = 4; String s = (String) value; if (StringUtils.isBlank(s)) { return ""; } // 获取最后一个@ int lastIndex = StringUtils.lastIndexOf(s, "@"); if (lastIndex <= 1) { return s; } else { suffixNoMaskLen = s.length() - lastIndex; } return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol); } return ""; } public String bankCard(Object value, String symbol) { //针对字符串的处理 if (value instanceof String){ // 对前后长度进行设置 默认 开头只展示六个字符 结尾只展示四个字符 int prefixNoMaskLen = 6; int suffixNoMaskLen = 4; return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol); } return ""; } public String password(Object value,String symbol) { //针对字符串的处理 if (value instanceof String){ // 对前后长度进行设置 默认 开头只展示六个字符 结尾只展示四个字符 int prefixNoMaskLen = 0; int suffixNoMaskLen = 0; return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol); } return ""; }}
public class User { private static final long serialVersionUID = 1L; private Long userId; @Sensitive(type = SensitiveType.CUSTOMER,prefixNoMaskLen = 2,suffixNoMaskLen = 1) private String nickName; @Sensitive(type = SensitiveType.CHINESE_NAME) private String userName; @Sensitive(type = SensitiveType.ID_CARD_NUM) private String identityCard; @Sensitive(type = SensitiveType.MOBILE_PHONE) private String phoneNumber;}
// 脱敏对象User user = new User();...... DesensitizedUtils<User> desensitizedUtils = new DesensitizedUtils<>(User.class); desensitizedUtils.desensitization(user);//脱敏队列List<User> users = new ArrayList<>();...... DesensitizedUtils<User> desensitizedUtils = new DesensitizedUtils<>(User.class); desensitizedUtils.desensitizedList(users);
以上就是关于“SpringBoot怎么新增脱敏功能”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网精选频道。
--结束END--
本文标题: SpringBoot怎么新增脱敏功能
本文链接: https://lsjlt.com/news/346525.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0