package com.zbkj.admin.aspect; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.servlet.ServletUtil; import com.alibaba.fastjson.JSON; import com.zbkj.admin.filter.TokenComponent; import com.zbkj.common.annotation.LogControllerAnnotation; import com.zbkj.admin.service.ActionService; import com.zbkj.common.model.record.SensitiveMethodLog; import com.zbkj.common.utils.SpringUtil; import com.zbkj.common.vo.LoginUserVo; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.HandlerMapping; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Map; import java.util.Objects; /** * 敏感操作日志记录Aop * +---------------------------------------------------------------------- * | CRMEB [ CRMEB赋能开发者,助力企业发展 ] * +---------------------------------------------------------------------- * | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved. * +---------------------------------------------------------------------- * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权 * +---------------------------------------------------------------------- * | Author: CRMEB Team * +---------------------------------------------------------------------- */ @Aspect @Component public class SensitiveLogAspect { private static final Logger LOGGER = LoggerFactory.getLogger(SensitiveLogAspect.class); @Resource private ActionService actionService; @Pointcut("@annotation(com.zbkj.common.annotation.LogControllerAnnotation)") public void controllerAspect() { } /** * 处理完请求后执行 * * @param joinPoint 切点 * @param logServiceAnnotation 注解 */ @AfterReturning(pointcut = "controllerAspect() && @annotation(logServiceAnnotation)", returning = "jsonResult") public void doAfterReturning(JoinPoint joinPoint, LogControllerAnnotation logServiceAnnotation, Object jsonResult) { addLog(joinPoint, logServiceAnnotation, jsonResult, null); } /** * 拦截异常操作 * * @param joinPoint 切点 * @param logServiceAnnotation 注解 * @param e 异常 */ @AfterThrowing(pointcut = "controllerAspect() && @annotation(logServiceAnnotation)", throwing = "e") public void doAfterThrowing(JoinPoint joinPoint, LogControllerAnnotation logServiceAnnotation, Exception e) { addLog(joinPoint, logServiceAnnotation, null, e); } private void addLog(JoinPoint joinPoint, LogControllerAnnotation logServiceAnnotation, Object jsonResult, Exception e) { if (!logServiceAnnotation.intoDB()) { return; } HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); // 获取当前用户 LoginUserVo loginUser = SpringUtil.getBean(TokenComponent.class).getLoginUser(request); Signature signature = joinPoint.getSignature(); SensitiveMethodLog methodLog = new SensitiveMethodLog(); if(ObjectUtil.isNotNull(loginUser)) { methodLog.setAdminId(loginUser.getUser().getId()); methodLog.setMerId(loginUser.getUser().getMerId()); methodLog.setAdminAccount(loginUser.getUser().getAccount()); }else{ methodLog.setAdminId(0); methodLog.setMerId(0); methodLog.setAdminAccount("unknown admin!"); } methodLog.setDescription(logServiceAnnotation.description()); methodLog.setMethodType(logServiceAnnotation.methodType().getName()); methodLog.setMethod(signature.getDeclaringTypeName() + "." + signature.getName() + "()"); methodLog.setRequestMethod(request.getMethod()); methodLog.setUrl(request.getRequestURI()); methodLog.setIp(ServletUtil.getClientIP(request)); String requestValue = getRequestValue(joinPoint, request.getMethod(), request); methodLog.setRequestParam(requestValue); if (jsonResult != null) { methodLog.setResult(StrUtil.sub(JSON.toJSONString(jsonResult), 0, 2000)); } methodLog.setStatus(0); if (e != null) { methodLog.setStatus(1); methodLog.setErrorMsg(StrUtil.sub(e.getMessage(), 0, 2000)); } actionService.addSensitiveLog(methodLog); } private String getRequestValue(JoinPoint joinPoint, String requestMethod, HttpServletRequest request) { if (requestMethod.equals("PUT") || requestMethod.equals("POST")) { return StrUtil.sub(argsArrayToString(joinPoint.getArgs()), 0, 2000); } else { Map paramsMap = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); return StrUtil.sub(paramsMap.toString(), 0, 2000); } } /** * 参数拼装 */ private String argsArrayToString(Object[] paramsArray) { StringBuilder params = new StringBuilder(); if (paramsArray != null && paramsArray.length > 0) { for (Object o : paramsArray) { if (!isFilterObject(o)) { Object jsonObj = JSON.toJSON(o); params.append(jsonObj.toString()).append(" "); } } } return params.toString().trim(); } /** * 判断是否需要过滤的对象。 * * @param o 对象信息。 * @return 如果是需要过滤的对象,则返回true;否则返回false。 */ public boolean isFilterObject(final Object o) { return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse; } }