Spring Security fires application events after various security-related actions, such as successful login, unsuccessful login, etc. There are two hierarchies of events, AbstractAuthenticationEvent and AbstractAuthorizationEvent.
There are two main ways of being notified of these events when using the Acegi plugin:
- register an event listener, ignoring events that you're not interested in (Spring doesn't allow selective event subscription - you get called for every application event)
- register one or more callback closures in grails-app/conf/SecurityConfig.groovy that take advantage of SecurityEventListener which does the filtering for you
The first approach involves creating either a Groovy or Java class, e.g.
package com.foo.bar class MySecurityEventListener implements ApplicationListener { /** * {@inheritDoc} * @see org.springframework.context.ApplicationListener#onApplicationEvent( * org.springframework.context.ApplicationEvent) */ void onApplicationEvent(final ApplicationEvent e) { if (e instanceof AbstractAuthenticationEvent) { if (e instanceof InteractiveAuthenticationSuccessEvent) { // handle InteractiveAuthenticationSuccessEvent } else if (e instanceof AbstractAuthenticationFailureEvent) { // handle AbstractAuthenticationFailureEvent } else if (e instanceof AuthenticationSuccessEvent) { // handle AuthenticationSuccessEvent } else if (e instanceof AuthenticationSwitchUserEvent) { // handle AuthenticationSwitchUserEvent } else { // handle other authentication event } } else if (e instanceof AbstractAuthorizationEvent) { // handle authorization event } } }
and to use this just register it in resources.groovy:
mySecurityEventListener(com.foo.bar.MySecurityEventListener) {}
Alternatively, you can just register one or more callback closure(s) in grails-app/conf/SecurityConfig.groovy and let SecurityEventListener do all of the work for you, and you can just handle any event you like, e.g.:
security {
active = true
onInteractiveAuthenticationSuccessEvent = { e, appCtx ->
// handle InteractiveAuthenticationSuccessEvent
}
onAbstractAuthenticationFailureEvent = { e, appCtx ->
// handle AbstractAuthenticationFailureEvent
}
onAuthenticationSuccessEvent = { e, appCtx ->
// handle AuthenticationSuccessEvent
}
onAuthenticationSwitchUserEvent = { e, appCtx ->
// handle AuthenticationSwitchUserEvent
}
onAuthorizationEvent = { e, appCtx ->
// handle AuthorizationEvent
}
}
None of these closures are required; if none are configured, nothing will be called. Just implement the event handlers that you need, e.g.:
security {
active = true
onAuthenticationSuccessEvent = { e, appCtx ->
// handle AuthenticationSuccessEvent
}
}