通过注解、切面、反射实现返回信息脱敏(二)

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 通过注解、切面、反射实现返回信息脱敏
/*** projectName micro-util* package  com.open.util.handler.provider* className TransSensitiveFieldProvider* <p>* description: 敏感字段转换* </p>** @author <a href="mailto:joshualwork@163.com">joshua_liu</a>* @date 2021/12/21 9:31*/@Slf4j@Component@ConditionalOnProperty(prefix="open.advice.sensitive", name="enabled", havingValue="true")
publicclassTransSensitiveFieldProvider {
@AutowiredprivateSensitiveEncProvidersensitiveEncProvider;
@SuppressWarnings("unchecked")
publicvoidcollectionObjSensitive(ArrayListcollectionObj, List<Field>senFields) {
collectionObj.forEach(eleObj->senFields.forEach(senField->sensitiveField(senField, eleObj)));
    }
@SuppressWarnings("unchecked")
publicvoidcollectionObjEnc(ArrayListcollectionObj, List<Field>encFields) {
collectionObj.forEach(eleObj->encFields.forEach(encField->encField(encField, eleObj)));
    }
publicvoidsensitiveField(FieldsenField, Objecttarget) {
try {
senField.setAccessible(true);
ObjecttempFieldValue=senField.get(target);
StringstringTempFieldValue=String.valueOf(tempFieldValue);
StringnullStr="null";
if (Objects.nonNull(stringTempFieldValue) &&!Objects.equals(nullStr, stringTempFieldValue)) {
SensitiveMetasensitiveMeta=senField.getAnnotation(SensitiveMeta.class);
intend=Math.min(stringTempFieldValue.length(), sensitiveMeta.rpEnd());
StringsubStr=stringTempFieldValue.substring(sensitiveMeta.rpStart(), end);
senField.set(target, stringTempFieldValue.replace(subStr, sensitiveMeta.rpSymbol()));
            }
        } catch (IllegalAccessExceptionex) {
log.error("Sensitive catch exception:", ex);
        }
    }
publicvoidencField(FieldencField, Objecttarget) {
try {
encField.setAccessible(true);
ObjecttempFieldValue=encField.get(target);
StringstringTempFieldValue=String.valueOf(tempFieldValue);
StringnullStr="null";
if (Objects.nonNull(stringTempFieldValue) &&!Objects.equals(nullStr, stringTempFieldValue)) {
StringaftEncValue=sensitiveEncProvider.encField(stringTempFieldValue);
encField.set(target, aftEncValue);
            }
        } catch (Exceptionex) {
log.error("Enc field catch exception:", ex);
        }
    }
publicvoiddecField(FielddecField, Objecttarget) {
try {
decField.setAccessible(true);
ObjecttempFieldValue=decField.get(target);
StringstringTempFieldValue=String.valueOf(tempFieldValue);
StringnullStr="null";
if (Objects.nonNull(stringTempFieldValue) &&!Objects.equals(nullStr, stringTempFieldValue)) {
StringaftEncValue=sensitiveEncProvider.decField(stringTempFieldValue);
decField.set(target, aftEncValue);
            }
        } catch (Exceptionex) {
log.error("Dec field catch exception:", ex);
        }
    }
publicvoidclassifyFields(Class<?>sourceClass, Field[] fields, ArrayList<Field>encFields,
ArrayList<Field>senFields, ArrayList<Field>subEncFields, ArrayList<Field>subSenFields) {
List<Field>fieldList=Stream.of(fields).collect(Collectors.toList());
if (sourceClass.isAnnotationPresent(SensitiveMeta.class)) {
if (Objects.nonNull(senFields)) {
senFields.addAll(fieldList);
            }
fieldList.forEach(e-> {
if (e.isAnnotationPresent(SensitiveSubMeta.class) &&Objects.nonNull(senFields)) {
senFields.remove(e);
                }
if (e.isAnnotationPresent(SensitiveSubMeta.class) &&Objects.nonNull(subSenFields)) {
subSenFields.add(e);
                }
            });
        }
if (sourceClass.isAnnotationPresent(EncMeta.class)) {
if (!CollectionUtils.isEmpty(encFields)) {
encFields.addAll(fieldList);
            }
fieldList.forEach(e-> {
if (e.isAnnotationPresent(EncSubMeta.class) &&Objects.nonNull(encFields)) {
encFields.remove(e);
                }
if (e.isAnnotationPresent(EncSubMeta.class) &&Objects.nonNull(subEncFields)) {
subEncFields.add(e);
                }
            });
        }
fieldList.forEach(e-> {
booleanannotationSenPresent=e.isAnnotationPresent(SensitiveMeta.class) &&!sourceClass.isAnnotationPresent(SensitiveMeta.class);
booleanannotationEncPresent=e.isAnnotationPresent(EncMeta.class) &&!sourceClass.isAnnotationPresent(EncMeta.class);
if (annotationEncPresent&&annotationSenPresent) {
encFields.add(e);
senFields.add(e);
            } elseif (annotationEncPresent) {
encFields.add(e);
            } elseif (annotationSenPresent) {
senFields.add(e);
            }
        });
    }
}






