What are Spring Security authentication events, and what publishes them?
answer
- ProviderManager fires on success/failure
- AuthenticationEventPublisher -> Default impl delegates to context
- extends ApplicationEvent -> @EventListener works
- success vs AbstractAuthenticationFailureEvent
- carries getAuthentication()
basics
~10 sWhen a login succeeds or fails, Spring Security publishes an application event (like AuthenticationSuccessEvent or a failure event). You can listen to these events to log or audit logins without changing the login code.
solid answer
~30 sSpring Security emits ApplicationEvents around authentication. On a successful login the AuthenticationManager (ProviderManager) fires an AuthenticationSuccessEvent; on failure it fires a subtype of AbstractAuthenticationFailureEvent (e.g. AuthenticationFailureBadCredentialsEvent). The actual publishing is done through the AuthenticationEventPublisher interface, whose default implementation is DefaultAuthenticationEventPublisher. Because these are ordinary Spring ApplicationEvents, any bean can consume them with an @EventListener method — a clean, decoupled way to add audit logging, metrics, or lockout counters without touching the authentication filters or manager. Spring Boot auto-configures the publisher and wires it into the AuthenticationManager, so in a typical app these events fire out of the box.
code
java · 21 linesimport org.springframework.context.event.EventListener;
import org.springframework.security.authentication.AuthenticationSuccessEvent;
import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent;
import org.springframework.stereotype.Component;
@Component
public class LoginAuditListener {
@EventListener
public void onSuccess(AuthenticationSuccessEvent event) {
String user = event.getAuthentication().getName();
// audit: successful authentication for `user`
}
@EventListener
public void onFailure(AbstractAuthenticationFailureEvent event) {
String attempted = event.getAuthentication().getName();
String reason = event.getException().getMessage();
// audit: failed authentication for `attempted` (reason)
}
}go deeper
Know that success and failure events exist and are consumed with @EventListener for auditing.
Name the publisher interface and default impl, and that ProviderManager fires them.
Explain the decoupling value and that the publisher must be wired into the manager.
Frame events as the sanctioned audit/observability seam versus embedding logic in filters.
## What an "authentication event" is An **authentication event** is a Spring `ApplicationEvent` that Spring Security publishes when an authentication attempt completes — either successfully or with a failure. Because it rides on Spring's ordinary event bus (`ApplicationEventPublisher`), any bean in the context can subscribe to it and react, without being coupled to the login machinery. All of these events extend `AbstractAuthenticationEvent`, which extends `org.springframework.context.ApplicationEvent`. Each carries the `Authentication` object (`getAuthentication()`) that was being processed, so a listener can read the username via `event.getAuthentication().getName()`. ## Who publishes them The `AuthenticationManager` implementation — almost always **`ProviderManager`** — holds a reference to an **`AuthenticationEventPublisher`**. When `authenticate()` runs: - On success, `ProviderManager` calls `eventPublisher.publishAuthenticationSuccess(authentication)` → fires **`AuthenticationSuccessEvent`**. - On an `AuthenticationException`, it calls `eventPublisher.publishAuthenticationFailure(exception, authentication)` → fires a subtype of **`AbstractAuthenticationFailureEvent`**. The default publisher is **`DefaultAuthenticationEventPublisher`**, which simply delegates to the Spring `ApplicationEventPublisher` (the context). ## The two families 1. **Success:** `AuthenticationSuccessEvent`. 2. **Failure:** subclasses of `AbstractAuthenticationFailureEvent`, one per exception category, e.g. `AuthenticationFailureBadCredentialsEvent`, `AuthenticationFailureDisabledEvent`, `AuthenticationFailureLockedEvent`, `AuthenticationFailureExpiredEvent`, `AuthenticationFailureCredentialsExpiredEvent`, `AuthenticationFailureProviderNotFoundEvent`, `AuthenticationFailureServiceExceptionEvent`. ## Consuming them You write a bean with an `@EventListener` (or implement `ApplicationListener<...>`): ```java @Component class LoginAuditListener { @EventListener void onSuccess(AuthenticationSuccessEvent e) { log.info("login ok: {}", e.getAuthentication().getName()); } } ``` ## When to use Use events for cross-cutting concerns that should not live inside authentication code: audit trails, login-attempt metrics, failed-login counters feeding account lockout, sending "new sign-in" notifications. It keeps `SecurityFilterChain` and providers focused on authentication itself. ## Gotcha Events only fire if the `AuthenticationManager` actually has a publisher wired in. Spring Boot's auto-configuration does this for the default `AuthenticationManager`; but if you construct a `ProviderManager` by hand and never call `setAuthenticationEventPublisher(...)`, **no events are published** — a classic silent surprise.
- Which component actually fires AuthenticationSuccessEvent?The AuthenticationManager implementation, typically ProviderManager, via its AuthenticationEventPublisher after a successful authenticate() call.
- Why prefer an event listener over adding audit code to a custom filter?Decoupling — the listener stays independent of the authentication mechanism, works across all providers/entry points, and keeps security config focused on authentication rather than cross-cutting concerns.
saying these in an interview costs you the question
- Thinking you must implement a custom filter to detect login success/failure
- Believing these events are HTTP/servlet events rather than Spring ApplicationEvents
- Assuming events fire even when you build ProviderManager manually without a publisher