Spring Boot Actuator提供了审核功能,用于在启用Spring Security的Spring Boot应用程序中发布和侦听与安全相关的事件。 默认事件是身份验证成功,身份验证失败和访问被拒绝,但是可以使用自定义事件进行扩展。
确保在项目中启用了Spring Boot Security和Actuator
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
执行器
默认情况下, /auditevents
端点/auditevents
启用状态,因此在启动应用程序(并使用应用程序日志中提供的用户名user
和password登录)后,您可以看到当前的安全事件:
{
"events": [
{
"timestamp": "2017-03-14T22:59:58+0000",
"principal": "user",
"type": "AUTHENTICATION_FAILURE",
"data": {
"details": {
"remoteAddress": "0:0:0:0:0:0:0:1",
"sessionId": null
},
"type": "org.springframework.security.authentication.BadCredentialsException",
"message": "Bad credentials"
}
},
{
"timestamp": "2017-03-14T23:00:07+0000",
"principal": "user",
"type": "AUTHENTICATION_SUCCESS",
"data": {
"details": {
"remoteAddress": "0:0:0:0:0:0:0:1",
"sessionId": null
}
}
}
]
}
/auditevents
端点接受请求的可选参数:
-
pricipal
-主体名称 -
after
–事件发生后的日期,格式如下:yyyy-MM-dd'T'HH:mm:ssZ
-
type
–事件类型(例如AUTHORIZATION_FAILURE,AUTHENTICATION_SUCCESS,AUTHENTICATION_FAILURE,AUTHENTICATION_SWITCH)
请求示例:
端点实现使用org.springframework.boot.actuate.audit.AuditEventRepository
返回所有已注册的审核事件。
- 自定义
/auditevents
端点
您可以使用endpoints.auditevents.*
属性来自定义端点。 例如,要更改审核事件端点的路径,只需使用endpoints.auditevents.path
属性。
使用
安全事件由执行器中的org.springframework.boot.actuate.audit.AuditEvent
值对象表示。 该对象包含时间戳,用户名,事件类型和事件数据。
获得有关审核事件的最简单方法是通过Spring的org.springframework.context.event.EventListener
订阅org.springframework.boot.actuate.audit.listener.AuditApplicationEvent
事件:
@Component
public class AuditApplicationEventListener {
private static final Logger LOG = LoggerFactory.getLogger(AuditApplicationEventListener.class);
@EventListener
public void onAuditEvent(AuditApplicationEvent event) {
AuditEvent actualAuditEvent = event.getAuditEvent();
LOG.info("On audit application event: timestamp: {}, principal: {}, type: {}, data: {}",
actualAuditEvent.getTimestamp(),
actualAuditEvent.getPrincipal(),
actualAuditEvent.getType(),
actualAuditEvent.getData()
);
}
}
输出示例:
2017-03-15 00:44:12.921 INFO 13316 --- [nio-8080-exec-1] p.c.d.s.s.AuditApplicationEventListener : On audit event: timestamp: Wed Mar 15 00:44:12 CET 2017, principal: user, type: AUTHENTICATION_SUCCESS, data: {details=org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null}
异步事件
@EventListener
是同步的,但是如果需要异步行为,则可以使用@Async
注释事件侦听器方法,并确保启用了异步(例如,通过@EnableAsync
):
@Component
public class AuditApplicationEventListener {
private static final Logger LOG = LoggerFactory.getLogger(AuditApplicationEventListener.class);
@EventListener
@Async
public void onAuditEvent(AuditApplicationEvent event) {
}
}
并配置:
@SpringBootApplication
@EnableAsync
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
使用
或者,您可以扩展org.springframework.boot.actuate.audit.listener.AbstractAuditListener
并覆盖其org.springframework.boot.actuate.audit.listener.AbstractAuditListener#onAuditEvent
方法:
@Component
public class AuditEventListener extends AbstractAuditListener {
private static final Logger LOG = LoggerFactory.getLogger(AuditEventListener.class);
@Override
protected void onAuditEvent(AuditEvent event) {
LOG.info("On audit event: timestamp: {}, principal: {}, type: {}, data: {}",
event.getTimestamp(),
event.getPrincipal(),
event.getType(),
event.getData()
);
}
}
注意:事件存储库中不会存储任何事件,因此/auditevents
端点将始终返回空数组。 要解决此问题,您可以注入审核存储库,也可以直接从org.springframework.boot.actuate.audit.listener.AuditListener
扩展:
@Component
public class AuditEventListener extends AbstractAuditListener {
private static final Logger LOG = LoggerFactory.getLogger(AuditEventListener.class);
@Autowired
private AuditEventRepository auditEventRepository;
@Override
protected void onAuditEvent(AuditEvent event) {
LOG.info("On audit event: timestamp: {}, principal: {}, type: {}, data: {}",
event.getTimestamp(),
event.getPrincipal(),
event.getType(),
event.getData()
);
auditEventRepository.add(event);
}
}
与事件发布者发布自己的审核事件
在下面的示例中,使用应用程序事件发布者( org.springframework.context.ApplicationEventPublisher
)来发布类型为CUSTOM_AUDIT_EVENT
的自定义审核事件。 新的侦听器方法仅侦听那些新事件,而先前的方法将忽略它们(请注意,这只是一个示例)。 与其他事件一样,自定义事件将使用审核事件存储库进行存储。
@Component
public class AuditApplicationEventListener {
private static final Logger LOG = LoggerFactory.getLogger(AuditApplicationEventListener.class);
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@EventListener(condition = "#event.auditEvent.type != 'CUSTOM_AUDIT_EVENT'")
@Async
public void onAuditEvent(AuditApplicationEvent event) {
AuditEvent actualAuditEvent = event.getAuditEvent();
LOG.info("On audit application event: timestamp: {}, principal: {}, type: {}, data: {}",
actualAuditEvent.getTimestamp(),
actualAuditEvent.getPrincipal(),
actualAuditEvent.getType(),
actualAuditEvent.getData()
);
applicationEventPublisher.publishEvent(
new AuditApplicationEvent(
new AuditEvent(actualAuditEvent.getPrincipal(), "CUSTOM_AUDIT_EVENT")
)
);
}
@EventListener(condition = "#event.auditEvent.type == 'CUSTOM_AUDIT_EVENT'")
public void onCustomAuditEvent(AuditApplicationEvent event) {
LOG.info("Handling custom audit event ...");
}
}
注意示例代码
可以在spring-boot-thymeleaf存储库中找到本文的示例代码。 默认情况下,两个配置文件中的安全性均处于禁用状态。 通过更改application.properties
的security.basic.enabled
属性来启用它。
翻译自: https://www.javacodegeeks.com/2017/03/spring-boot-security-events-actuator.html