/*** projectName micro-util* package com.open.util.handler.aspect.sensitive4chain* className SensitiveManageChain* <p>* description:* </p>** @author <a href="mailto:joshualwork@163.com">joshua_liu</a>* @date 2021/12/21 9:17*/publicinterfaceSensitiveManageChainextendsOrdered {
/*** description:** @param sourceResult  原返回结果* @param method        当前处理方法* @param sensitiveMeta 敏感信息方法元数据* @param sourceMapMeta* @param senFields     敏感字段集合* @param encFields     加密字段集合* @param subEncFields* @param subSenFields* @param sortedChain   有序链路* @return {@link Object} 处理后的返回结果* @throws* @author <a href="mailto:joshualwork@163.com">joshua_liu</a>* @date 2021/12/21 9:19*/ObjectsensitiveHand(ObjectsourceResult, Methodmethod, SensitiveMethodsensitiveMeta, SensitiveMapMetasourceMapMeta, ArrayList<Field>senFields, ArrayList<Field>encFields, ArrayList<Field>subEncFields, ArrayList<Field>subSenFields, List<SensitiveManageChain>sortedChain);
/*** description: 设置下一个链路** @param chain 下一个链路* @author <a href="mailto:joshualwork@163.com">joshua_liu</a>* @date 2021/12/21 9:42*/voidsetNextChain(SensitiveManageChainchain);
}






/*** projectName micro-util* package com.open.util.handler.aspect.sensitive4chain* className CollectionResultHandler* <p>* description:* </p>** @author <a href="mailto:joshualwork@163.com">joshua_liu</a>* @date 2021/12/21 10:05*/@Data@Slf4j@Component@ConditionalOnProperty(prefix="open.advice.sensitive", name="enabled", havingValue="true")
publicclassCollectionManageChainimplementsSensitiveManageChain {
privateintorder;
privateSensitiveManageChainnextChain;
@AutowiredprivateTransSensitiveFieldProvidertransSensitiveField;
/*** description:** @param sourceResult  原返回结果* @param method        当前处理方法* @param sensitiveMeta 敏感信息方法元数据* @param sourceMapMeta* @param senFields     敏感字段集合* @param encFields     加密字段集合* @param subEncFields* @param subSenFields* @param sortedChain   有序链路* @return {@link Object} 处理后的返回结果* @throws* @author <a href="mailto:joshualwork@163.com">joshua_liu</a>* @date 2021/12/21 9:19*/@Override@SuppressWarnings("unchecked")
publicObjectsensitiveHand(ObjectsourceResult, Methodmethod, SensitiveMethodsensitiveMeta, SensitiveMapMetasourceMapMeta, ArrayList<Field>senFields, ArrayList<Field>encFields,
ArrayList<Field>subEncFields, ArrayList<Field>subSenFields, List<SensitiveManageChain>sortedChain) {
if (Objects.isNull(sourceResult)) {
returnnull;
        }
if (sourceResultinstanceofCollection) {
ArrayListcollectionObj=newArrayList();
ClasssensitiveClass=Objects.nonNull(sourceMapMeta) ?sourceMapMeta.sensitiveClass() : sensitiveMeta.sensitiveClass();
if (Objects.equals(sensitiveClass, Integer.class)) {
log.warn("Return collection need to config sensitiveClass() ,but not found method {},please check you config.", method);
returnsourceResult;
            }
Field[] fields=sensitiveClass.getDeclaredFields();
if (fields.length<=0) {
returnsourceResult;
            }
Collectioncollection= (Collection) sourceResult;
if (!CollectionUtils.isEmpty(collection)) {
collectionObj.addAll(collection);
            }
transSensitiveField.classifyFields(sensitiveClass, fields, encFields, senFields, subEncFields, subSenFields);
booleansenResultEnabled=Objects.nonNull(sourceMapMeta) ?sourceMapMeta.sensitiveResultEnabled() : sensitiveMeta.sensitiveResultEnabled();
if (sensitiveMeta.sensitiveResultEnabled() &&!CollectionUtils.isEmpty(senFields)) {
transSensitiveField.collectionObjSensitive(collectionObj, senFields);
            }
if (sensitiveMeta.encResultEnabled() &&!CollectionUtils.isEmpty(encFields)) {
transSensitiveField.collectionObjEnc(collectionObj, encFields);
            }
returncollectionObj;
        }
if (Objects.isNull(nextChain)) {
returnsourceResult;
        }
returnnextChain.sensitiveHand(sourceResult, method, sensitiveMeta, sourceMapMeta, senFields, encFields, subEncFields, subSenFields, sortedChain);
    }
}






