diff --git a/ballcat-admin/ballcat-admin-core/src/main/java/com/hccake/ballcat/admin/modules/log/handler/AdminAccessLogHandler.java b/ballcat-admin/ballcat-admin-core/src/main/java/com/hccake/ballcat/admin/modules/log/handler/AdminAccessLogHandler.java index f5ea70d3..212101c3 100644 --- a/ballcat-admin/ballcat-admin-core/src/main/java/com/hccake/ballcat/admin/modules/log/handler/AdminAccessLogHandler.java +++ b/ballcat-admin/ballcat-admin-core/src/main/java/com/hccake/ballcat/admin/modules/log/handler/AdminAccessLogHandler.java @@ -10,6 +10,9 @@ import com.hccake.ballcat.admin.oauth.util.SecurityUtils; import com.hccake.ballcat.commom.log.access.handler.AccessLogHandler; import com.hccake.ballcat.commom.log.constant.LogConstant; import com.hccake.ballcat.commom.log.util.LogUtils; +import com.hccake.ballcat.common.core.desensite.DesensitizationHandler; +import com.hccake.ballcat.common.core.desensite.DesensitizationHandlerHolder; +import com.hccake.ballcat.common.core.desensite.DesensitizationTypeConstant; import com.hccake.ballcat.common.core.util.IPUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -20,6 +23,9 @@ import org.springframework.web.servlet.HandlerMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.List; +import java.util.Map; import java.util.Optional; /** @@ -39,6 +45,17 @@ public class AdminAccessLogHandler implements AccessLogHandler { private final ObjectMapper objectMapper; + /** + * 需要脱敏记录的参数 + */ + private final List needDesensitizeParams = Arrays.asList("password", "pass", "passConfirm"); + + /** + * 脱敏处理器 + */ + private final DesensitizationHandler desensitizationHandler = DesensitizationHandlerHolder.TYPE_MAPS + .get(DesensitizationTypeConstant.ENCRYPTED_PASSWORD); + /** * 生产一个日志 * @return accessLog @@ -53,6 +70,7 @@ public class AdminAccessLogHandler implements AccessLogHandler { Object matchingPatternAttr = request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); String matchingPattern = matchingPatternAttr == null ? "" : String.valueOf(matchingPatternAttr); // @formatter:off + String uri = URLUtil.getPath(request.getRequestURI()); AdminAccessLog adminAccessLog = new AdminAccessLog() .setTraceId(MDC.get(LogConstant.TRACE_ID)) .setCreateTime(LocalDateTime.now()) @@ -60,30 +78,25 @@ public class AdminAccessLogHandler implements AccessLogHandler { .setIp(IPUtil.getIpAddr(request)) .setMethod(request.getMethod()) .setUserAgent(request.getHeader("user-agent")) - .setUri(URLUtil.getPath(request.getRequestURI())) + .setUri(uri) .setMatchingPattern(matchingPattern) .setErrorMsg(Optional.ofNullable(myThrowable).map(Throwable::getMessage).orElse("")) .setHttpStatus(response.getStatus()); // @formatter:on // 参数获取 - String params = ""; - try { - params = objectMapper.writeValueAsString(request.getParameterMap()); - } - catch (JsonProcessingException e) { - log.error("[prodLog],参数获取序列化异常", e); - } + String params = getParams(request); adminAccessLog.setReqParams(params); - // 非文件上传请求,记录body - if (!LogUtils.isMultipartContent(request)) { + // 非文件上传请求,记录body,用户改密时不记录body + // TODO 使用注解控制此次请求是否记录body,更方便个性化定制 + if (!LogUtils.isMultipartContent(request) && "/sysuser/pass/{userId}".equals(uri)) { adminAccessLog.setReqBody(LogUtils.getRequestBody(request)); } // 只记录响应头为 application/json 的返回数据 // 后台日志对于分页数据请求,不记录返回值 - if (!request.getRequestURI().endsWith("/page") && response.getContentType() != null + if (!uri.endsWith("/page") && response.getContentType() != null && response.getContentType().contains(APPLICATION_JSON)) { adminAccessLog.setResult(LogUtils.getResponseBody(request, response)); } @@ -97,6 +110,30 @@ public class AdminAccessLogHandler implements AccessLogHandler { return adminAccessLog; } + /** + * 获取参数信息 + * @param request 请求信息 + * @return 请求参数 + */ + public String getParams(HttpServletRequest request) { + String params; + try { + Map parameterMap = request.getParameterMap(); + for (String paramKey : needDesensitizeParams) { + String[] values = parameterMap.get(paramKey); + if (values != null && values.length != 0) { + parameterMap.put(paramKey, new String[] { desensitizationHandler.handle(values[0]) }); + } + } + params = objectMapper.writeValueAsString(parameterMap); + } + catch (JsonProcessingException e) { + params = "记录参数异常"; + log.error("[prodLog],参数获取序列化异常", e); + } + return params; + } + /** * 记录日志 * @param accessLog 访问日志 diff --git a/ballcat-admin/ballcat-admin-core/src/main/java/com/hccake/ballcat/admin/modules/sys/controller/SysUserController.java b/ballcat-admin/ballcat-admin-core/src/main/java/com/hccake/ballcat/admin/modules/sys/controller/SysUserController.java index 8e6d1b9a..9679b7d2 100644 --- a/ballcat-admin/ballcat-admin-core/src/main/java/com/hccake/ballcat/admin/modules/sys/controller/SysUserController.java +++ b/ballcat-admin/ballcat-admin-core/src/main/java/com/hccake/ballcat/admin/modules/sys/controller/SysUserController.java @@ -1,9 +1,9 @@ package com.hccake.ballcat.admin.modules.sys.controller; import cn.hutool.core.collection.CollectionUtil; -import cn.hutool.core.util.StrUtil; import com.hccake.ballcat.admin.constants.SysUserConst; import com.hccake.ballcat.admin.modules.sys.model.dto.SysUserDTO; +import com.hccake.ballcat.admin.modules.sys.model.dto.SysUserPassDTO; import com.hccake.ballcat.admin.modules.sys.model.dto.SysUserScope; import com.hccake.ballcat.admin.modules.sys.model.entity.SysRole; import com.hccake.ballcat.admin.modules.sys.model.entity.SysUser; @@ -25,6 +25,7 @@ import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -42,6 +43,7 @@ import java.util.List; * @author hccake 2020-09-24 20:16:15 */ @Slf4j +@Validated @RestController @RequestMapping("/sysuser") @Api(value = "sysuser", tags = "用户管理模块") @@ -161,12 +163,11 @@ public class SysUserController { @ApiOperation(value = "修改系统用户密码", notes = "修改系统用户密码") @UpdateOperationLogging(msg = "修改系统用户密码") @PreAuthorize("@per.hasPermission('sys:sysuser:pass')") - public R updateUserPass(@PathVariable Integer userId, String pass, String confirm) { - if (StrUtil.isBlank(pass) || StrUtil.isBlank(confirm) || !pass.equals(confirm)) { + public R updateUserPass(@PathVariable Integer userId, @RequestBody SysUserPassDTO sysUserPassDTO) { + if (!sysUserPassDTO.getPass().equals(sysUserPassDTO.getConfirmPass())) { return R.failed(SystemResultCode.BAD_REQUEST, "错误的密码!"); } - - return sysUserService.updateUserPass(userId, pass) ? R.ok() + return sysUserService.updateUserPass(userId, sysUserPassDTO.getPass()) ? R.ok() : R.failed(BaseResultCode.UPDATE_DATABASE_ERROR, "修改用户密码失败!"); } diff --git a/ballcat-admin/ballcat-admin-core/src/main/java/com/hccake/ballcat/admin/modules/sys/model/dto/SysUserDTO.java b/ballcat-admin/ballcat-admin-core/src/main/java/com/hccake/ballcat/admin/modules/sys/model/dto/SysUserDTO.java index 99780ba0..d8a4101c 100644 --- a/ballcat-admin/ballcat-admin-core/src/main/java/com/hccake/ballcat/admin/modules/sys/model/dto/SysUserDTO.java +++ b/ballcat-admin/ballcat-admin-core/src/main/java/com/hccake/ballcat/admin/modules/sys/model/dto/SysUserDTO.java @@ -1,5 +1,7 @@ package com.hccake.ballcat.admin.modules.sys.model.dto; +import com.hccake.ballcat.common.core.desensite.DesensitizationTypeConstant; +import com.hccake.ballcat.common.core.desensite.JsonDesensitize; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -21,6 +23,7 @@ public class SysUserDTO { /** * 前端传入密码 */ + @JsonDesensitize(type = DesensitizationTypeConstant.ENCRYPTED_PASSWORD) @ApiModelProperty(value = "前端传入密码") private String pass; diff --git a/ballcat-admin/ballcat-admin-core/src/main/java/com/hccake/ballcat/admin/modules/sys/model/dto/SysUserPassDTO.java b/ballcat-admin/ballcat-admin-core/src/main/java/com/hccake/ballcat/admin/modules/sys/model/dto/SysUserPassDTO.java new file mode 100644 index 00000000..f8f86f03 --- /dev/null +++ b/ballcat-admin/ballcat-admin-core/src/main/java/com/hccake/ballcat/admin/modules/sys/model/dto/SysUserPassDTO.java @@ -0,0 +1,35 @@ +package com.hccake.ballcat.admin.modules.sys.model.dto; + +import com.hccake.ballcat.common.core.desensite.DesensitizationTypeConstant; +import com.hccake.ballcat.common.core.desensite.JsonDesensitize; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 用户密码传输DTO,字段序列化时忽略,防止记录 + * + * @author Hccake 2021/1/22 + * @version 1.0 + */ +@Data +public class SysUserPassDTO { + + /** + * 前端传入密码 + */ + @NotBlank(message = "The password cannot be empty!") + @JsonDesensitize(type = DesensitizationTypeConstant.ENCRYPTED_PASSWORD) + @ApiModelProperty(value = "前端输入密码") + private String pass; + + /** + * 前端确认密码 + */ + @NotBlank(message = "The confirm password cannot be empty!") + @JsonDesensitize(type = DesensitizationTypeConstant.ENCRYPTED_PASSWORD) + @ApiModelProperty(value = "前端确认密码") + private String confirmPass; + +} diff --git a/ballcat-starters/ballcat-spring-boot-starter-log/src/main/java/com/hccake/ballcat/commom/log/operation/enums/OperationTypeEnum.java b/ballcat-starters/ballcat-spring-boot-starter-log/src/main/java/com/hccake/ballcat/commom/log/operation/enums/OperationTypeEnum.java index 7a3dc164..21b6db82 100644 --- a/ballcat-starters/ballcat-spring-boot-starter-log/src/main/java/com/hccake/ballcat/commom/log/operation/enums/OperationTypeEnum.java +++ b/ballcat-starters/ballcat-spring-boot-starter-log/src/main/java/com/hccake/ballcat/commom/log/operation/enums/OperationTypeEnum.java @@ -12,6 +12,21 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor public enum OperationTypeEnum { + /** + * 其他操作 + */ + OTHER(0), + + /** + * 导入操作 + */ + IMPORT(1), + + /** + * 导出操作 + */ + EXPORT(2), + /** * 查看操作,主要用于敏感数据查询记录 */