diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServer.java
index 90a226014a6b98565145df4b88eaabda2530bae4..77bed90f15169e7ed96cbcadecb88bafd9533b80 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServer.java
@@ -371,4 +371,16 @@ public abstract class AbstractServer<T extends IServer> extends AbstractServiceW
         }
         return result;
     }
+
+    public void setSessionUser(String sessionToken, String userID)
+    {
+        Session session = getSession(sessionToken);
+        PersonPE person = daoFactory.getPersonDAO().tryFindPersonByUserId(userID);
+        if (person == null)
+        {
+            throw new UserFailureException("Unknown user: " + userID);
+        }
+        HibernateUtils.initialize(person.getAllPersonRoles());
+        session.setPerson(person);
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServerLogger.java
index 261fbdcbc5324903a2288d87566e1eb53034d7f6..10988362cb1ef37e8202a8205d28f6fcfd9f4835 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServerLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServerLogger.java
@@ -26,6 +26,7 @@ import ch.systemsx.cisd.common.exceptions.InvalidSessionException;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
+import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.openbis.generic.shared.IServer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DisplaySettings;
@@ -45,29 +46,76 @@ public abstract class AbstractServerLogger implements IServer
 
     private static final String RESULT_FAILURE = " ...FAILED";
 
+    private final Logger authLog;
+    
     private final Logger accessLog;
 
     private final Logger trackingLog;
 
-    protected final ISessionManager<Session> sessionManager;
-
-    protected final boolean invocationSuccessful;
+    protected final LogMessagePrefixGenerator logMessagePrefixGenerator;
 
-    protected final long elapsedTime;
+    private final ISessionManager<Session> sessionManager;
+    
+    private final IInvocationLoggerContext context;
 
-    protected final LogMessagePrefixGenerator logMessagePrefixGenerator;
+    private final String prefixOrNull;
 
     public AbstractServerLogger(final ISessionManager<Session> sessionManager,
-            final boolean invocationSuccessful, final long elapsedTime)
+            IInvocationLoggerContext context)
     {
         this.sessionManager = sessionManager;
-        this.invocationSuccessful = invocationSuccessful;
-        this.elapsedTime = elapsedTime;
+        this.context = context;
         logMessagePrefixGenerator = new LogMessagePrefixGenerator();
+        String sessionTokenOrNull = context.tryToGetSessionToken();
+        prefixOrNull = tryToCreatePrefix(sessionTokenOrNull);
+        
+        authLog = LogFactory.getLogger(LogCategory.AUTH, getClass());
         accessLog = LogFactory.getLogger(LogCategory.ACCESS, getClass());
         trackingLog = LogFactory.getLogger(LogCategory.TRACKING, getClass());
     }
 
