From 1571d47bfb698410a576a5c5168ef974958deb15 Mon Sep 17 00:00:00 2001 From: lijiahang Date: Thu, 12 Oct 2023 10:44:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E8=AE=B0=E5=BD=95=E5=8F=82=E6=95=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pom.xml | 7 + .../log/core/annotation/IgnoreParameter.java | 17 +++ .../log/core/annotation/OperatorLog.java | 13 ++ .../log/core/aspect/OperatorLogAspect.java | 141 +++++++++++++++--- .../log/core/constant/OperatorLogKeys.java | 4 + .../log/core/model/OperatorLogModel.java | 5 + .../operator/log/core/uitls/OperatorLogs.java | 30 +++- .../OrionDesensitizeAutoConfiguration.java | 13 +- .../core/annotation/Desensitize.java | 10 +- .../core/filter/DesensitizeValueFilter.java | 10 +- .../serializer/DesensitizeJsonSerializer.java | 16 +- .../controller/AuthenticationController.java | 8 +- .../operator/AuthenticationOperatorType.java | 30 ++++ .../infra/entity/domain/OperatorLogDO.java | 4 + .../entity/request/user/UserLoginRequest.java | 4 + .../module/infra/entity/vo/OperatorLogVO.java | 3 + .../infra/runner/InfraOperatorTypeRunner.java | 22 +++ .../infra/service/AuthenticationService.java | 5 +- .../impl/AuthenticationServiceImpl.java | 11 +- .../service/impl/SystemUserServiceImpl.java | 2 +- .../resources/mapper/OperatorLogMapper.xml | 3 +- 21 files changed, 322 insertions(+), 36 deletions(-) create mode 100644 orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/annotation/IgnoreParameter.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/define/operator/AuthenticationOperatorType.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/runner/InfraOperatorTypeRunner.java diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/pom.xml b/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/pom.xml index 869fe7ab..4db62a30 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/pom.xml +++ b/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/pom.xml @@ -26,6 +26,13 @@ org.springframework.boot spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-web + provided + \ No newline at end of file diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/annotation/IgnoreParameter.java b/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/annotation/IgnoreParameter.java new file mode 100644 index 00000000..3d472499 --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/annotation/IgnoreParameter.java @@ -0,0 +1,17 @@ +package com.orion.ops.framework.biz.operator.log.core.annotation; + +import java.lang.annotation.*; + +/** + * 用于记录操作日志时候 忽略参数 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/10/11 17:45 + */ +@Target({ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface IgnoreParameter { + +} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/annotation/OperatorLog.java b/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/annotation/OperatorLog.java index c69443dd..feea2bbe 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/annotation/OperatorLog.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/annotation/OperatorLog.java @@ -21,6 +21,19 @@ public @interface OperatorLog { */ String value(); + /** + * 是否记录参数 + *

+ * - {@link org.springframework.web.bind.annotation.RequestBody} + * - {@link org.springframework.web.bind.annotation.RequestParam} + * - {@link org.springframework.web.bind.annotation.RequestHeader} + * - {@link org.springframework.web.bind.annotation.PathVariable} + *

+ * 使用 @IgnoreParameter 可以忽略参数记录 {@link IgnoreParameter} + * 如果只需要忽略某个字段可以使用 @Desensitize(toEmpty = true) 标注 + */ + boolean parameter() default true; + /** * 返回值处理 */ diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/aspect/OperatorLogAspect.java b/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/aspect/OperatorLogAspect.java index 549f0d0d..531c61fb 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/aspect/OperatorLogAspect.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/aspect/OperatorLogAspect.java @@ -4,8 +4,10 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.ValueFilter; import com.orion.lang.define.thread.ExecutorBuilder; import com.orion.lang.define.wrapper.Ref; +import com.orion.lang.utils.Arrays1; import com.orion.lang.utils.Strings; import com.orion.lang.utils.json.matcher.ReplacementFormatters; +import com.orion.ops.framework.biz.operator.log.core.annotation.IgnoreParameter; import com.orion.ops.framework.biz.operator.log.core.annotation.OperatorLog; import com.orion.ops.framework.biz.operator.log.core.config.OperatorLogConfig; import com.orion.ops.framework.biz.operator.log.core.enums.ReturnType; @@ -16,6 +18,7 @@ import com.orion.ops.framework.biz.operator.log.core.service.OperatorLogFramewor import com.orion.ops.framework.biz.operator.log.core.uitls.OperatorLogs; import com.orion.ops.framework.common.enums.BooleanBit; import com.orion.ops.framework.common.meta.TraceIdHolder; +import com.orion.ops.framework.common.security.LoginUser; import com.orion.ops.framework.common.security.SecurityHolder; import com.orion.ops.framework.common.utils.IpUtils; import com.orion.web.servlet.web.Servlets; @@ -23,14 +26,19 @@ 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.reflect.MethodSignature; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; -import java.util.Date; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.*; import java.util.concurrent.ExecutorService; /** @@ -71,9 +79,9 @@ public class OperatorLogAspect { @Around("@annotation(o)") public Object around(ProceedingJoinPoint joinPoint, OperatorLog o) throws Throwable { long start = System.currentTimeMillis(); - // 先清空上下文 - OperatorLogs.clear(); try { + // 初始化参数 + this.initExtra(joinPoint, o); // 执行 Object result = joinPoint.proceed(); // 记录日志 @@ -89,6 +97,71 @@ public class OperatorLogAspect { } } + /** + * 初始化参数 + * + * @param joinPoint joinPoint + */ + private void initExtra(ProceedingJoinPoint joinPoint, OperatorLog o) { + // 清空上下文 + OperatorLogs.clear(); + if (!o.parameter()) { + return; + } + // 获取方法注解 + Annotation[][] methodAnnotations = Optional.ofNullable(joinPoint.getSignature()) + .filter(s -> (s instanceof MethodSignature)) + .map(s -> ((MethodSignature) s).getMethod()) + .map(Method::getParameterAnnotations) + .orElse(null); + if (Arrays1.isEmpty(methodAnnotations)) { + return; + } + // 获取参数 + Object[] args = joinPoint.getArgs(); + for (int i = 0; i < methodAnnotations.length; i++) { + Annotation[] annotations = methodAnnotations[i]; + if (Arrays1.isEmpty(annotations)) { + continue; + } + // 检查是否有 IgnoreParameter 注解 + boolean ignore = Arrays.stream(annotations) + .anyMatch(s -> s instanceof IgnoreParameter); + if (ignore) { + continue; + } + // 获取需要记录的参数 + for (Annotation annotation : annotations) { + if (annotation instanceof RequestBody) { + OperatorLogs.add(args[i]); + break; + } else if (annotation instanceof RequestParam) { + Object arg = args[i]; + if (arg instanceof MultipartFile) { + break; + } + OperatorLogs.add( + orElse(((RequestParam) annotation).value(), + ((RequestParam) annotation).name()), + args[i]); + break; + } else if (annotation instanceof RequestHeader) { + OperatorLogs.add( + orElse(((RequestHeader) annotation).value(), + ((RequestHeader) annotation).name()), + args[i]); + break; + } else if (annotation instanceof PathVariable) { + OperatorLogs.add( + orElse(((PathVariable) annotation).value(), + ((PathVariable) annotation).name()), + args[i]); + break; + } + } + } + } + /** * 保存日志 * @@ -97,7 +170,17 @@ public class OperatorLogAspect { */ private void saveLog(long start, OperatorLog o, Object ret, Throwable exception) { try { - // 请求信息 + // 获取日志类型 + OperatorType type = OperatorTypeHolder.get(o.value()); + if (type == null) { + return; + } + // 获取当前用户 + LoginUser user = this.getUser(); + if (user == null) { + return; + } + // 获取请求信息 Map extra = OperatorLogs.get(); if (!OperatorLogs.isSave(extra)) { return; @@ -106,7 +189,7 @@ public class OperatorLogAspect { // 填充使用时间 this.fillUseTime(model, start); // 填充用户信息 - this.fillUserInfo(model); + this.fillUserInfo(model, user); // 填充请求信息 this.fillRequest(model); // 填充结果信息 @@ -114,7 +197,7 @@ public class OperatorLogAspect { // 填充拓展信息 this.fillExtra(model, extra); // 填充日志 - this.fillLogInfo(model, extra, o); + this.fillLogInfo(model, extra, type); // 插入日志 this.asyncSaveLog(model); } catch (Exception e) { @@ -122,6 +205,20 @@ public class OperatorLogAspect { } } + /** + * 获取当前用户 + * + * @return user + */ + private LoginUser getUser() { + LoginUser user = OperatorLogs.getUser(); + if (user != null) { + return user; + } + // 登录上下文获取 + return securityHolder.getLoginUser(); + } + /** * 填充使用时间 * @@ -139,9 +236,11 @@ public class OperatorLogAspect { * 填充用户信息 * * @param model model + * @param user user */ - private void fillUserInfo(OperatorLogModel model) { - model.setUserId(securityHolder.getLoginUserId()); + private void fillUserInfo(OperatorLogModel model, LoginUser user) { + model.setUserId(user.getId()); + model.setUsername(user.getUsername()); } /** @@ -205,10 +304,9 @@ public class OperatorLogAspect { * * @param model model * @param extra extra - * @param o o + * @param type type */ - private void fillLogInfo(OperatorLogModel model, Map extra, OperatorLog o) { - OperatorType type = OperatorTypeHolder.get(o.value()); + private void fillLogInfo(OperatorLogModel model, Map extra, OperatorType type) { model.setModule(type.getModule()); model.setType(type.getType()); model.setLogInfo(ReplacementFormatters.format(type.getTemplate(), extra)); @@ -220,9 +318,18 @@ public class OperatorLogAspect { * @param model model */ private void asyncSaveLog(OperatorLogModel model) { - LOG_SAVER.submit(() -> { - operatorLogFrameworkService.insert(model); - }); + LOG_SAVER.submit(() -> operatorLogFrameworkService.insert(model)); + } + + /** + * 获取可用值 + * + * @param value value + * @param name name + * @return available + */ + private String orElse(String value, String name) { + return Strings.isBlank(value) ? name : value; } } diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/constant/OperatorLogKeys.java b/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/constant/OperatorLogKeys.java index 3ef35011..3d8999de 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/constant/OperatorLogKeys.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/constant/OperatorLogKeys.java @@ -17,6 +17,10 @@ public interface OperatorLogKeys { String NAME = "name"; + String STATUS = "status"; + + String STATUS_NAME = "statusName"; + String USERNAME = "username"; String TITLE = "title"; diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/model/OperatorLogModel.java b/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/model/OperatorLogModel.java index 55d1b8c6..76cbe3e0 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/model/OperatorLogModel.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/model/OperatorLogModel.java @@ -19,6 +19,11 @@ public class OperatorLogModel { */ private Long userId; + /** + * 用户名 + */ + private String username; + /** * traceId */ diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/uitls/OperatorLogs.java b/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/uitls/OperatorLogs.java index b0edf33d..bd3e615e 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/uitls/OperatorLogs.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-biz-operator-log/src/main/java/com/orion/ops/framework/biz/operator/log/core/uitls/OperatorLogs.java @@ -3,6 +3,7 @@ package com.orion.ops.framework.biz.operator.log.core.uitls; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.ValueFilter; import com.orion.ops.framework.biz.operator.log.core.constant.OperatorLogKeys; +import com.orion.ops.framework.common.security.LoginUser; import java.util.HashMap; import java.util.Map; @@ -20,8 +21,16 @@ public class OperatorLogs implements OperatorLogKeys { private static ValueFilter desensitizeValueFilter; + /** + * 拓展信息 + */ private static final ThreadLocal> EXTRA_HOLDER = new ThreadLocal<>(); + /** + * 当前用户 优先于登录用户 + */ + private static final ThreadLocal USER_HOLDER = new ThreadLocal<>(); + private OperatorLogs() { } @@ -93,10 +102,11 @@ public class OperatorLogs implements OperatorLogKeys { */ public static void clear() { EXTRA_HOLDER.remove(); + USER_HOLDER.remove(); } /** - * 是否保存 + * 设置是否保存 * * @param map map * @return save @@ -105,6 +115,24 @@ public class OperatorLogs implements OperatorLogKeys { return map == null || !map.containsKey(UN_SAVE_FLAG); } + /** + * 设置用户信息 + * + * @param user user + */ + public static void setUser(LoginUser user) { + USER_HOLDER.set(user); + } + + /** + * 获取用户 + * + * @return user + */ + public static LoginUser getUser() { + return USER_HOLDER.get(); + } + /** * 初始化 * diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/config/OrionDesensitizeAutoConfiguration.java b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/config/OrionDesensitizeAutoConfiguration.java index b15ceae8..9c41e4ea 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/config/OrionDesensitizeAutoConfiguration.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/config/OrionDesensitizeAutoConfiguration.java @@ -23,6 +23,10 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert public class OrionDesensitizeAutoConfiguration { /** + * 用于参数打印 + * - 全局日志打印 + * - 操作日志参数 + * * @return fastjson 序列化脱敏过滤器 */ @Bean @@ -31,13 +35,14 @@ public class OrionDesensitizeAutoConfiguration { } /** - * @return jackson 序列化脱敏过滤器 + * 用于 HTTP 响应序列化 + * + * @return jackson 序列化脱敏序列化 */ @Bean @ConditionalOnBean(MappingJackson2HttpMessageConverter.class) - public DesensitizeJsonSerializer desensitizeJsonSerializer(MappingJackson2HttpMessageConverter converter) { - DesensitizeJsonSerializer serializer = new DesensitizeJsonSerializer(); - return serializer; + public DesensitizeJsonSerializer desensitizeJsonSerializer() { + return new DesensitizeJsonSerializer(); } } diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/annotation/Desensitize.java b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/annotation/Desensitize.java index bcc9165b..d836f396 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/annotation/Desensitize.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/annotation/Desensitize.java @@ -9,7 +9,8 @@ import java.lang.annotation.*; /** * FastJson / Jackson 脱敏配置元注解 *

- * 标注在字段上则标记该字段执行 http 序列化时脱敏 + * Jackson 标注在字段上则标记该字段执行 http 序列化 (返回 VO)时脱敏 (http-message-converts 用的是 jackson) + * FastJson 需要组合 {@link DesensitizeObject} 一起使用 * * @author Jiahang Li * @version 1.0.0 @@ -22,6 +23,13 @@ import java.lang.annotation.*; @JsonSerialize(using = DesensitizeJsonSerializer.class) public @interface Desensitize { + /** + * 一般用于操作日志参数脱敏 + * + * @return 是否直接设置为空 + */ + boolean toEmpty() default false; + /** * @return 起始保留字符数 */ diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/filter/DesensitizeValueFilter.java b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/filter/DesensitizeValueFilter.java index 9d334a45..87857123 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/filter/DesensitizeValueFilter.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/filter/DesensitizeValueFilter.java @@ -8,6 +8,7 @@ import com.orion.lang.utils.Strings; import com.orion.lang.utils.collect.Maps; import com.orion.lang.utils.reflect.Annotations; import com.orion.lang.utils.reflect.Fields; +import com.orion.ops.framework.common.constant.Const; import com.orion.ops.framework.desensitize.core.annotation.Desensitize; import com.orion.ops.framework.desensitize.core.annotation.DesensitizeObject; @@ -39,8 +40,13 @@ public class DesensitizeValueFilter implements ValueFilter { if (config == null) { return value; } - // 脱敏 - return Desensitizes.mix(Objects1.toString(value), config.keepStart(), config.keepEnd(), config.replacer()); + if (config.toEmpty()) { + // 设置为空 + return Const.EMPTY; + } else { + // 脱敏 + return Desensitizes.mix(Objects1.toString(value), config.keepStart(), config.keepEnd(), config.replacer()); + } } /** diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/serializer/DesensitizeJsonSerializer.java b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/serializer/DesensitizeJsonSerializer.java index 333cb7e4..b59092d0 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/serializer/DesensitizeJsonSerializer.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-desensitize/src/main/java/com/orion/ops/framework/desensitize/core/serializer/DesensitizeJsonSerializer.java @@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.ContextualSerializer; +import com.orion.lang.constant.Const; import com.orion.lang.utils.Desensitizes; import com.orion.lang.utils.Objects1; import com.orion.ops.framework.desensitize.core.annotation.Desensitize; @@ -24,6 +25,10 @@ import java.util.Objects; */ public class DesensitizeJsonSerializer extends JsonSerializer implements ContextualSerializer { + /** + * 这里是线程安全的 + * 同一个字段使用同一个 serializer 所以不需要使用 TheadLocal + */ private Desensitize desensitize; @Override @@ -43,9 +48,14 @@ public class DesensitizeJsonSerializer extends JsonSerializer implements gen.writeNull(); return; } - // 脱敏 - String mix = Desensitizes.mix(Objects1.toString(value), desensitize.keepStart(), desensitize.keepEnd(), desensitize.replacer()); - gen.writeString(mix); + if (desensitize.toEmpty()) { + // 设置为空 + gen.writeString(Const.EMPTY); + } else { + // 脱敏 + String mix = Desensitizes.mix(Objects1.toString(value), desensitize.keepStart(), desensitize.keepEnd(), desensitize.replacer()); + gen.writeString(mix); + } } } \ No newline at end of file diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/AuthenticationController.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/AuthenticationController.java index 7118a89e..7b7209e4 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/AuthenticationController.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/AuthenticationController.java @@ -1,10 +1,12 @@ package com.orion.ops.module.infra.controller; import com.orion.lang.define.wrapper.HttpWrapper; +import com.orion.ops.framework.biz.operator.log.core.annotation.OperatorLog; import com.orion.ops.framework.log.core.annotation.IgnoreLog; import com.orion.ops.framework.log.core.enums.IgnoreLogMode; import com.orion.ops.framework.security.core.utils.SecurityUtils; import com.orion.ops.framework.web.core.annotation.RestWrapper; +import com.orion.ops.module.infra.define.operator.AuthenticationOperatorType; import com.orion.ops.module.infra.entity.request.user.UserLoginRequest; import com.orion.ops.module.infra.entity.request.user.UserResetPasswordRequest; import com.orion.ops.module.infra.entity.vo.UserLoginVO; @@ -42,15 +44,16 @@ public class AuthenticationController { @Resource private SystemUserService systemUserService; + @OperatorLog(AuthenticationOperatorType.LOGIN) @PermitAll @Operation(summary = "登陆") @PostMapping("/login") public UserLoginVO login(@Validated @RequestBody UserLoginRequest request, HttpServletRequest servletRequest) { - String token = authenticationService.login(request, servletRequest); - return UserLoginVO.builder().token(token).build(); + return authenticationService.login(request, servletRequest); } + @OperatorLog(AuthenticationOperatorType.LOGOUT) @PermitAll @IgnoreLog(IgnoreLogMode.RET) @Operation(summary = "登出") @@ -60,6 +63,7 @@ public class AuthenticationController { return HttpWrapper.ok(); } + @OperatorLog(AuthenticationOperatorType.UPDATE_PASSWORD) @Operation(summary = "修改密码") @PutMapping("/update-password") public HttpWrapper updatePassword(@Validated @RequestBody UserResetPasswordRequest request) { diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/define/operator/AuthenticationOperatorType.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/define/operator/AuthenticationOperatorType.java new file mode 100644 index 00000000..a854f8ef --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/define/operator/AuthenticationOperatorType.java @@ -0,0 +1,30 @@ +package com.orion.ops.module.infra.define.operator; + +import com.orion.ops.framework.biz.operator.log.core.model.OperatorType; + +import static com.orion.ops.framework.biz.operator.log.core.holder.OperatorTypeHolder.set; + +/** + * 认证服务 操作日志类型 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-10-10 19:06 + */ +public class AuthenticationOperatorType { + + private static final String MODULE = "infra:authentication"; + + public static final String LOGIN = "authentication:login"; + + public static final String LOGOUT = "authentication:logout"; + + public static final String UPDATE_PASSWORD = "authentication:update-password"; + + public static void init() { + set(new OperatorType(MODULE, LOGIN, "登陆系统")); + set(new OperatorType(MODULE, LOGOUT, "登出系统")); + set(new OperatorType(MODULE, UPDATE_PASSWORD, "修改密码")); + } + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/domain/OperatorLogDO.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/domain/OperatorLogDO.java index 583ab432..972c8a6f 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/domain/OperatorLogDO.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/domain/OperatorLogDO.java @@ -36,6 +36,10 @@ public class OperatorLogDO extends BaseDO { @TableField("user_id") private Long userId; + @Schema(description = "用户名") + @TableField("username") + private String username; + @Schema(description = "traceId") @TableField("trace_id") private String traceId; diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/user/UserLoginRequest.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/user/UserLoginRequest.java index 96527e2b..c4bbc908 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/user/UserLoginRequest.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/user/UserLoginRequest.java @@ -1,5 +1,7 @@ package com.orion.ops.module.infra.entity.request.user; +import com.orion.ops.framework.desensitize.core.annotation.Desensitize; +import com.orion.ops.framework.desensitize.core.annotation.DesensitizeObject; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -13,6 +15,7 @@ import javax.validation.constraints.NotEmpty; * @since 2023/7/13 22:16 */ @Data +@DesensitizeObject @Schema(name = "UserLoginRequest", description = "登陆请求") public class UserLoginRequest { @@ -20,6 +23,7 @@ public class UserLoginRequest { @Schema(description = "用户名") private String username; + @Desensitize(toEmpty = true) @NotEmpty @Schema(description = "密码") private String password; diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/vo/OperatorLogVO.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/vo/OperatorLogVO.java index 8543d7fb..d6783299 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/vo/OperatorLogVO.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/vo/OperatorLogVO.java @@ -31,6 +31,9 @@ public class OperatorLogVO implements Serializable { @Schema(description = "用户id") private Long userId; + @Schema(description = "用户名") + private String username; + @Schema(description = "traceId") private String traceId; diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/runner/InfraOperatorTypeRunner.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/runner/InfraOperatorTypeRunner.java new file mode 100644 index 00000000..2e1c2e0f --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/runner/InfraOperatorTypeRunner.java @@ -0,0 +1,22 @@ +package com.orion.ops.module.infra.runner; + +import com.orion.ops.module.infra.define.operator.AuthenticationOperatorType; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +/** + * 操作类型 初始化 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/10/10 18:03 + */ +@Component +public class InfraOperatorTypeRunner implements CommandLineRunner { + + @Override + public void run(String... args) { + AuthenticationOperatorType.init(); + } + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/AuthenticationService.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/AuthenticationService.java index 5db87855..72ce1567 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/AuthenticationService.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/AuthenticationService.java @@ -3,6 +3,7 @@ package com.orion.ops.module.infra.service; import com.orion.ops.framework.common.security.LoginUser; import com.orion.ops.module.infra.entity.dto.LoginTokenDTO; import com.orion.ops.module.infra.entity.request.user.UserLoginRequest; +import com.orion.ops.module.infra.entity.vo.UserLoginVO; import javax.servlet.http.HttpServletRequest; @@ -30,9 +31,9 @@ public interface AuthenticationService { * * @param request request * @param servletRequest servletRequest - * @return token + * @return login */ - String login(UserLoginRequest request, HttpServletRequest servletRequest); + UserLoginVO login(UserLoginRequest request, HttpServletRequest servletRequest); /** * 登出 diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/AuthenticationServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/AuthenticationServiceImpl.java index edf1b2cb..8b2e1ef5 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/AuthenticationServiceImpl.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/AuthenticationServiceImpl.java @@ -6,6 +6,7 @@ import com.orion.lang.define.wrapper.Pair; import com.orion.lang.utils.Exceptions; import com.orion.lang.utils.collect.Lists; import com.orion.lang.utils.crypto.Signatures; +import com.orion.ops.framework.biz.operator.log.core.uitls.OperatorLogs; import com.orion.ops.framework.common.constant.Const; import com.orion.ops.framework.common.constant.ErrorMessage; import com.orion.ops.framework.common.security.LoginUser; @@ -23,6 +24,7 @@ import com.orion.ops.module.infra.entity.domain.SystemRoleDO; import com.orion.ops.module.infra.entity.domain.SystemUserDO; import com.orion.ops.module.infra.entity.dto.LoginTokenDTO; import com.orion.ops.module.infra.entity.request.user.UserLoginRequest; +import com.orion.ops.module.infra.entity.vo.UserLoginVO; import com.orion.ops.module.infra.enums.LoginTokenStatusEnum; import com.orion.ops.module.infra.enums.UserStatusEnum; import com.orion.ops.module.infra.service.AuthenticationService; @@ -62,13 +64,15 @@ public class AuthenticationServiceImpl implements AuthenticationService { private RedisTemplate redisTemplate; @Override - public String login(UserLoginRequest request, HttpServletRequest servletRequest) { + public UserLoginVO login(UserLoginRequest request, HttpServletRequest servletRequest) { // 登陆前检查 this.preCheckLogin(request); // 获取登陆用户 LambdaQueryWrapper wrapper = systemUserDAO.wrapper() .eq(SystemUserDO::getUsername, request.getUsername()); SystemUserDO user = systemUserDAO.of(wrapper).getOne(); + // 设置日志上下文 + OperatorLogs.setUser(SystemUserConvert.MAPPER.toLoginUser(user)); // 检查密码 boolean passwordCorrect = this.checkPassword(request, user); Valid.isTrue(passwordCorrect, ErrorMessage.USERNAME_PASSWORD_ERROR); @@ -90,7 +94,10 @@ public class AuthenticationServiceImpl implements AuthenticationService { this.invalidOtherDeviceToken(user.getId(), current, remoteAddr, location); } // 生成 loginToken - return this.generatorLoginToken(user, current, remoteAddr, location); + String token = this.generatorLoginToken(user, current, remoteAddr, location); + return UserLoginVO.builder() + .token(token) + .build(); } @Override diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserServiceImpl.java index c43f1d84..d2726460 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserServiceImpl.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserServiceImpl.java @@ -63,7 +63,7 @@ public class SystemUserServiceImpl implements SystemUserService { public Long createSystemUser(SystemUserCreateRequest request) { // 转换 SystemUserDO record = SystemUserConvert.MAPPER.to(request); - // 查询用户名称是否存在 + // 查询用户名是否存在 this.checkUsernamePresent(record); // 查询花名是否存在 this.checkNicknamePresent(record); diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/resources/mapper/OperatorLogMapper.xml b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/resources/mapper/OperatorLogMapper.xml index 3c9030ef..4e775ba3 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/resources/mapper/OperatorLogMapper.xml +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/resources/mapper/OperatorLogMapper.xml @@ -6,6 +6,7 @@ + @@ -25,7 +26,7 @@ - id, user_id, trace_id, address, location, user_agent, module, type, log_info, extra, result, error_message, return_value, duration, start_time, end_time, create_time + id, user_id, username, trace_id, address, location, user_agent, module, type, log_info, extra, result, error_message, return_value, duration, start_time, end_time, create_time