
org.jwall.web.audit.session.AbstractSessionTracker Maven / Gradle / Ivy
/*
* Copyright (C) 2007-2014 Christian Bockermann
*
* This file is part of the web-audit library.
*
* web-audit library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The web-audit library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
package org.jwall.web.audit.session;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;
import org.jwall.web.audit.AuditEvent;
import org.jwall.web.audit.ModSecurity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* This class is an abstract implementation of a simple session tracker and
* provides the basis for the tracker HeuristicSessionTracker and
* CookieSessionTracker.
*
* @author Christian Bockermann <[email protected]>
*
*/
public abstract class AbstractSessionTracker implements SessionTracker {
static Logger log = LoggerFactory.getLogger(AbstractSessionTracker.class);
protected long sessionTimeOut = 2 * 3600 * 1000;
protected HashMap activeSessions;
protected List timedOutSessions;
protected int type = -1;
boolean strictSessions = true;
/**
*
* This creates a new instance of this class which is based on the default
* timeout of 2 hours ( = 7200000 ms ).
*
*/
public AbstractSessionTracker() {
super();
activeSessions = new HashMap();
timedOutSessions = new LinkedList();
}
/**
* This initializes the tracker with the given session-timeout.
*
* @param timeout
* The session-timeout in seconds.
*/
public AbstractSessionTracker(long timeout) {
this();
setSessionTimeOut(timeout);
}
/**
*
* This method tracks an AuditEvent object and creates a session if none
* existed yet. Otherwise the existing session is touched.
*
* @param event
* The AuditEvent instance that is to be associated with a
* session.
*
*/
public void eventArrived(AuditEvent event) {
String key = extractKey(event);
if (key == null) {
log.debug("Ignoring event without session-key {}",
event.getEventId());
return;
} else
log.trace("Found session-id '{}'!", key);
Session s = activeSessions.get(key);
if (s == null) {
log.debug("creating a new session ({}): {}", activeSessions
.keySet().size(), key);
Session sess = new Session(type, key, event);
activeSessions.put(key, sess);
event.setSessionId(sess.getId());
event.set(ModSecurity.SESSIONID, s.getId());
} else {
if (isExpired(s, event)) {
expireSession(s);
s = this.createSession(event);
if (s == null)
return;
event.setSessionId(s.getId());
event.set(ModSecurity.SESSIONID, s.getId());
} else {
s.addEvent(event);
event.setSessionId(s.getId());
event.set(ModSecurity.SESSIONID, s.getId());
}
}
}
public void eventsArrived(Collection events) {
for (AuditEvent evt : events)
eventArrived(evt);
}
/**
* Remove the session from the hash of active sessions and store it in the
* list of timed-out sessions.
*
* @param s
* The session to expire.
*/
protected void expireSession(Session s) {
activeSessions.remove(s.getId());
timedOutSessions.add(s);
}
/**
* This method returns the session with the given session-id.
*
* @param sessionId
* The id of the session that is to be retrieved.
* @return The appopriate session if it is still active or null
* if the session is inactive or does not exist at all.
*/
public Session getSession(String sessionId) {
return activeSessions.get(sessionId);
}
/*
*
* This method is used to create a new session.
*/
private Session createSession(AuditEvent event) {
String key = extractKey(event);
if (key == null)
return null;
Session s = activeSessions.get(key);
if (s != null && isExpired(s, event)) {
activeSessions.remove(key);
timedOutSessions.add(s);
s = null;
}
if (s == null) {
s = new Session(type, key, event);
event.setSessionId(s.getId());
activeSessions.put(key, s);
}
return s;
}
/**
*
* This method returns all the sessions (active and timed-out) that have
* been created by the session-tracker.
*
* @return A collection of session instances.
*
*/
public Collection getSessions() {
Collection v = new Vector();
v.addAll(timedOutSessions);
v.addAll(activeSessions.values());
return v;
}
/**
*
* This method simply resets the session-tracker to the initial state which
* holds no sessions.
*
*/
public void reset() {
activeSessions.clear();
timedOutSessions.clear();
}
/**
*
* This method is used to check a session for expiration according to the
* date of the given audit-event.
*
* @param s
* The session that is to be checked.
* @param event
* The event which defines the current date.
* @return true
if the sessions' last access-time is no longer
* that a period of X seconds away from the events date. Here X is
* the session-timeout defined for this session-tracker.
*
*/
public boolean isExpired(Session s, AuditEvent event) {
return event.getDate().getTime() - s.lastAccessed().getTime() > sessionTimeOut;
}
/**
* This method is used to set the session-timeout. Modification of the
* timeout does not affect any of the sessions created so far.
*
* @param s
* The number of seconds after which a session is to be timed
* out.
*/
public void setSessionTimeOut(long s) {
sessionTimeOut = s;
}
/**
* Returns the session-timeout that is used by this tracker.
*
* @return The number of seconds that a session is kept active without any
* events related to it.
*/
public long getSessionTimeOut() {
return sessionTimeOut;
}
/**
*
* In a strict session the session-id is presumed to be created by the
* server-side application. Thus only sessions for which the server
* responded with a session identifier are assumed to be valid. This
* prevents the tracker from trusting any requests of a simple
* session-guessing attack.
*
* @param b
* Wether this tracker should only track strict sessions.
*
*/
public void setStrictSessions(boolean b) {
strictSessions = b;
}
/**
*
* @return Wether the tracker is using strict sessioning only.
*/
public boolean usesStrictSessions() {
return strictSessions;
}
/**
* This method extracts the key-feature from an event which is used to
* identify the session that this event is related to. This might be the
* remote-address, a special request-parameter or a cookie.
*
* @param evt
* The event from which to extract the session-id.
* @return A string that identifies the session associated with this event.
*/
public abstract String extractKey(AuditEvent evt);
/**
* This method returns a string of all events grouped by their session-id.
*
* @return A string holding all sessions
*/
public String toString() {
StringBuffer sb = new StringBuffer();
for (Session s : getSessions()) {
sb.append("-------SESSION: " + s.getId()
+ "---------------------------\n");
}
return sb.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy