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

简介: 通过注解、切面、反射实现返回信息脱敏
/*** projectName micro-util* package com.open.util.handler.aspect* className SensitiveMethod  * * description: 标注于需要处理的方法上* ** @author joshua_liu* @date 2021/12/20 10:11*/@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documentedpublic@interfaceSensitiveMethod {
/*** 是否启用*/booleanenabled() defaulttrue;
booleanencParamEnabled() defaultfalse;
booleanencResultEnabled() defaultfalse;
booleansensitiveResultEnabled() defaulttrue;
ClasssensitiveClass() defaultInteger.class;
SensitiveMapMeta[] sensitiveMapMeta() default {};
}
/*** projectName micro-util* package com.open.util.handler.aspect* className SensitiveMapMeta  * * description: 标注于需要处理的方法上,当返回类型是map时标注* ** @author joshua_liu* @date 2021/12/20 10:11*/@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documentedpublic@interfaceSensitiveMapMeta {
Stringkey() default"";
ClasssensitiveClass() defaultInteger.class;
booleanencResultEnabled() defaultfalse;
booleansensitiveResultEnabled() defaulttrue;
}
/*** projectName micro-util* package com.open.util.handler.aspect* className EncMeta  * * description: 标注于需要加密的字段上* ** @author joshua_liu* @date 2021/12/20 10:11*/@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documentedpublic@interfaceEncMeta {
}
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documentedpublic@interfaceEncSubMeta {
}
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documentedpublic@interfaceSensitiveMeta {
/*** 开始替换位置*/intrpStart() default0;
/*** 结束替换位置*/intrpEnd() default1;
/*** 替换成的符号*/StringrpSymbol() default"*";
}
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documentedpublic@interfaceSensitiveSubMeta {
}
@Slf4j@Aspect@Order(Ordered.LOWEST_PRECEDENCE-100)
@Component@ConditionalOnProperty(prefix="open.advice.sensitive", name="enabled", havingValue="true")
publicclassSensitiveInfoAspect {
@AutowiredprivateListsensitiveManageChain=newCopyOnWriteArrayList<>();
@AutowiredprivateTransSensitiveFieldProvidertransSensitiveField;
@Pointcut("@annotation(com.open.util.entity.annotation.SensitiveMethod)")
privatevoidallAnnotationMethod() {
    }
/*** description: PARAMETER 不支持,所有加密的数据都放到body中* //        Object[] args = point.getArgs();* //        Annotation[][] paramAnnotations = method.getParameterAnnotations();* //        for (int i = 0; i < paramAnnotations.length; i++) {* //            for (int j = 0; j < paramAnnotations[i].length; j++) {* //                Annotation currentAnnotation = paramAnnotations[i][j];* //                Object arg = args[i];* //                if (currentAnnotation instanceof EncMeta && Objects.nonNull(arg) && arg instanceof String) {* //                    log.debug("Source args[{}] value {}", i, arg);* //                    args[i] = encManager.decField(String.valueOf(arg));* //                }* //            }* //        }** @param point* @return {@link Object}* @throws* @author joshua_liu* @date 2021/12/21 17:53*/@Around("allAnnotationMethod()")
publicObjectdoAround(ProceedingJoinPointpoint) throwsThrowable {
MethodSignaturesignature= (MethodSignature) point.getSignature();
Methodmethod=signature.getMethod();
SensitiveMethodsensitiveMethodMeta=method.getAnnotation(SensitiveMethod.class);
if (sensitiveMethodMeta.encParamEnabled()) {
ArrayListdecFields=newArrayList<>();
Object[] args=point.getArgs();
Annotation[][] paramAnnotations=method.getParameterAnnotations();
for (inti=0; i<paramAnnotations.length; i++) {
for (intj=0; j<paramAnnotations[i].length; j++) {
AnnotationcurrentAnnotation=paramAnnotations[i][j];
Objectarg=args[i];
if (currentAnnotationinstanceofRequestBody&&Objects.nonNull(arg)) {
Field[] fields=arg.getClass().getDeclaredFields();
transSensitiveField.classifyFields(arg.getClass(), fields, decFields, null, null, null);
log.debug("Source args[{}] value {}", i, arg);
decFields.forEach(e->transSensitiveField.decField(e, arg));
                    }
                }
            }
        }
ObjecttempObj=point.proceed();
if (!sensitiveMethodMeta.enabled() ||Objects.isNull(tempObj)) {
returntempObj;
        }
ListsortedChain=sensitiveManageChain.stream()
                .sorted(Comparator.comparing(SensitiveManageChain::getOrder)).collect(Collectors.toList());
for (inti=0; i<sortedChain.size() -1; i++) {
sortedChain.get(i).setNextChain(sortedChain.get(i+1));
        }
returnsortedChain.get(0).sensitiveHand(tempObj, method, sensitiveMethodMeta, null, newArrayList<>(), newArrayList<>(),
newArrayList<>(), newArrayList<>(), sortedChain);
    }
}



相关文章
|
存储 SQL Java
Java反射读取注解信息
Java反射读取注解信息
69 0
|
6月前
|
存储 Java 数据库
整合切面,参数拦截+过滤
整合切面,参数拦截+过滤
|
缓存 开发框架 安全
AOP的另类用法 (权限校验&&自定义注解)
告别了OOP编程, 迎来了一个新的AOP编程时代👍👍👍, 最近有同学问我AOP除了写日志还能干什么, 其实AOP能干的事情挺多的, 可能只是他们写的代码中暂时用不到. 其实如果当我们写一些简单的程序的时候, SpringSecurity完全用不到的时候, 就可以使用AOP与自定义注解来为角色的访问权限进行鉴定, 绝对比Security更轻量👉👉👉 我们在接触框架的时候经常会用到注解, 但是我们自己自定义注解的情况比较少, 一般都是配合切面编程使用, 一起来看看吧
203 0
|
JSON Java 数据库连接
一个注解优雅的实现 接口数据脱敏
一个注解优雅的实现 接口数据脱敏
接口参数注解验证案例
写作缘由 写接口的时候经常会有请求体里某字段不为null的需求;也有使用一个dto对象,但是插入和修改都想使用这个dto,那这样的话判断条件就不一样,因为修改操作必须有ID,所以参数验证还是挺麻烦的。所以写个demo记录一下,亲测可用。
137 0
AOP + 注解 实现通用的接口参数校验
写移动端接口的时候,为了校验参数,传统的做法是加各种判断,写了很多重复的代码,而且也不美观。为了增加代码复用性,美观的校验参数,采用AOP + 注解的方式来实现接口的参数校验(使用拦截器也可以实现),在需要校验参数的方法上加上自定义的注解即可。
305 0
AOP + 注解 实现通用的接口参数校验
|
Java Spring 容器
通过反射获得并调用类的方法导致@Autowired注入失效的解决方案
通过反射获得并调用类的方法导致@Autowired注入失效的解决方案
524 0
|
JavaScript 前端开发 Java
注解与反射5.反射概述
注解与反射5.反射概述
|
XML Java 数据格式
注解与反射关联的应用(三)
注解与反射关联的应用(三)
注解与反射关联的应用(三)