刘帅
2026-09-29 dcb96821f905f3fd93c059d8703517bdcac4d336
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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(); }
}