[[servlet-events]] = Authorization Events For each authorization that is denied, an `AuthorizationDeniedEvent` is fired. Also, it's possible to fire an `AuthorizationGrantedEvent` for authorizations that are granted. To listen for these events, you must first publish an `AuthorizationEventPublisher`. Spring Security's `SpringAuthorizationEventPublisher` will probably do fine. It comes publishes authorization events using Spring's `ApplicationEventPublisher`: [tabs] ====== Java:: + [source,java,role="primary"] ---- @Bean public AuthorizationEventPublisher authorizationEventPublisher (ApplicationEventPublisher applicationEventPublisher) { return new SpringAuthorizationEventPublisher(applicationEventPublisher); } ---- Kotlin:: + [source,kotlin,role="secondary"] ---- @Bean fun authorizationEventPublisher (applicationEventPublisher: ApplicationEventPublisher?): AuthorizationEventPublisher { return SpringAuthorizationEventPublisher(applicationEventPublisher) } ---- ====== Then, you can use Spring's `@EventListener` support: [tabs] ====== Java:: + [source,java,role="primary"] ---- @Component public class AuthenticationEvents { @EventListener public void onFailure(AuthorizationDeniedEvent failure) { // ... } } ---- Kotlin:: + [source,kotlin,role="secondary"] ---- @Component class AuthenticationEvents { @EventListener fun onFailure(failure: AuthorizationDeniedEvent?) { // ... } } ---- ====== [[authorization-granted-events]] == Authorization Granted Events Because ``AuthorizationGrantedEvent``s have the potential to be quite noisy, they are not published by default. In fact, publishing these events will likely require some business logic on your part to ensure that your application is not inundated with noisy authorization events. You can create your own event publisher that filters success events. For example, the following publisher only publishes authorization grants where `ROLE_ADMIN` was required: [tabs] ====== Java:: + [source,java,role="primary"] ---- @Component public class MyAuthorizationEventPublisher implements AuthorizationEventPublisher { private final ApplicationEventPublisher publisher; private final AuthorizationEventPublisher delegate; public MyAuthorizationEventPublisher(ApplicationEventPublisher publisher) { this.publisher = publisher; this.delegate = new SpringAuthorizationEventPublisher(publisher); } @Override public void publishAuthorizationEvent(Supplier authentication, T object, AuthorizationDecision decision) { if (decision == null) { return; } if (!decision.isGranted()) { this.delegate.publishAuthorizationEvent(authentication, object, decision); return; } if (shouldThisEventBePublished(decision)) { AuthorizationGrantedEvent granted = new AuthorizationGrantedEvent( authentication, object, decision); this.publisher.publishEvent(granted); } } private boolean shouldThisEventBePublished(AuthorizationDecision decision) { if (!(decision instanceof AuthorityAuthorizationDecision)) { return false; } Collection authorities = ((AuthorityAuthorizationDecision) decision).getAuthorities(); for (GrantedAuthority authority : authorities) { if ("ROLE_ADMIN".equals(authority.getAuthority())) { return true; } } return false; } } ---- Kotlin:: + [source,kotlin,role="secondary"] ---- @Component class MyAuthorizationEventPublisher(val publisher: ApplicationEventPublisher, val delegate: SpringAuthorizationEventPublisher = SpringAuthorizationEventPublisher(publisher)): AuthorizationEventPublisher { override fun publishAuthorizationEvent( authentication: Supplier?, `object`: T, decision: AuthorizationDecision? ) { if (decision == null) { return } if (!decision.isGranted) { this.delegate.publishAuthorizationEvent(authentication, `object`, decision) return } if (shouldThisEventBePublished(decision)) { val granted = AuthorizationGrantedEvent(authentication, `object`, decision) this.publisher.publishEvent(granted) } } private fun shouldThisEventBePublished(decision: AuthorizationDecision): Boolean { if (decision !is AuthorityAuthorizationDecision) { return false } val authorities = decision.authorities for (authority in authorities) { if ("ROLE_ADMIN" == authority.authority) { return true } } return false } } ---- ======