| | |
| | | public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { |
| | | ServerHttpRequest request = exchange.getRequest(); |
| | | String uri = request.getURI().getRawPath(); |
| | | if (uri.startsWith("/internal/audit-logs")) return chain.filter(exchange); |
| | | if (uri.startsWith("/internal/audit-logs") || !shouldAudit(request.getMethodValue(), uri)) { |
| | | return chain.filter(exchange); |
| | | } |
| | | long startedAt = System.currentTimeMillis(); |
| | | return chain.filter(exchange).then(Mono.<Void>fromRunnable(() -> writeAudit(exchange, startedAt)) |
| | | .subscribeOn(Schedulers.boundedElastic())); |
| | |
| | | String lower = uri.toLowerCase(); |
| | | if (lower.contains("login") || lower.contains("token")) return "LOGIN"; |
| | | if (lower.matches(".*(status|state|ticket|payment|finance|refund|withdraw|balance).*")) return "STATUS_CHANGE"; |
| | | if ("POST".equalsIgnoreCase(method)) return "CREATE"; |
| | | if (lower.matches(".*(add|create|save|insert|commit|submit|upload).*")) return "CREATE"; |
| | | if ("PUT".equalsIgnoreCase(method) || "PATCH".equalsIgnoreCase(method)) return "UPDATE"; |
| | | if ("DELETE".equalsIgnoreCase(method)) return "DELETE"; |
| | | if (lower.matches(".*(edit|update|modify|change|set|reset|freeze|unfreeze|enable|disable|audit|approve|reject).*")) return "UPDATE"; |
| | | if (lower.matches(".*(phone|mobile|idcard|identity|bank|wallet).*")) return "VIEW_SENSITIVE"; |
| | | return "READ"; |
| | | } |
| | | |
| | | /** |
| | | * 网关只记录外部用户真正触发的业务变更、登录和敏感数据访问。 |
| | | * POST 在本系统中大量用于列表/详情查询,不能再按 HTTP 方法一概当作新增。 |
| | | */ |
| | | private boolean shouldAudit(String method, String uri) { |
| | | String lower = uri == null ? "" : uri.toLowerCase(); |
| | | if (lower.matches(".*(login|token|phone|mobile|idcard|identity|bank|wallet).*")) return true; |
| | | if ("PUT".equalsIgnoreCase(method) || "PATCH".equalsIgnoreCase(method) |
| | | || "DELETE".equalsIgnoreCase(method)) return true; |
| | | return "POST".equalsIgnoreCase(method) |
| | | && lower.matches(".*(add|create|save|insert|edit|update|modify|delete|remove|del|" |
| | | + "change|set|reset|freeze|unfreeze|enable|disable|commit|submit|upload|" |
| | | + "audit|approve|reject|refund|withdraw|payment).*" ); |
| | | } |
| | | private String riskLevel(String uri, String type) { |
| | | String lower = uri.toLowerCase(); |
| | | if ("STATUS_CHANGE".equals(type) || lower.matches(".*(finance|payment|refund|withdraw|balance|ticket).*")) return "CRITICAL"; |