SpringSecurity实战教程(十八)安全日志与审计:关键操作追踪与风险预警
1048 字
5 分钟
SpringSecurity实战教程(十八)安全日志与审计:关键操作追踪与风险预警
1. 前言
在我们日常开发系统的安全架构中,仅仅通过认证和授权往往不足以满足合规、溯源、风险预警等需求。企业级系统必须记录并分析 “谁在什么时候对什么资源做了什么操作”,并结合规则引擎识别异常行为,及时告警。
安全审计作为企业防护的最后一道防线,能有效追踪异常行为、还原攻击链、满足合规要求。本文笔者将带领大家基于 Spring Security 构建完整的安全审计系统,实现关键操作追踪与实时风险预警。
2. Spring Security 审计架构设计
2.1 系统架构
我们常见的安全审计应该具备以下基础:以笔者目前所在公司使用的系统架构如下图:

2.2 审计日志四要素
| 要素 | 说明 | 示例 |
|---|---|---|
| 主体 | 操作执行者 | 用户 ID、IP 地址 |
| 客体 | 被操作对象 | 数据 ID、接口路径 |
| 动作 | 操作类型 | 登录、删除、授权变更 |
| 环境 | 操作上下文 | 时间、设备、地理位置 |
2.3 技术栈选择
- 事件采集:Spring AOP + ApplicationEvent
- 存储方案:MySQL + MyBatis‑Plus(中小型应用适用)或 Elasticsearch + Logstash(大型应用 + 实时检索)
- 风险分析:Drools 规则引擎
- 可视化:Grafana 监控看板
笔者为简化演示,本文以 MySQL + MyBatis‑Plus 为存储方案。
鉴于之前的子模块代码中,我们已经集成好了 MySQL + MyBatis‑Plus,在开始之前复用之前的子模块,需在 pom.xml 中引入:
<dependency> <groupId>org.drools</groupId> <artifactId>drools-core</artifactId> <version>9.44.0.Final</version></dependency><dependency> <groupId>org.kie</groupId> <artifactId>kie-spring</artifactId> <version>7.74.1.Final</version></dependency>3. 数据库与实体设计
CREATE TABLE audit_log ( id BIGINT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50), action VARCHAR(100), resource VARCHAR(200), timestamp DATETIME, duration BIGINT);@Data@TableName("audit_log")public class AuditLog { @TableId(type = IdType.AUTO) private Long id; private String username; private String action; private String resource; private LocalDateTime timestamp; private Long duration;}
// Mapper@Mapperpublic interface AuditLogMapper extends BaseMapper<AuditLog> {}4. 事件采集:Spring AOP + 自定义注解
4.1 自定义注解
@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface Audit { String action(); String resource();}4.2 AOP 切面实现
@Aspect@Componentpublic class AuditAspect { @Autowired private ApplicationEventPublisher publisher;
@Pointcut("@annotation(audit)") public void auditPoint(Audit audit) {}
@Around("auditPoint(audit)") public Object around(ProceedingJoinPoint jp, Audit audit) throws Throwable { long start = System.currentTimeMillis(); Object result = jp.proceed(); long duration = System.currentTimeMillis() - start;
MethodSignature ms = (MethodSignature) jp.getSignature(); String username = ((UserDetails) SecurityContextHolder.getContext() .getAuthentication().getPrincipal()).getUsername();
AuditEvent evt = new AuditEvent(username, audit.action(), audit.resource(), duration, LocalDateTime.now()); publisher.publishEvent(evt); return result; }}说明:上述代码中,可补充捕获异常并发布失败事件。
4.3 事件类
public record AuditEvent(String username, String action, String resource, long duration, LocalDateTime timestamp) {}4.4 事件监听并保存日志
@Component@RequiredArgsConstructorpublic class AuditListener { private final AuditLogMapper mapper; private final KieContainer kieContainer; private final Counter riskCounter; // Prometheus counter
@EventListener public void handle(AuditEvent evt) { AuditLog log = new AuditLog(null, evt.username(), evt.action(), evt.resource(), evt.timestamp(), evt.duration()); mapper.insert(log);
var session = kieContainer.newKieSession(); session.insert(log); var fired = session.fireAllRules(); session.dispose();
if (fired > 0) riskCounter.increment(); }}5. Drools 动态规则引擎
5.1 Drools 配置
@Configurationpublic class DroolsConfig { @Bean public KieContainer kieContainer() { KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem(); kfs.write(ResourceFactory.newClassPathResource("rules/audit-risk.drl")); ks.newKieBuilder(kfs).buildAll(); return ks.newKieContainer( ks.getRepository().getDefaultReleaseId()); }}5.2 规则文件 audit-risk.drl
rule "Slow Audit"when $log: AuditLog(duration > 1000)then System.out.println("风险预警:操作耗时过长 by " + $log.getUsername());end6. 监控指标采集与可视化
6.1 添加监控依赖并启用 Actuator
<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId></dependency>6.2 配置 application.yml
management: endpoints: web: exposure: include: prometheus,health6.3 指标配置
@Configurationpublic class MetricsConfig { @Bean public Counter riskCounter(MeterRegistry reg) { return Counter.builder("audit.risk.count") .description("Number of risky audit events") .register(reg); }}Prometheus 采集 /actuator/prometheus,Grafana 仪表板配置查询:audit_risk_count。
7. 控制器示例
完成上述所有操作后,可编写一个 Controller 进行相关测试:
@RestController@RequestMapping("/api")@RequiredArgsConstructorpublic class DemoController { @Audit(action = "ACCESS", resource = "demoEndpoint") @GetMapping("/demo") public String demo() { return "OK"; }}8. 结语
本章节我们以最简单的一个入门示例,主要讲解了:
- 利用 MyBatis‑Plus 实现高效、自动化地操作 MySQL 审计日志表;
- 通过 Spring AOP + ApplicationEvent 实现操作日志透明采集;
- 使用 Drools 规则引擎实现可配置、实时化的风险判断;
- 集成 Prometheus + Grafana 实现可视化监控,从流量、耗时、风险事件维度全方位审计系统行为。
这套方案可按需扩展为审计超级系统,支持敏感操作追踪、异常报警、人机判定等功能,适合企业级复杂场景。后续可添加 CI/CD 自动部署 Drools 规则、Grafana 警报等高级功能。
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!
SpringSecurity实战教程(十八)安全日志与审计:关键操作追踪与风险预警
https://fanrich.eu.org/posts/程技/java/springsecurity实战教程/十八安全日志与审计关键操作追踪与风险预警/相关文章智能推荐
1
SpringSecurity实战教程(八)Remember-Me实现原理:持久化令牌与安全存储方案
程技2026-03-02
2
SpringSecurity实战教程(一)初识Spring Security安全框架
程技2026-03-02
3
SpringSecurity实战教程(十六)微服务间安全通信 - JWT 令牌传递与校验机制
程技2026-03-02
4
SpringSecurity实战教程(七)方法级安全控制:@PreAuthorize注解的灵活运用
程技2026-03-02
5
SpringSecurity实战教程(十五)快速集成 GitHub 与 Gitee 的社交登录
程技2026-03-02
随机文章随机推荐
樊笼










