栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot-AOP记录日志+脱敏

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot-AOP记录日志+脱敏

目录
    • 1. 引入依赖
    • 2. 配置文件
    • 3. 注解类
    • 4. 切面类
    • 5. 需要脱敏的实体类
    • 6. 查看日志打印

1. 引入依赖
//脱敏工具包
implementation 'com.github.houbb:sensitive-core:0.0.9'
implementation 'com.alibaba:fastjson:1.2.75'
2. 配置文件
  • 配置需要脱敏的字段名称
exclude.properties=name,phoneNo,password
3. 注解类
package com.example.fisher.gradledemo.annotation;

import java.lang.annotation.documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@documented
public @interface Log {

}

4. 切面类
  • 提供2种方式脱敏
  • fastjson脱敏字段不显示,sensitive-core将带有脱敏注解的属性字段部分显示***
package com.example.fisher.gradledemo.aspectj;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.support.spring.PropertyPreFilters;
import com.example.fisher.gradledemo.dto.LogInfo;
import com.github.houbb.sensitive.core.api.SensitiveUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
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.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Slf4j
@Component
@Aspect
public class LogAspect {

    
    @Value("${exclude.properties}")
    private Set properties;

    public static final String DESENSITISE_MSG = "******";

    
    public PropertyPreFilters.MySimplePropertyPreFilter excludePropertyPreFilter() {
        return new PropertyPreFilters().addFilter().addExcludes(properties.toArray(String[]::new));
    }

    
    @Pointcut("execution(public * com.example.fisher.gradledemo.sysuser.controller.*.*(..))")
    public void pc1() {}

    
    @Pointcut("@annotation(com.example.fisher.gradledemo.annotation.Log)")
    public void pc2() {}

    @Around("pc1()||pc2()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        // 入参使用fastjson进行脱敏,脱敏字段不显示
        LogInfo loginfo = getLoginfo(point);
        Object result = point.proceed();
        // 返回值使用sensitive-core工具包进行脱敏,脱敏字段部分显示***
        Object deSensitiveObject = getDeSensitiveObject2(null, result);
        loginfo.setResult(String.valueOf(deSensitiveObject));
        log.info("{}", loginfo);
        return result;
    }

    
    @AfterThrowing(value = "pc1()||pc2()", throwing = "e")
    public void afterThrowing(JoinPoint point, Throwable e) {
        LogInfo loginfo = getLoginfo(point);
        log.error("{},{}", loginfo, e);
    }

    
    private LogInfo getLoginfo(JoinPoint point) {
        String className = point.getTarget().getClass().getName();
        MethodSignature signature = (MethodSignature)point.getSignature();
        String methodName = signature.getName();
        HttpServletRequest request = getRequestAttributes().getRequest();
        LogInfo logInfo = new LogInfo();
        logInfo.setClassName(className);
        logInfo.setMethodName(methodName);
        logInfo.setUrl(request.getRequestURI());
        logInfo.setHttpMethod(request.getMethod());
        logInfo.setIpAddress(request.getRemoteAddr());
        // 获取入参
        Object[] args = point.getArgs();
        String[] parameterNames = signature.getParameterNames();
        Map inputParam = getInputParam(parameterNames, args);
        logInfo.setParameter(String.valueOf(inputParam));
        return logInfo;
    }

    
    private Map getInputParam(String[] parameterNames, Object[] args) {
        Map map = new HashMap<>(16);
        for (int i = 0; i < parameterNames.length; i++) {
            String parameterName = parameterNames[i];
            Object arg = args[i];
            Object deSensitiveObject = getDeSensitiveObject(parameterName, arg);
            map.put(parameterName, deSensitiveObject);
        }
        return map;
    }

    
    private Object getDeSensitiveObject(String parameterName, Object arg) {
        Class clazz = arg.getClass();
        if (arg instanceof MultipartFile || arg instanceof HttpServletRequest || arg instanceof HttpServletResponse) {
            return "";
        } else if (String.class.isAssignableFrom(clazz)) {
            if (properties.contains(parameterName)) {
                return DESENSITISE_MSG;
            }
        } else if (Collection.class.isAssignableFrom(clazz) || Map.class.isAssignableFrom(clazz)) {
            arg = JSONObject.toJSONString(arg, excludePropertyPreFilter());
        } else {
            arg = JSONObject.toJSONString(arg, excludePropertyPreFilter());
        }
        return arg;
    }

    
    private Object getDeSensitiveObject2(String parameterName, Object arg) {
        Class clazz = arg.getClass();
        if (arg instanceof MultipartFile || arg instanceof HttpServletRequest || arg instanceof HttpServletResponse) {
            return "";
        } else if (String.class.isAssignableFrom(clazz)) {
            if (properties.contains(parameterName)) {
                return DESENSITISE_MSG;
            }
        } else if (Collection.class.isAssignableFrom(clazz) ) {
            arg = SensitiveUtil.desCopyCollection((Collection)arg);
        }else if (Map.class.isAssignableFrom(clazz)){
            HashMap hashMap = new HashMap<>(16);
            ((Map)arg).forEach((s, o) -> {
                if (properties.contains(String.valueOf(s))) {
                    hashMap.put(s, DESENSITISE_MSG);
                } else {
                    hashMap.put(s, o);
                }
            });
            arg = hashMap;
        }else {
            //当做对象处理
            arg = SensitiveUtil.desJson(arg);
        }
        return arg;
    }


    
    public ServletRequestAttributes getRequestAttributes() {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        return (ServletRequestAttributes)attributes;
    }

}

5. 需要脱敏的实体类
  • 在需要脱敏的属性上添加注解,例如@SensitiveStrategyChineseName,@SensitiveStrategyPhone等
  • 这里使用了mybatis-plus
package com.example.fisher.gradledemo.sysuser.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.houbb.sensitive.annotation.strategy.SensitiveStrategyChineseName;
import lombok.Data;

import java.io.Serializable;
import java.time.LocalDateTime;

@SuppressWarnings("serial")
@Data
public class SysUser extends Model {

    @TableId(type = IdType.AUTO)
    private Long userId;

    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    @TableField(fill = FieldFill.UPDATE)
    private LocalDateTime updateTime;

    @TableLogic
    @JsonIgnore
    private Integer delFlag;

    @SensitiveStrategyChineseName
    private String name;

    private Integer age;

    private String interest;

    
    @Override
    public Serializable pkVal() {
        return this.userId;
    }
    
}
6. 查看日志打印

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/643621.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号