Quantcast
Channel: Learning the code way
Viewing all articles
Browse latest Browse all 231

Listening for Session creation

$
0
0
With Spring security session creation and destruction is managed by the framework. Along with the session management code, we often tend to have some other activities performed. For e.g. I would like a count of the sessions created. As the code is now within Spring how do we add our audit code ? In a simple application the solution would be to add a HttpSessionListener.
Accordingly in my web.xml:
<listener>
<listener-class>com.web.SessionCounter</listener-class>
</listener>
The code for the listener would be :
publicclass SessionCounter implements HttpSessionListener {
privateint counter = 0;

@Override
publicvoid sessionCreated(HttpSessionEvent event) {
counter++;
System.out.println("Total sessions created " + counter);
}

// other methods
}
Now whenever Spring creates a session, my listener is activated and the message will be logged to the console.
Total sessions created 1
The limitation with this approach is that the above listener is outside the Spring environment. If we need to access beans here, then the code gets complicated.
Spring Security provides a workaround for the problem. They have implemented a listener - HttpSessionEventPublisher.
publicclassHttpSessionEventPublisher implements HttpSessionListener {

// ... code

@Override
publicvoid sessionCreated(HttpSessionEvent event) {
HttpSessionCreatedEvent e = new HttpSessionCreatedEvent(
event.getSession());
Log log = LogFactory.getLog(LOGGER_NAME);
if (log.isDebugEnabled()) {
log.debug("Publishing event: " + e);
}
getContext(event.getSession().getServletContext()).publishEvent(e);
}

// other methods

}
As seen the Listener is similar to my listener in that both receive the HttpSessionEvent when a session is created anywhere within the application. The HttpSessionEventPublisher class however converts this event to a Spring event.It publishes the event to the ApplicationContext. Any bean that listens for this event will now be made aware of Session creation. The 2 steps to do the above would be:
  1. Update the deployment descriptor:
    <listener>
    <listener-class>
    org.springframework.security.web.session.HttpSessionEventPublisher
    </listener-class>
    </listener>
  2. Create the bean for the task:
    <beans:bean class="com.web.SessionCreatedListener"/>
The java code for the class is very much the same:
publicclassSessionCreatedListener implements
ApplicationListener<HttpSessionCreatedEvent> {

// as this is a bean, the listener code executes within the Spring
// Security Framework

privateint counter = 0;

@Override
publicvoid onApplicationEvent(
HttpSessionCreatedEvent httpSessionCreatedEvent) {
counter++;
System.out.println("Total sessions created " + counter);

Date timestamp = new Date(httpSessionCreatedEvent.getTimestamp());
System.out.println("Session created at "
+ new SimpleDateFormat("yyyy-MM-dd").format(timestamp)
+ " and session is " + httpSessionCreatedEvent.getSession());
}

}
If we run the code, the logs are as below:
DEBUG HttpSessionEventPublisher:66 - Publishing event: 
org.springframework.security.web.session.HttpSessionCreatedEvent

[source=org.apache.catalina.session.StandardSessionFacade@195f463]
TRACE XmlWebApplicationContext:332 - Publishing event in Root
WebApplicationContext:
org.springframework.security.web.session.HttpSessionCreatedEvent
[source=org.apache.catalina.session.StandardSessionFacade@195f463]
Total sessions created 2
Session created at 2013-08-12 and session is
org.apache.catalina.session.StandardSessionFacade@195f463
Similarly for Session destroy, the beans need to listen for the HttpSessionDestroyedEvent. This one is also from the HttpSessionEventPublisher class (sessionDestroyed method). The HttpSessionEventPublisher also plays an important role in setting limits on the maximum number of concurrent sessions for a user.

Viewing all articles
Browse latest Browse all 231

Trending Articles