+    private String tryToCreatePrefix(String sessionTokenOrNull)
+    {
+        if (sessionTokenOrNull == null)
+        {
+            return null;
+        }
+        return tryToCreatePrefixFromSession(sessionTokenOrNull);
+    }
+
+    private String tryToCreatePrefixSecondTime(String sessionToken)
+    {
+        if (prefixOrNull != null)
+        {
+            return prefixOrNull;
+        }
+        return tryToCreatePrefixFromSession(sessionToken);
+    }
+
+    private String tryToCreatePrefixFromSession(String sessionToken)
+    {
+        if (sessionManager.isAWellFormedSessionToken(sessionToken) == false)
+        {
+            return null;
+        }
+        try
+        {
+            Session session = sessionManager.getSession(sessionToken);
+            return logMessagePrefixGenerator.createPrefix(session);
+        } catch (InvalidSessionException e)
+        {
+            // ignore the situation when session is not available
+            return null;
+        }
+    }
+    
+    protected final void logAuth(final String sessionToken, final String commandName,
+            final String parameterDisplayFormat, final Object... parameters)
+    {
+        logMessage(authLog, Level.INFO, sessionToken, commandName, parameterDisplayFormat,
+                parameters);
+    }
+
     protected final void logAccess(final String sessionToken, final String commandName)
     {
         logAccess(sessionToken, commandName, "");
@@ -102,15 +150,6 @@ public abstract class AbstractServerLogger implements IServer
         {
             return;
         }
-        Session sessionOrNull = null;
-        try
-        {
-            sessionOrNull = sessionManager.getSession(sessionToken);
-        } catch (InvalidSessionException e)
-        {
-            // ignore the situation when session is not available
-        }
-        final String prefix = logMessagePrefixGenerator.createPrefix(sessionOrNull);
         for (int i = 0; i < parameters.length; i++)
         {
             final Object parameter = parameters[i];
@@ -127,19 +166,19 @@ public abstract class AbstractServerLogger implements IServer
         final String elapsedTimeMessage = getElapsedTimeMessage();
         // We put on purpose 2 spaces between the command and the message derived from the
         // parameters.
-        logger.log(level, prefix
+        logger.log(level, tryToCreatePrefixSecondTime(sessionToken)
                 + String.format(": (%s) %s  %s%s", elapsedTimeMessage, commandName, message,
                         invocationStatusMessage));
     }
 
     private String getInvocationStatusMessage()
     {
-        return invocationSuccessful ? RESULT_SUCCESS : RESULT_FAILURE;
+        return context.invocationWasSuccessful() ? RESULT_SUCCESS : RESULT_FAILURE;
     }
 
     private String getElapsedTimeMessage()
     {
-        return elapsedTime + "ms";
+        return context.getElapsedTime() + "ms";
     }
 
     //
@@ -204,4 +243,10 @@ public abstract class AbstractServerLogger implements IServer
     {
         logAccess(sessionToken, "set_base_url", "BASE_URL(%s)", baseURL);
     }
+
+    public void setSessionUser(String sessionToken, String userID)
+    {
+        logMessage(authLog, Level.INFO, sessionToken, "set_session_user", "USER(%s)", new Object[]
+            { userID });
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
index aad456226c1058051b6d2bdef7d68d7a941f4935..afdb65779ff947b6fc966ce002e99771a7fddc2a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
@@ -35,6 +35,7 @@ import org.springframework.dao.DataIntegrityViolationException;
 import ch.systemsx.cisd.authentication.IAuthenticationService;
 import ch.systemsx.cisd.authentication.ISessionManager;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.DataAccessExceptionTranslator;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IAttachmentBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IAuthorizationGroupBO;
@@ -209,10 +210,9 @@ public final class CommonServer extends AbstractCommonServer<ICommonServer> impl
     /**
      * Creates a logger used to log invocations of objects of this class.
      */
-    public final ICommonServer createLogger(final boolean invocationSuccessful,
-            final long elapsedTime)
+    public final ICommonServer createLogger(IInvocationLoggerContext context)
     {
-        return new CommonServerLogger(getSessionManager(), invocationSuccessful, elapsedTime);
+        return new CommonServerLogger(getSessionManager(), context);
     }
 
     //
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
index 162f555ab059bf00ee3948081d9fec5a59f23636..428175fc675d2362550913558ae00fa27350d8d9 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
@@ -26,6 +26,7 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Level;
 
 import ch.systemsx.cisd.authentication.ISessionManager;
+import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.openbis.generic.shared.ICommonServer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolder;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
@@ -103,9 +104,9 @@ final class CommonServerLogger extends AbstractServerLogger implements ICommonSe
      * message.
      */
     CommonServerLogger(final ISessionManager<Session> sessionManager,
-            final boolean invocationSuccessful, final long elapsedTime)
+            IInvocationLoggerContext context)
     {
-        super(sessionManager, invocationSuccessful, elapsedTime);
+        super(sessionManager, context);
     }
 
     //
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
index 0ec428006ce8cea33ed7ee378ae7254bc5184d33..44e3d91fef98682af1354ec9810c50a9ab0a07b4 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
@@ -27,6 +27,7 @@ import ch.systemsx.cisd.authentication.ISessionManager;
 import ch.systemsx.cisd.common.collections.CollectionUtils;
 import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.openbis.generic.server.business.IDataStoreServiceFactory;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.ICommonBusinessObjectFactory;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IExperimentBO;
@@ -111,9 +112,9 @@ public class ETLService extends AbstractCommonServer<IETLService> implements IET
         this.dssFactory = dssFactory;
     }
 
-    public IETLService createLogger(final boolean invocationSuccessful, final long elapsedTime)
+    public IETLService createLogger(IInvocationLoggerContext context)
     {
-        return new ETLServiceLogger(getSessionManager(), invocationSuccessful, elapsedTime);
+        return new ETLServiceLogger(getSessionManager(), context);
     }
 
     @Override
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceLogger.java
index 76299f22a75ac159079d535e649032a210764886..a21c4a74759979e35d523f8a93cfe8f7cd45eef3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceLogger.java
@@ -20,6 +20,7 @@ import java.util.List;
 
 import ch.systemsx.cisd.authentication.ISessionManager;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetTypeWithVocabularyTerms;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance;
@@ -51,9 +52,9 @@ public class ETLServiceLogger extends AbstractServerLogger implements IETLServic
 {
 
     public ETLServiceLogger(final ISessionManager<Session> sessionManager,
-            final boolean invocationSuccessful, final long elapsedTime)
+            IInvocationLoggerContext context)
     {
-        super(sessionManager, invocationSuccessful, elapsedTime);
+        super(sessionManager, context);
     }
 
     public String createDataSetCode(String sessionToken) throws UserFailureException
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServer.java
index a332430325707836d51e77e53d88db5322d12bb8..64357994dca5563d1d9e6c6e19732a27176027f0 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServer.java
@@ -22,6 +22,7 @@ import java.util.List;
 import java.util.Map;
 
 import ch.systemsx.cisd.authentication.ISessionManager;
+import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.ICommonBusinessObjectFactory;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.datasetlister.IDatasetLister;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleLister;
@@ -58,10 +59,9 @@ public final class TrackingServer extends AbstractServer<ITrackingServer> implem
     /**
      * Creates a logger used to log invocations of objects of this class.
      */
-    public final ITrackingServer createLogger(final boolean invocationSuccessful,
-            final long elapsedTime)
+    public final ITrackingServer createLogger(IInvocationLoggerContext context)
     {
-        return new TrackingServerLogger(getSessionManager(), invocationSuccessful, elapsedTime);
+        return new TrackingServerLogger(getSessionManager(), context);
     }
 
     //
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServerLogger.java
index 4b5598e4b18884be1b58e0fffac5056ffd0a285a..2de861168be7b887307fd070292acd52c5dbeaa8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServerLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServerLogger.java
@@ -19,6 +19,7 @@ package ch.systemsx.cisd.openbis.generic.server;
 import java.util.List;
 
 import ch.systemsx.cisd.authentication.ISessionManager;
+import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.openbis.generic.shared.ITrackingServer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
@@ -39,9 +40,9 @@ final class TrackingServerLogger extends AbstractServerLogger implements ITracki
      * message.
      */
     TrackingServerLogger(final ISessionManager<Session> sessionManager,
-            final boolean invocationSuccessful, final long elapsedTime)
+            IInvocationLoggerContext context)
     {
-        super(sessionManager, invocationSuccessful, elapsedTime);
+        super(sessionManager, context);
     }
 
     //
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IServer.java
index 2ce174eb36970f213a8c366e94da11450481d80a..f9ededb9415c1a992ec6bce6aa7564654bff9412 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IServer.java
@@ -20,8 +20,11 @@ import java.util.List;
 
 import org.springframework.transaction.annotation.Transactional;
 
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.ISessionProvider;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RoleSet;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DisplaySettings;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.GridCustomColumn;
@@ -84,4 +87,16 @@ public interface IServer extends ISessionProvider
      * Logout the session with the specified session token.
      */
     public void logout(final String sessionToken) throws UserFailureException;
