| [[eventNotification]] |
| === Event Notification |
| |
| You can set up event notifications in two ways. The sections that follow describe each approach in more detail. |
| |
| * Register an event listener, ignoring events that do not interest you. Spring allows only partial event subscription; you use generics to register the class of events that interest you, and you are notified of that class and all subclasses. |
| * Register one or more callback closures in `grails-app/conf/application.groovy` that take advantage of the plugin's `grails.plugin.springsecurity.SecurityEventListener`. The listener does the filtering for you. |
| |
| ==== AuthenticationEventPublisher |
| |
| Spring Security publishes events using an {apidocs}org/springframework/security/authentication/AuthenticationEventPublisher.html[AuthenticationEventPublisher] which in turn fire events using the {apidocs_spring}org/springframework/context/ApplicationEventPublisher.html[ApplicationEventPublisher]. By default no events are fired since the `AuthenticationEventPublisher` instance registered is a `grails.plugin.springsecurity.authentication.NullAuthenticationEventPublisher`. But you can enable event publishing by setting `grails.plugin.springsecurity.useSecurityEventListener = true` in `grails-app/conf/application.groovy`. |
| |
| You can use the `useSecurityEventListener` setting to temporarily disable and enable the callbacks, or enable them per-environment. |
| |
| ==== UsernameNotFoundException |
| |
| Most authentication exceptions trigger an event with a similar name as described in this table: |
| |
| .Exceptions and associated events |
| [cols="50,50"] |
| |==================== |
| | *Exception* | *Event* |
| |
| |`AccountExpiredException` |
| |`AuthenticationFailureExpiredEvent` |
| |
| |`AuthenticationServiceException` |
| |`AuthenticationFailureServiceExceptionEvent` |
| |
| |`LockedException` |
| |`AuthenticationFailureLockedEvent` |
| |
| |`CredentialsExpiredException` |
| |`AuthenticationFailureCredentialsExpiredEvent` |
| |
| |`DisabledException` |
| |`AuthenticationFailureDisabledEvent` |
| |
| |`BadCredentialsException` |
| |`AuthenticationFailureBadCredentialsEvent` |
| |
| |`UsernameNotFoundException` |
| |`AuthenticationFailureBadCredentialsEvent` |
| |
| |`ProviderNotFoundException` |
| |`AuthenticationFailureProviderNotFoundEvent` |
| |==================== |
| |
| This holds for all exceptions except `UsernameNotFoundException` which triggers an `AuthenticationFailureBadCredentialsEvent` just like a `BadCredentialsException`. This is a good idea since it doesn't expose extra information - there's no differentiation between a bad password and a missing user. In addition, by default a missing user will trigger a `BadCredentialsException` for the same reasons. You can configure Spring Security to re-throw the original `UsernameNotFoundException` instead of converting it to a `BadCredentialsException` by setting `grails.plugin.springsecurity.dao.hideUserNotFoundExceptions = false` in `grails-app/conf/application.groovy`. |
| |
| Fortunately all subclasses of {apidocs}org/springframework/security/authentication/event/AbstractAuthenticationFailureEvent.html[AbstractAuthenticationFailureEvent] have a `getException()` method that gives you access to the exception that triggered the event, so you can use that to differentiate between a bad password and a missing user (if `hideUserNotFoundExceptions=false`). |