package com.dsh.other.audit;
|
|
import com.alibaba.fastjson.JSON;
|
import com.dsh.other.entity.SysAccountAuditLog;
|
import org.apache.commons.lang3.StringUtils;
|
|
import javax.servlet.http.HttpServletRequest;
|
import java.util.LinkedHashMap;
|
import java.util.Map;
|
import java.util.UUID;
|
|
final class AuditLogSupport {
|
private AuditLogSupport() { }
|
static final String TRACE_HEADER = "X-Audit-Trace-Id";
|
|
static SysAccountAuditLog fromRequest(HttpServletRequest request) {
|
String uri = request.getRequestURI();
|
String method = request.getMethod();
|
SysAccountAuditLog log = new SysAccountAuditLog();
|
log.setTraceId(StringUtils.defaultIfBlank(request.getHeader(TRACE_HEADER), UUID.randomUUID().toString().replace("-", "")));
|
log.setUserId(toLong(request.getHeader("userId")));
|
// 账号列用于定位操作人,不能保存为 a***in 这类不可检索的掩码值。
|
log.setUserAccount(request.getHeader("username"));
|
log.setSourceService("mb-cloud-other");
|
log.setSourceType("HTTP");
|
log.setRequestMethod(method);
|
log.setRequestUri(uri);
|
log.setRequestParams(maskParameters(request.getParameterMap()));
|
log.setClientIp(clientIp(request));
|
log.setOperationType(operationType(method, uri));
|
log.setRiskLevel(riskLevel(uri, log.getOperationType()));
|
log.setOperationName(method + " " + uri);
|
return log;
|
}
|
|
static String operationType(String method, String uri) {
|
String value = (uri == null ? "" : uri).toLowerCase();
|
if (value.contains("login") || value.contains("token")) return "LOGIN";
|
if (value.matches(".*(status|state|ticket|payment|finance|refund|withdraw|balance|order).*")) return "STATUS_CHANGE";
|
if ("POST".equalsIgnoreCase(method)) return "CREATE";
|
if ("PUT".equalsIgnoreCase(method) || "PATCH".equalsIgnoreCase(method)) return "UPDATE";
|
if ("DELETE".equalsIgnoreCase(method)) return "DELETE";
|
if (value.matches(".*(phone|mobile|idcard|identity|bank|wallet|finance|payment|ticket).*")) return "VIEW_SENSITIVE";
|
return "READ";
|
}
|
|
static String riskLevel(String uri, String operationType) {
|
String value = (uri == null ? "" : uri).toLowerCase();
|
if ("STATUS_CHANGE".equals(operationType) || value.matches(".*(finance|payment|refund|withdraw|balance|ticket).*")) return "CRITICAL";
|
if ("VIEW_SENSITIVE".equals(operationType) || value.matches(".*(phone|mobile|idcard|identity|bank|wallet).*")) return "SENSITIVE";
|
return "NORMAL";
|
}
|
|
static String maskParameters(Map<String, String[]> parameters) {
|
Map<String, Object> result = new LinkedHashMap<String, Object>();
|
for (Map.Entry<String, String[]> entry : parameters.entrySet()) {
|
String key = entry.getKey();
|
result.put(key, isSensitiveKey(key) ? "***" : entry.getValue());
|
}
|
return JSON.toJSONString(result);
|
}
|
|
static String maskText(String text) { return text == null ? null : text.replaceAll("(?i)(password|token|authorization|idcard|bankCard)\\s*[:=]\\s*[^,\\s&}]+", "$1=***"); }
|
static boolean isSensitiveKey(String key) { return key != null && key.toLowerCase().matches(".*(password|token|authorization|secret|idcard|identity|bank|card|mobile|phone).*" ); }
|
static Long toLong(String value) { try { return StringUtils.isBlank(value) ? null : Long.valueOf(value); } catch (NumberFormatException e) { return null; } }
|
static String clientIp(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); return StringUtils.isBlank(ip) ? request.getRemoteAddr() : ip.split(",")[0].trim(); }
|
}
|