+    
+    /**
+     * Sets the user that owns this session. All methods called after this method are called with
+     * the privileges of the user specified by <var>userCode</code>.
+     * <p>
+     * This method may only be called by an administrator and only from an explicitly allowed IP
+     * address or else it will throw an {@link AuthorizationFailureException}.
+     */
+    @Transactional(readOnly = true)
+    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
+    public void setSessionUser(String sessionToken, String userID);
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Session.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Session.java
index 07273a2f0e0f0b394299addaaa87f07463d1a770..709df48f87b166446686b10195bcb059beb07982 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Session.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Session.java
@@ -117,6 +117,12 @@ public final class Session extends BasicSession implements IAuthSession
         return personOrNull;
     }
 
+    @Override
+    public String getUserName()
+    {
+        return personOrNull == null ? super.getUserName() : personOrNull.getUserId();
+    }
+
     //
     // Object
     //
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/demo/server/DemoServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/demo/server/DemoServer.java
index 129b99b85462a84d353372f6bede18a06a720931..f1b69d6e9a54fbc6fd3d2893ebb2b3d954c2fd89 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/demo/server/DemoServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/demo/server/DemoServer.java
@@ -25,6 +25,7 @@ import org.springframework.stereotype.Component;
 import ch.rinn.restrictions.Private;
 import ch.systemsx.cisd.authentication.ISessionManager;
 import ch.systemsx.cisd.common.exceptions.NotImplementedException;
+import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.openbis.generic.server.AbstractServer;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleBO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
@@ -74,9 +75,9 @@ public final class DemoServer extends AbstractServer<IDemoServer> implements IDe
     /**
      * Creates a logger used to log invocations of objects of this class.
      */
