How does Spring Security integrate with Actuator auditing to record authentication success and failure events?
answer
- Security fires events → AuthenticationAuditListener translates
- types: AUTHENTICATION_SUCCESS / FAILURE / SWITCH
- AuthorizationAuditListener → AUTHORIZATION_FAILURE
- DefaultAuthenticationEventPublisher (auto)
- authz events need SpringAuthorizationEventPublisher in Security 6
basics
~20 sSpring Security fires application events on auth success and failure. Spring Boot's AuthenticationAuditListener listens for them and converts each into an AuditEvent (type AUTHENTICATION_SUCCESS or AUTHENTICATION_FAILURE) stored in the AuditEventRepository, so they appear at /actuator/auditevents.
solid answer
~40 sWhen an AuditEventRepository bean exists, Spring Boot's AuditAutoConfiguration registers an AuthenticationAuditListener and an AuthorizationAuditListener. Spring Security publishes framework events — e.g. AuthenticationSuccessEvent and subclasses of AbstractAuthenticationFailureEvent — via its DefaultAuthenticationEventPublisher (auto-configured by Boot). AuthenticationAuditListener translates those into AuditEvents with types AUTHENTICATION_SUCCESS, AUTHENTICATION_FAILURE, and AUTHENTICATION_SWITCH, putting the username in principal and the exception/type in the data map. AuthorizationAuditListener turns authorization-denied events into AUTHORIZATION_FAILURE. These flow through the same AuditListener into the repository and become visible at /actuator/auditevents. The chain requires: the actuator dependency, an AuditEventRepository bean, and Spring Security actually publishing events (for authorization denials in Security 6, you must enable authorization event publishing explicitly).
code
java · 26 linesimport org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.actuate.audit.InMemoryAuditEventRepository;
import org.springframework.boot.actuate.audit.AuditEventRepository;
import org.springframework.security.authorization.AuthorizationEventPublisher;
import org.springframework.security.authorization.SpringAuthorizationEventPublisher;
import org.springframework.context.ApplicationEventPublisher;
@Configuration
public class AuditConfig {
// Required: activates the whole audit chain incl. the security listeners.
@Bean
AuditEventRepository auditEventRepository() {
return new InMemoryAuditEventRepository();
}
// Spring Security 6: publish authorization denials so
// AUTHORIZATION_FAILURE audit events are produced.
@Bean
AuthorizationEventPublisher authorizationEventPublisher(ApplicationEventPublisher pub) {
return new SpringAuthorizationEventPublisher(pub);
}
}
// Authentication success/failure events are published automatically
// by the auto-configured DefaultAuthenticationEventPublisher.go deeper
Know that login success/failure automatically appear in auditevents.
Name the listener and the event types (AUTHENTICATION_SUCCESS/FAILURE).
Explain the full publisher→listener→repository chain and the repository-bean prerequisite.
Distinguish Security 6 authorization-event publishing, customize listeners, and route events to a SIEM.
**The event flow, end to end.** 1. **Spring Security emits events.** On login, Spring Security's `ProviderManager` (via an `AuthenticationEventPublisher`) fires an `AuthenticationSuccessEvent` or, on failure, a subclass of `AbstractAuthenticationFailureEvent` (e.g. `AuthenticationFailureBadCredentialsEvent`). Spring Boot auto-configures a `DefaultAuthenticationEventPublisher` so these are published to the application context. 2. **Actuator's listeners translate them.** When an `AuditEventRepository` bean is present, `AuditAutoConfiguration` registers: - `AuthenticationAuditListener` (extends `AbstractAuthenticationAuditListener`) — listens for `AbstractAuthenticationEvent`. It maps success → `AuditEvent` type `AUTHENTICATION_SUCCESS`, failures → `AUTHENTICATION_FAILURE`, and `AuthenticationSwitchUserEvent` → `AUTHENTICATION_SWITCH`. The principal is the authentication name; the `data` map includes details like the failure exception class/message and the web/authentication details. - `AuthorizationAuditListener` (extends `AbstractAuthorizationAuditListener`) — listens for authorization events and emits `AUTHORIZATION_FAILURE` for denials, with the principal and the required authorities/`type` in `data`. 3. **Actuator persists them.** Each translated `AuditEvent` is wrapped in an `AuditApplicationEvent` and reaches the `AuditListener`, which calls `AuditEventRepository.add(...)`. The event is now queryable at `/actuator/auditevents`. **Types you will see:** `AUTHENTICATION_SUCCESS`, `AUTHENTICATION_FAILURE`, `AUTHENTICATION_SWITCH`, `AUTHORIZATION_FAILURE`. **Prerequisites & gotchas.** - **Repository bean.** No `AuditEventRepository` → no listeners registered → nothing recorded. This is the single most common reason auth events don't appear. - **Events must actually be published.** Authentication success/failure events are published by `DefaultAuthenticationEventPublisher` out of the box. **Authorization** auditing is different in Spring Security 6: authorization decisions don't publish events unless you enable them — you register a `SpringAuthorizationEventPublisher` (an `AuthorizationEventPublisher` bean) so denials fire `AuthorizationDeniedEvent`. Without that, `AUTHORIZATION_FAILURE` audit entries won't be produced. - **Class presence.** The two listeners are also `@ConditionalOnClass` on the relevant Spring Security event base classes; no Spring Security on the classpath → no auth auditing. - **Anonymous / pre-auth.** Failures may carry principal values like the attempted username or `anonymousUser` depending on where they occur. - **Sensitive data.** These events reveal usernames, timing, and failure reasons — treat the endpoint as sensitive and restrict access. **Customizing.** You can define your own `AbstractAuthenticationAuditListener`/`AbstractAuthorizationAuditListener` bean; the `@ConditionalOnMissingBean` on the auto-configured ones lets yours take over to enrich or filter the data map. **When to use.** Great for a built-in login audit trail and quick security visibility. For long-term/compliance auditing, forward these into a durable store or SIEM (see the persistence question).
- Login failures aren't showing as AUTHENTICATION_FAILURE but you have the actuator on the classpath. What do you check?That an AuditEventRepository bean exists (otherwise no listeners are registered), that Spring Security is on the classpath, and that authentication events are actually published (DefaultAuthenticationEventPublisher is auto-configured, but a custom AuthenticationManager wiring can bypass it).
- Why might AUTHORIZATION_FAILURE events be missing even though authentication ones work?In Spring Security 6, authorization decisions don't publish events by default. You must register an AuthorizationEventPublisher (SpringAuthorizationEventPublisher) so denied authorizations fire AuthorizationDeniedEvent, which AuthorizationAuditListener then audits.
- How would you enrich the recorded data map for auth events?Define your own bean extending AbstractAuthenticationAuditListener; the auto-configured one is @ConditionalOnMissingBean, so yours replaces it and you control the AuditEvent's type/data.
saying these in an interview costs you the question
- Claiming auth events are audited without any AuditEventRepository bean.
- Assuming authorization denials are audited by default in Spring Security 6.
- Thinking the listeners poll Spring Security instead of reacting to published ApplicationEvents.
- Believing you must write the listeners yourself — Boot auto-configures them.