package com.bt.sensitive.aop;
import com.bt.sensitive.aop.annotation.Decryption;
import com.bt.sensitive.aop.annotation.EnAndDecryption;
import com.bt.sensitive.aop.annotation.Encryption;
import com.bt.sensitive.aop.annotation.SensitiveMethod;
import com.bt.sensitive.aop.type.ProcessTime;
import com.bt.sensitive.aop.type.SensitiveProcessWay;
import com.bt.sensitive.aop.type.ReturnType;
import com.bt.sensitive.aop.utils.SensitiveProcess;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Aspect
@ConditionalOnProperty(name = "sensitive.enable",havingValue = "true")
@Slf4j
@Component
public class SensitiveInformationAspect implements Ordered {
@Resource
private Map
sensitiveProcessMap;
@Value("${order.sensitiveInformationAspect:2147483647}")
private Integer order;
@Pointcut("@annotation(com.bt.sensitive.aop.annotation.SensitiveMethod)")
private void pointCut(){
}
@Around("pointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
SensitiveMethod sensitiveMethod = method.getAnnotation(SensitiveMethod.class);
ProcessTime me = sensitiveMethod.processTime();
if(ProcessTime.BEFORE.equals(me)){
Object[] args = changeArgsBefore(joinPoint.getArgs(), method,sensitiveMethod);
return joinPoint.proceed(args);
}
if(ProcessTime.AFTER.equals(me)){
Object result = joinPoint.proceed();
return changeResultAfter(result,sensitiveMethod);
}
if(ProcessTime.ALL.equals(me)){
Object[] args = changeArgsBefore(joinPoint.getArgs(), method,sensitiveMethod);
return changeResultAfter(joinPoint.proceed(args),sensitiveMethod);
}
return joinPoint.proceed();
}
private Object[] changeArgsBefore(Object[] args,Method method,SensitiveMethod sensitiveMethod) {
Annotation[][] annotations = method.getParameterAnnotations();
for(int i=0;i fieldList = new ArrayList<>();
Class> aClass = arg.getClass();
while(aClass!=null){
fieldList.addAll(Arrays.asList(aClass.getDeclaredFields()));
aClass = aClass.getSuperclass();
}
for(Field field : fieldList){
field.setAccessible(true);
EnAndDecryption enAndDecryption = field.getAnnotation(EnAndDecryption.class);
if(enAndDecryption != null){
process(field,arg,enAndDecryption,time,utilName,encryptMethodName,decryptMethodName);
continue;
}
Encryption encryption = field.getAnnotation(Encryption.class);
if(encryption!=null){
process(field,arg,encryption,time,utilName,encryptMethodName,decryptMethodName);
continue;
}
Decryption decryption = field.getAnnotation(Decryption.class);
if(decryption!=null){
process(field,arg,decryption,time,utilName,encryptMethodName,decryptMethodName);
}
}
}
@SuppressWarnings("unchecked")
private void process(Field field,Object arg,Annotation annotation,String time,String utilName,String encryptMethodName,String decryptMethodName){
try{
Object o = field.get(arg);
if(o!=null){
if(o instanceof List){
List