diff --git a/authentication/source/java/ch/systemsx/cisd/authentication/BasicSession.java b/authentication/source/java/ch/systemsx/cisd/authentication/BasicSession.java
index 30d2dfcc22f16cf36ea3b7710d1fa5ecd19e86e2..cb59410370c775dae1db7324f50fa962432f21d4 100644
--- a/authentication/source/java/ch/systemsx/cisd/authentication/BasicSession.java
+++ b/authentication/source/java/ch/systemsx/cisd/authentication/BasicSession.java
@@ -127,6 +127,13 @@ public class BasicSession implements Serializable
         return sessionExpirationTime;
     }
 
+    /**
+     * Called when the session is closed. Can perform additional cleanup tasks.
+     */
+    public void cleanup()
+    {
+    }
+    
     @Deprecated
     public void setSessionToken(String sessionToken)
     {
diff --git a/authentication/source/java/ch/systemsx/cisd/authentication/DefaultSessionManager.java b/authentication/source/java/ch/systemsx/cisd/authentication/DefaultSessionManager.java
index 2c0032fdc926c68e7b6321ac4f9fa43689f3f925..f4bae8c6c3d01520eaface1f30fb2478b4f49c34 100644
--- a/authentication/source/java/ch/systemsx/cisd/authentication/DefaultSessionManager.java
+++ b/authentication/source/java/ch/systemsx/cisd/authentication/DefaultSessionManager.java
@@ -231,9 +231,8 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa
         authenticationLog.info(prefix + ": login   ...FAILED");
     }
 
-    private void logSessionExpired(final FullSession<T> fullSession)
+    private void logSessionExpired(final T session)
     {
-        final T session = fullSession.getSession();
         if (operationLog.isInfoEnabled())
         {
             operationLog.info(String.format("%sExpiring session '%s' for user '%s' "
@@ -289,6 +288,11 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa
 
     @Override
     public T getSession(final String sessionToken) throws InvalidSessionException
+    {
+        return getSession(sessionToken, true);
+    }
+    
+    private T getSession(final String sessionToken, boolean checkAndTouch) throws InvalidSessionException
     {
         checkIfNotBlank(sessionToken, "sessionToken");
 
@@ -305,7 +309,6 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa
                 }
                 throw new InvalidSessionException(msg);
             }
-            final String user = getUserName(splittedToken);
             final FullSession<T> session = sessions.get(sessionToken);
             if (session == null)
             {
@@ -328,30 +331,24 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa
                 }
                 throw new InvalidSessionException(msg);
             }
-            if (doSessionExpiration(session))
+            if (checkAndTouch && doSessionExpiration(session))
             {
-                logSessionExpired(session);
-                sessions.remove(user);
+                closeSession(session.getSession(), false);
             }
-            if (isSessionUnavailable(session))
+            if (checkAndTouch && isSessionUnavailable(session))
             {
                 throw new InvalidSessionException(
                         "Session no longer available. Please login again.");
             }
             // This is where we know for sure we have a session.
-            session.touch();
+            if (checkAndTouch)
+            {
+                session.touch();
+            }
             return session.getSession();
         }
     }
 
-    // take all tokens till the third token counting from the back
-    private static String getUserName(String[] splittedSessionToken)
-    {
-        int exclusiveEndIndex = splittedSessionToken.length - 1;
-        return StringUtils
-                .join(splittedSessionToken, SESSION_TOKEN_SEPARATOR, 0, exclusiveEndIndex);
-    }
-
     @Override
     public String tryToOpenSession(final String user, final String password)
     {
@@ -408,9 +405,25 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa
     {
         synchronized (sessions)
         {
-            final T session = getSession(sessionToken);
-            sessions.remove(sessionToken);
-            logLogout(session);
+            final T session = getSession(sessionToken, false);
+            closeSession(session, true);
+        }
+    }
+
+    private void closeSession(final T session, final boolean regularLogout)
+            throws InvalidSessionException
+    {
+        synchronized (sessions)
+        {
+            session.cleanup();
+            sessions.remove(session.getSessionToken());
+            if (regularLogout)
+            {
+                logLogout(session);
+            } else
+            {
+                logSessionExpired(session);
+            }
         }
     }