/*** projectName micro-util* package com.open.util.handler.aspect.sensitive4chain* classname  PageManageChain* <p>* description* </p>** @author <a href="mailto:joshualwork@163.com">joshua_liu</a>* @date 2021/12/22 23:09*/@Data@Slf4j@Component@ConditionalOnProperty(prefix="open.advice.sensitive", name="enabled", havingValue="true")
publicclassPageManageChainimplementsSensitiveManageChain {
privateintorder;
privateSensitiveManageChainnextChain;
@AutowiredprivateTransSensitiveFieldProvidertransSensitiveField;
/*** description:** @param sourceResult  原返回结果* @param method        当前处理方法* @param sensitiveMeta 敏感信息方法元数据* @param sourceMapMeta* @param senFields     敏感字段集合* @param encFields     加密字段集合* @param sortedChain   有序链路* @return {@link Object} 处理后的返回结果* @throws* @author <a href="mailto:joshualwork@163.com">joshua_liu</a>* @date 2021/12/21 9:19*/@Override@SuppressWarnings("unchecked")
publicObjectsensitiveHand(ObjectsourceResult, Methodmethod, SensitiveMethodsensitiveMeta, SensitiveMapMetasourceMapMeta, ArrayList<Field>senFields, ArrayList<Field>encFields,
ArrayList<Field>subEncFields, ArrayList<Field>subSenFields, List<SensitiveManageChain>sortedChain) {
if (Objects.isNull(sourceResult)) {
returnnull;
        }
if (sourceResultinstanceofPage) {
ArrayListcollectionObj=newArrayList();
Pageablepageable;
longtotal;
ClasssensitiveClass=sensitiveMeta.sensitiveClass();
if (Objects.equals(sensitiveClass, Integer.class)) {
log.warn("Return page need to config SensitiveMethod.sensitiveClass() ,but not found method {},please check you config.", method);
returnsourceResult;
            }
Field[] fields=sensitiveMeta.sensitiveClass().getDeclaredFields();
if (fields.length<=0) {
returnsourceResult;
            }
PageModelpageResult= (PageModel) sourceResult;
total=pageResult.getTotal();
pageable=pageResult.getPageable();
Collectioncollection=pageResult.getContent();
if (!CollectionUtils.isEmpty(collection)) {
collectionObj.addAll(collection);
            }
transSensitiveField.classifyFields(sourceResult.getClass(), fields, encFields, senFields, subEncFields, subSenFields);
if (sensitiveMeta.sensitiveResultEnabled() &&!CollectionUtils.isEmpty(senFields)) {
transSensitiveField.collectionObjSensitive(collectionObj, senFields);
returnPageModel.pageSuccess(collectionObj, pageable, total);
            }
if (sensitiveMeta.encResultEnabled() &&!CollectionUtils.isEmpty(encFields)) {
transSensitiveField.collectionObjEnc(collectionObj, encFields);
            }
        }
if (Objects.isNull(nextChain)) {
returnsourceResult;
        }
returnnextChain.sensitiveHand(sourceResult, method, sensitiveMeta, sourceMapMeta, senFields, encFields,
subEncFields, subSenFields, sortedChain);
    }
}




/*** projectName micro-util* package com.open.util.handler.aspect.sensitive4chain* className GenericManageChain* <p>* description:* </p>** @author <a href="mailto:joshualwork@163.com">joshua_liu</a>* @date 2021/12/21 10:12*/@Data@Slf4j@Component@ConditionalOnProperty(prefix="open.advice.sensitive", name="enabled", havingValue="true")
publicclassGenericManageChainimplementsSensitiveManageChain {
privateintorder=Ordered.LOWEST_PRECEDENCE-1000;
privateSensitiveManageChainnextChain=null;
@AutowiredprivateTransSensitiveFieldProvidertransSensitiveField;
/*** description:** @param sourceResult  原返回结果* @param method        当前处理方法* @param sensitiveMeta 敏感信息方法元数据* @param sourceMapMeta* @param senFields     敏感字段集合* @param encFields     加密字段集合* @param subEncFields* @param subSenFields* @param sortedChain   有序链路* @return {@link Object} 处理后的返回结果* @throws* @author <a href="mailto:joshualwork@163.com">joshua_liu</a>* @date 2021/12/21 9:19*/@OverridepublicObjectsensitiveHand(ObjectsourceResult, Methodmethod, SensitiveMethodsensitiveMeta, SensitiveMapMetasourceMapMeta, ArrayList<Field>senFields, ArrayList<Field>encFields,
ArrayList<Field>subEncFields, ArrayList<Field>subSenFields, List<SensitiveManageChain>sortedChain) {
if (Objects.isNull(sourceResult)) {
returnnull;
        }
Class<?>sourceClass=sourceResult.getClass();
Field[] fields=sourceResult.getClass().getDeclaredFields();
if (fields.length<=0) {
returnsourceResult;
        }
transSensitiveField.classifyFields(sourceClass, fields, encFields, senFields, subEncFields, subSenFields);
if (sensitiveMeta.sensitiveResultEnabled()) {
senFields.forEach(field->transSensitiveField.sensitiveField(field, sourceResult));
        }
if (sensitiveMeta.encResultEnabled()) {
encFields.forEach(field->transSensitiveField.encField(field, sourceResult));
        }
returnsourceResult;
    }
}
相关文章
|
存储 SQL Java
Java反射读取注解信息
Java反射读取注解信息
62 0
|
Java 编译器 测试技术
手写反射实现读取自定义注解中的属性值
手写反射实现读取自定义注解中的属性值
|
Java 数据安全/隐私保护
使用反射实现@RequestBody的参数校验功能
springboot中对实体类参数中属性进行校验一般都是使用javax.validation中提供的注解
|
JSON Java 数据库连接
一个注解优雅的实现 接口数据脱敏
一个注解优雅的实现 接口数据脱敏
接口参数注解验证案例
写作缘由 写接口的时候经常会有请求体里某字段不为null的需求;也有使用一个dto对象,但是插入和修改都想使用这个dto,那这样的话判断条件就不一样,因为修改操作必须有ID,所以参数验证还是挺麻烦的。所以写个demo记录一下,亲测可用。
130 0
AOP + 注解 实现通用的接口参数校验
写移动端接口的时候,为了校验参数,传统的做法是加各种判断,写了很多重复的代码,而且也不美观。为了增加代码复用性,美观的校验参数,采用AOP + 注解的方式来实现接口的参数校验(使用拦截器也可以实现),在需要校验参数的方法上加上自定义的注解即可。
283 0
AOP + 注解 实现通用的接口参数校验
|
JavaScript 前端开发 Java
注解与反射5.反射概述
注解与反射5.反射概述
|
XML Java 数据格式
注解与反射关联的应用(三)
注解与反射关联的应用(三)
注解与反射关联的应用(三)
|
Java Spring
自定义注解实现方式解析
自定义注解实现方式解析
230 0
自定义注解实现方式解析