刘帅
2026-09-22 bc68f4393cafe39c4fce614c8128936067ea25f7
cloud-server-management/src/main/java/com/dsh/guns/modular/system/audit/ManagementFeignAuditInterceptor.java
@@ -5,47 +5,15 @@
import feign.RequestTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/** Spring 会把该 RequestInterceptor 应用于管理端全部 Feign 客户端。 */
/** 仅透传敏感数据访问所需的内部标识;Feign 调用不是用户操作,不写审计日志。 */
@Component
public class ManagementFeignAuditInterceptor implements RequestInterceptor {
    @Resource private ManagementAuditWriter auditWriter;
    @Override
    public void apply(RequestTemplate template) {
        try {
            Map<String, Object> audit = new HashMap<String, Object>();
            String url = template.url();
            if (url != null && url.startsWith("/internal/sensitive/")
                    && UserExt.getUser() != null && "admin".equalsIgnoreCase(UserExt.getUser().getAccount())) {
                template.header("X-Internal-Sensitive-Access", "true");
            }
            audit.put("traceId", UUID.randomUUID().toString().replace("-", ""));
            audit.put("sourceService", "mb-cloud-management");
            audit.put("sourceType", "FEIGN");
            audit.put("operationType", "FEIGN_CALL");
            audit.put("riskLevel", riskLevel(url));
            audit.put("operationName", template.feignTarget() == null ? "Feign调用" : template.feignTarget().name());
            audit.put("requestMethod", template.method());
            audit.put("requestUri", url);
            audit.put("requestParams", template.body() == null ? null : "bodyBytes=" + template.body().length);
            audit.put("userId", UserExt.getUser() == null ? null : UserExt.getUser().getId());
            audit.put("userAccount", UserExt.getUser() == null ? null : UserExt.getUser().getAccount());
            audit.put("result", "REQUESTED");
            audit.put("createdAt", new Date());
            auditWriter.append(audit);
        } catch (Exception ignored) {
            // 审计异常绝不能阻塞原 Feign 调用。
        }
    }
    private String riskLevel(String url) {
        String value = url == null ? "" : url.toLowerCase();
        return value.matches(".*(ticket|payment|finance|refund|withdraw|balance|status|state).*") ? "CRITICAL" : "NORMAL";
    }
}