-    public final IDemoServer createLogger(final boolean invocationSuccessful, final long elapsedTime)
+    public final IDemoServer createLogger(IInvocationLoggerContext context)
     {
-        return new DemoServerLogger(getSessionManager(), invocationSuccessful, elapsedTime);
+        return new DemoServerLogger(getSessionManager(), context);
     }
 
     //
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/demo/server/DemoServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/demo/server/DemoServerLogger.java
index 0d0478dd6af9f9e29200f298987b3c128217309d..d0d9ec767a8068fb509a9a11fa896db3f01413a8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/demo/server/DemoServerLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/demo/server/DemoServerLogger.java
@@ -19,6 +19,7 @@ package ch.systemsx.cisd.openbis.plugin.demo.server;
 import java.util.Collection;
 
 import ch.systemsx.cisd.authentication.ISessionManager;
+import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.openbis.generic.server.AbstractServerLogger;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment;
@@ -36,9 +37,9 @@ import ch.systemsx.cisd.openbis.plugin.demo.shared.IDemoServer;
 final class DemoServerLogger extends AbstractServerLogger implements IDemoServer
 {
     DemoServerLogger(final ISessionManager<Session> sessionManager,
-            final boolean invocationSuccessful, final long elapsedTime)
+            IInvocationLoggerContext context)
     {
-        super(sessionManager, invocationSuccessful, elapsedTime);
+        super(sessionManager, context);
     }
 
     //
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
index 2edd4e8300c5703321cc96fc9fbda432729f3efe..5a4f6273675d84c452df396a4dbbac4c1b7c5789 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
@@ -31,6 +31,7 @@ import ch.rinn.restrictions.Private;
 import ch.systemsx.cisd.authentication.ISessionManager;
 import ch.systemsx.cisd.common.collections.CollectionUtils;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.openbis.generic.server.AbstractServer;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IExperimentBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IExternalDataBO;
@@ -123,9 +124,9 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen
     /**
      * Creates a logger used to log invocations of objects of this class.
      */
-    public IGenericServer createLogger(final boolean invocationSuccessful, final long elapsedTime)
+    public IGenericServer createLogger(IInvocationLoggerContext context)
     {
-        return new GenericServerLogger(getSessionManager(), invocationSuccessful, elapsedTime);
+        return new GenericServerLogger(getSessionManager(), context);
     }
 
     //
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServerLogger.java
index a7b92315fb213fb053b5dd408332d0677c681e90..e145da06939c63806fd027d1b2e2a78e2c28bc4d 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServerLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServerLogger.java
@@ -25,6 +25,7 @@ import org.apache.commons.lang.StringUtils;
 import ch.systemsx.cisd.authentication.ISessionManager;
 import ch.systemsx.cisd.common.collections.CollectionUtils;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.openbis.generic.server.AbstractServerLogger;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AttachmentWithContent;
@@ -60,9 +61,9 @@ final class GenericServerLogger extends AbstractServerLogger implements IGeneric
      * session manager is used to retrieve user information which will be a part of the log message.
      */
     GenericServerLogger(final ISessionManager<Session> sessionManager,
-            final boolean invocationSuccessful, final long elapsedTime)
+            IInvocationLoggerContext context)
     {
-        super(sessionManager, invocationSuccessful, elapsedTime);
+        super(sessionManager, context);
     }
 
     //
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/server/QueryServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/server/QueryServer.java
index db82360e0e76720cdca393303597e748c58c7e41..bf9859ad46077f1bb921f93f6964b58f91966109 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/server/QueryServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/server/QueryServer.java
@@ -28,6 +28,7 @@ import org.springframework.stereotype.Component;
 import ch.systemsx.cisd.authentication.ISessionManager;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.spring.ExposablePropertyPaceholderConfigurer;
+import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.common.utilities.BeanUtils;
 import ch.systemsx.cisd.common.utilities.ExtendedProperties;
 import ch.systemsx.cisd.common.utilities.PropertyUtils;
@@ -81,9 +82,9 @@ public class QueryServer extends AbstractServer<IQueryServer> implements IQueryS
         this.dao = dao;
     }
 
-    public IQueryServer createLogger(boolean invocationSuccessful, long elapsedTime)
+    public IQueryServer createLogger(IInvocationLoggerContext context)
     {
-        return new QueryServerLogger(getSessionManager(), invocationSuccessful, elapsedTime);
+        return new QueryServerLogger(getSessionManager(), context);
     }
 
     public String tryToGetQueryDatabaseLabel(String sessionToken)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/server/QueryServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/server/QueryServerLogger.java
