package jnpf.bizcommon.audit.controller; import cn.dev33.satoken.same.SaSameUtil; import jnpf.audit.model.AuditEventDTO; import jnpf.bizcommon.audit.service.AuditEventService; import jnpf.bizcommon.audit.service.DataInterfaceSignAuditService; import jnpf.base.ActionResult; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * 审计事件内部接收端点:只服务 {@link jnpf.audit.AuditEventApi} 的 Feign 调用, * 走平台内部鉴权链,不经网关白名单暴露给外部。path 与 AuditEventApi 的 @FeignClient * path 保持字面一致(/Internal/audit + /events)。 * *
写端点鉴权(权威安全边界):本方法首行的服务侧 * {@link SaSameUtil#checkCurrentRequestToken()} 是审计写端点的权威安全边界——它拒绝一切 * 不携带合法 {@code SA-SAME-TOKEN} 的请求,覆盖网关层的所有绕过变体(Discovery Locator * 自动路由 {@code /jnpf-audit/**}、大小写变体、多斜杠、white-ip 白名单跳过 block 等), * 使本端点只接受携带有效 {@code SA-SAME-TOKEN} 的服务间 Feign 调用: * jnpf-common-feign 的 {@code FeignConfig} 请求拦截器对所有 Feign 出站请求自动注入 * {@code SA-SAME-TOKEN = UserProvider.getInnerAuthToken() = SaSameUtil.getToken()}(已反编译实证); * 而网关转发的外部请求只被注入 {@code SA-SAME-TOKEN_GATEWAY}(MvcSecurityConfig),不带 * {@code SA-SAME-TOKEN},故 {@code checkCurrentRequestToken()} 读不到 header 即抛 * {@link cn.dev33.satoken.exception.SameTokenInvalidException}(sa-token 1.44.0 的 same-token 校验异常, * 该版本无 {@code SaSameException})拒收——堵住任意登录用户经网关伪造投递审计事件、破坏 append-only 完整性的漏洞。 * 该校验与请求路径大小写、前缀形态无关,是伪造防线的最终裁定层。 * *
网关 block-url 是纵深第一层(非权威边界):router.yaml 的 {@code gateway.block-url} * 已覆盖数据面标准路径 {@code /api/audit/Internal/**}(前端/DB 数据接口用)与 * {@code /jnpf-audit/Internal/**}(Discovery Locator 自动路由标准路径); * 2026-08-11 审计搬入 jnpf-biz-common 后又多出两条到达路径,已一并补堵: * {@code /api/biz/Internal/**}(biz-common 的对外前缀同样 StripPrefix=2, * {@code /api/biz/Internal/audit/events} 去掉两段后正是本端点)与 * {@code /jnpf-biz-common/Internal/**}(Locator 按新服务名生成;原 {@code /jnpf-audit/**} * 那条仍须保留,因为 discovery.yaml 里 jnpf-audit 作为别名依然注册)。它是纵深第一层, * 按用户决策只覆盖数据面标准路径、不穷尽所有变体:大写/混合大小写变体(如 * {@code /JNPF-AUDIT/Internal/audit/events})实测在下游 Spring MVC 因 controller 路径映射 * 大小写敏感直接 404(不达本方法),多斜杠变体被平台"非法请求"过滤器拦截——均无法落库, * 兜底全部由上述服务侧 SAME-TOKEN 承担。网关层完整覆盖(全局 {@code /Internal} 屏蔽 + * Discovery Locator 收敛)作为独立平台加固项另议。 * *
⚠ 新增任何 /Internal 写端点,必须在方法首行复制
* {@code SaSameUtil.checkCurrentRequestToken()} 校验——网关 block-url 不保证覆盖新路径,
* 服务侧 SAME-TOKEN 才是权威边界,漏写即等于对外开放伪造投递面。
*/
@RestController
@RequestMapping("/Internal/audit")
public class AuditInternalController {
@Autowired
private AuditEventService auditEventService;
@Autowired
private DataInterfaceSignAuditService dataInterfaceSignAuditService;
@PostMapping("/events")
public ActionResult