mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-30 06:03:32 +00:00
124 lines
3.2 KiB
Plaintext
124 lines
3.2 KiB
Plaintext
[[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 provide your own predicate that filters success events.
|
|
For example, the following publisher only publishes authorization grants where `ROLE_ADMIN` was required:
|
|
|
|
[tabs]
|
|
======
|
|
Java::
|
|
+
|
|
[source,java,role="primary"]
|
|
----
|
|
@Bean
|
|
AuthorizationEventPublisher authorizationEventPublisher() {
|
|
SpringAuthorizationEventPublisher eventPublisher = new SpringAuthorizationEventPublisher();
|
|
eventPublisher.setShouldPublishEvent((result) -> {
|
|
if (!result.isGranted()) {
|
|
return true;
|
|
}
|
|
if (result instanceof AuthorityAuthorizationDecision decision) {
|
|
Collection<GrantedAuthority> authorities = decision.getAuthorities();
|
|
return AuthorityUtils.authorityListToSet(authorities).contains("ROLE_ADMIN");
|
|
}
|
|
return false;
|
|
});
|
|
return eventPublisher;
|
|
}
|
|
----
|
|
|
|
Kotlin::
|
|
+
|
|
[source,kotlin,role="secondary"]
|
|
----
|
|
@Bean
|
|
fun authorizationEventPublisher(): AuthorizationEventPublisher {
|
|
val eventPublisher = SpringAuthorizationEventPublisher()
|
|
eventPublisher.setShouldPublishEvent { (result) ->
|
|
if (!result.isGranted()) {
|
|
return true
|
|
}
|
|
if (decision is AuthorityAuthorizationDecision) {
|
|
val authorities = decision.getAuthorities()
|
|
return AuthorityUtils.authorityListToSet(authorities).contains("ROLE_ADMIN")
|
|
}
|
|
return false
|
|
}
|
|
return eventPublisher
|
|
}
|
|
----
|
|
======
|