index b9de3d06ef868f4c9160ecaf25147dba07cef68e..c740c78a68f5bb2144a556826973f6f73589750f 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/server/QueryServerLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/server/QueryServerLogger.java
@@ -19,6 +19,7 @@ package ch.systemsx.cisd.openbis.plugin.query.server;
 import java.util.List;
 
 import ch.systemsx.cisd.authentication.ISessionManager;
+import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.openbis.generic.server.AbstractServerLogger;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IExpressionUpdates;
@@ -35,9 +36,9 @@ import ch.systemsx.cisd.openbis.plugin.query.shared.basic.dto.QueryParameterBind
 class QueryServerLogger extends AbstractServerLogger implements IQueryServer
 {
     QueryServerLogger(final ISessionManager<Session> sessionManager,
-            final boolean invocationSuccessful, final long elapsedTime)
+            IInvocationLoggerContext context)
     {
-        super(sessionManager, invocationSuccessful, elapsedTime);
+        super(sessionManager, context);
     }
 
     public String tryToGetQueryDatabaseLabel(String sessionToken)
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/SetSessionUserTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/SetSessionUserTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..851215c9a0d3cf4b62351c7c3866aef0067588b2
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/SetSessionUserTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2010 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.systemtest;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.AssertJUnit.fail;
+
+import org.apache.log4j.Level;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.common.logging.BufferedAppender;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SessionContextDTO;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+@Test(groups = "system test")
+public class SetSessionUserTest extends SystemTestCase
+{
+    private BufferedAppender logRecorder;
+
+    @BeforeMethod
+    public void setUp()
+    {
+        logRecorder = new BufferedAppender("%m%n", Level.INFO);
+    }
+    
+    @AfterMethod
+    public void tearDown()
+    {
+        logRecorder.reset();
+    }
+
+    @Test
+    public void testNotInstanceAdmin()
+    {
+        
+        SessionContextDTO session = commonServer.tryToAuthenticate("observer", "a");
+        String sessionToken = session.getSessionToken();
+        try
+        {
+            commonServer.setSessionUser(sessionToken, "test");
+            fail("AuthorizationFailureException expected");
+        } catch (AuthorizationFailureException ex)
+        {
+            assertEquals("Authorization failure: None of method roles '[INSTANCE.ADMIN]' " +
+            		"could be found in roles of user 'observer'.", ex.getMessage());
+        }
+    }
+    
+    @Test
+    public void testUnkownUser()
+    {
+        
+        SessionContextDTO session = commonServer.tryToAuthenticate("test", "a");
+        String sessionToken = session.getSessionToken();
+        try
+        {
+            commonServer.setSessionUser(sessionToken, "dontKnow");
+            fail("UserFailureException expected");
+        } catch (UserFailureException ex)
+        {
+            assertEquals("Unknown user: dontKnow", ex.getMessage());
+        }
+    }
+    
+    @Test
+    public void testLogging()
+    {
+        
+        SessionContextDTO session = commonServer.tryToAuthenticate("test", "a");
+        String sessionToken = session.getSessionToken();
+        
+        commonServer.setSessionUser(sessionToken, "observer");
+        
+        String[] logContent = logRecorder.getLogContent().split("\n");
+        assertEquals(3, logContent.length);
+        String logLine = logContent[2];
+        assertTrue("Following log line does start as expected: " + logLine, logLine
+                .startsWith("[USER:'test' SPACE:'CISD' HOST:'localhost'"));
+        assertTrue("Following log line does end as expected: " + logLine, logLine
+                .endsWith("set_session_user  USER('observer')"));      
+        
+        commonServer.logout(sessionToken);
+        
+        System.out.println(logRecorder.getLogContent());
+        logContent = logRecorder.getLogContent().split("\n");
+        assertEquals(5, logContent.length);
+        logLine = logContent[4];
+        assertEquals("LOGOUT: Session '" + sessionToken + "' of user 'observer' has been closed.",
+                logLine);
+    }
+    
+    @Test
+    public void testAuthorization()
+    {
+        
+        SessionContextDTO session = commonServer.tryToAuthenticate("test", "a");
+        String sessionToken = session.getSessionToken();
+        commonServer.setSessionUser(sessionToken, "test");
+        commonServer.setSessionUser(sessionToken, "observer"); // allowed because still user 'test'
+        try
+        {
+            // not allowed because user 'observer' has no INSTANCE ADMIN rights
+            commonServer.setSessionUser(sessionToken, "observer");
+            fail("AuthorizationFailureException expected");
+        } catch (AuthorizationFailureException ex)
+        {
+            assertEquals("Authorization failure: None of method roles '[INSTANCE.ADMIN]' " +
+                    "could be found in roles of user 'observer'.", ex.getMessage());
+        }
+    }
+}