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


/**
 * 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")
public class TransSensitiveFieldProvider {
    @Autowired
    private SensitiveEncProvider sensitiveEncProvider;

    @SuppressWarnings("unchecked")
    public void collectionObjSensitive(ArrayList collectionObj, List<Field> senFields) {
        collectionObj.forEach(eleObj -> senFields.forEach(senField -> sensitiveField(senField, eleObj)));
    }

    @SuppressWarnings("unchecked")
    public void collectionObjEnc(ArrayList collectionObj, List<Field> encFields) {
        collectionObj.forEach(eleObj -> encFields.forEach(encField -> encField(encField, eleObj)));
    }

    public void sensitiveField(Field senField, Object target) {
        try {
            senField.setAccessible(true);
            Object tempFieldValue = senField.get(target);
            String stringTempFieldValue = String.valueOf(tempFieldValue);
            String nullStr = "null";
            if (Objects.nonNull(stringTempFieldValue) && !Objects.equals(nullStr, stringTempFieldValue)) {
                SensitiveMeta sensitiveMeta = senField.getAnnotation(SensitiveMeta.class);
                int end = Math.min(stringTempFieldValue.length(), sensitiveMeta.rpEnd());
                String subStr = stringTempFieldValue.substring(sensitiveMeta.rpStart(), end);
                senField.set(target, stringTempFieldValue.replace(subStr, sensitiveMeta.rpSymbol()));
            }
        } catch (IllegalAccessException ex) {
            log.error("Sensitive catch exception:", ex);
        }
    }

    public void encField(Field encField, Object target) {
        try {
            encField.setAccessible(true);
            Object tempFieldValue = encField.get(target);
            String stringTempFieldValue = String.valueOf(tempFieldValue);
            String nullStr = "null";
            if (Objects.nonNull(stringTempFieldValue) && !Objects.equals(nullStr, stringTempFieldValue)) {
                String aftEncValue = sensitiveEncProvider.encField(stringTempFieldValue);
                encField.set(target, aftEncValue);
            }
        } catch (Exception ex) {
            log.error("Enc field catch exception:", ex);
        }
    }

    public void decField(Field decField, Object target) {
        try {
            decField.setAccessible(true);
            Object tempFieldValue = decField.get(target);
            String stringTempFieldValue = String.valueOf(tempFieldValue);
            String nullStr = "null";
            if (Objects.nonNull(stringTempFieldValue) && !Objects.equals(nullStr, stringTempFieldValue)) {
                String aftEncValue = sensitiveEncProvider.decField(stringTempFieldValue);
                decField.set(target, aftEncValue);
            }
        } catch (Exception ex) {
            log.error("Dec field catch exception:", ex);
        }
    }

    public void classifyFields(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 -> {
            boolean annotationSenPresent = e.isAnnotationPresent(SensitiveMeta.class) && !sourceClass.isAnnotationPresent(SensitiveMeta.class);
            boolean annotationEncPresent = e.isAnnotationPresent(EncMeta.class) && !sourceClass.isAnnotationPresent(EncMeta.class);
            if (annotationEncPresent && annotationSenPresent) {
                encFields.add(e);
                senFields.add(e);
            } else if (annotationEncPresent) {
                encFields.add(e);
            } else if (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
 */
public interface SensitiveManageChain extends Ordered {
    /**
     * 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
     */
    Object sensitiveHand(Object sourceResult, Method method, SensitiveMethod sensitiveMeta, SensitiveMapMeta sourceMapMeta, 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
     */
    void setNextChain(SensitiveManageChain chain);


}







/**
 * 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")
public class CollectionManageChain implements SensitiveManageChain {
    private int order;
    private SensitiveManageChain nextChain;
    @Autowired
    private TransSensitiveFieldProvider transSensitiveField;

    /**
     * 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")
    public Object sensitiveHand(Object sourceResult, Method method, SensitiveMethod sensitiveMeta, SensitiveMapMeta sourceMapMeta, ArrayList<Field> senFields, ArrayList<Field> encFields,
                                ArrayList<Field> subEncFields, ArrayList<Field> subSenFields, List<SensitiveManageChain> sortedChain) {
        if (Objects.isNull(sourceResult)) {
            return null;
        }
        if (sourceResult instanceof Collection) {
            ArrayList collectionObj = new ArrayList();
            Class sensitiveClass = 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);
                return sourceResult;
            }
            Field[] fields = sensitiveClass.getDeclaredFields();
            if (fields.length <= 0) {
                return sourceResult;
            }
            Collection collection = (Collection) sourceResult;
            if (!CollectionUtils.isEmpty(collection)) {
                collectionObj.addAll(collection);
            }
            transSensitiveField.classifyFields(sensitiveClass, fields, encFields, senFields, subEncFields, subSenFields);
            boolean senResultEnabled = 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);
            }
            return collectionObj;
        }
        if (Objects.isNull(nextChain)) {
            return sourceResult;
        }
        return nextChain.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")
public class PageManageChain implements SensitiveManageChain {
    private int order;
    private SensitiveManageChain nextChain;
    @Autowired
    private TransSensitiveFieldProvider transSensitiveField;

    /**
     * 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")
    public Object sensitiveHand(Object sourceResult, Method method, SensitiveMethod sensitiveMeta, SensitiveMapMeta sourceMapMeta, ArrayList<Field> senFields, ArrayList<Field> encFields,
                                ArrayList<Field> subEncFields, ArrayList<Field> subSenFields, List<SensitiveManageChain> sortedChain) {
        if (Objects.isNull(sourceResult)) {
            return null;
        }
        if (sourceResult instanceof Page) {
            ArrayList collectionObj = new ArrayList();
            Pageable pageable;
            long total;
            Class sensitiveClass = 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);
                return sourceResult;
            }
            Field[] fields = sensitiveMeta.sensitiveClass().getDeclaredFields();
            if (fields.length <= 0) {
                return sourceResult;
            }
            PageModel pageResult = (PageModel) sourceResult;
            total = pageResult.getTotal();
            pageable = pageResult.getPageable();
            Collection collection = 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);
                return PageModel.pageSuccess(collectionObj, pageable, total);
            }
            if (sensitiveMeta.encResultEnabled() && !CollectionUtils.isEmpty(encFields)) {
                transSensitiveField.collectionObjEnc(collectionObj, encFields);
            }
        }
        if (Objects.isNull(nextChain)) {
            return sourceResult;
        }
        return nextChain.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")
public class GenericManageChain implements SensitiveManageChain {
    private int order = Ordered.LOWEST_PRECEDENCE - 1000;
    private SensitiveManageChain nextChain = null;
    @Autowired
    private TransSensitiveFieldProvider transSensitiveField;

    /**
     * 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
    public Object sensitiveHand(Object sourceResult, Method method, SensitiveMethod sensitiveMeta, SensitiveMapMeta sourceMapMeta, ArrayList<Field> senFields, ArrayList<Field> encFields,
                                ArrayList<Field> subEncFields, ArrayList<Field> subSenFields, List<SensitiveManageChain> sortedChain) {
        if (Objects.isNull(sourceResult)) {
            return null;
        }
        Class<?> sourceClass = sourceResult.getClass();
        Field[] fields = sourceResult.getClass().getDeclaredFields();
        if (fields.length <= 0) {
            return sourceResult;
        }
        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));
        }
        return sourceResult;
    }
}
上一篇:python获取拉钩岗位信息


下一篇:微信支付报错误“出现了内部错误”或“无法找到证书路径” 解决方法