From 072d32f2e0cb608b37bea83c79553abd89f8663f Mon Sep 17 00:00:00 2001
From: brinn <brinn>
Date: Thu, 10 Feb 2011 20:11:19 +0000
Subject: [PATCH] fix: dependency violations refactor: authorization checking
 in DSS to better separate responsibilities

SVN: 19888
---
 .../generic/server/AbstractDssServiceRpc.java | 24 +----
 .../dss/generic/server/DataStoreServer.java   |  4 +-
 .../server/DatasetSessionAuthorizer.java      | 93 +++++++++++++++++++
 .../DssServiceRpcAuthorizationAdvisor.java    | 66 +++++++++++--
 .../server/api/v1/DssServiceRpcGeneric.java   |  2 +-
 .../api/v1/DssServiceRpcGenericLogger.java    | 15 +--
 .../{ => internal}/AuthorizationGuard.java    |  4 +-
 .../{ => internal}/DataSetAccessGuard.java    |  9 +-
 .../DataSetCodeStringPredicate.java           | 24 +++--
 .../DataSetFileDTOPredicate.java              | 28 ++++--
 .../DssSessionAuthorizationHolder.java        | 77 +++++++++++++++
 .../IAuthorizationGuardPredicate.java         |  4 +-
 .../IDssServiceRpcGenericInternal.java        |  9 +-
 .../internal/IDssSessionAuthorizer.java       | 64 +++++++++++++
 .../{ => internal}/NewDataSetPredicate.java   | 27 ++++--
 .../shared/api/v1/IDssServiceRpcGeneric.java  | 10 +-
 .../source/java/dssApplicationContext.xml     |  2 +-
 .../client/api/v1/impl/DssComponentTest.java  | 56 ++++++++---
 .../generic/server/DssServiceRpcV1Test.java   |  9 +-
 .../api/v1/DssServiceRpcGenericTest.java      |  8 ++
 screening/build/build.xml                     |  8 +-
 screening/resource/dependency-structure.ddf   |  4 +-
 .../server/DssServiceRpcScreening.java        |  1 -
 .../internal}/DatasetIdentifierPredicate.java | 25 ++---
 .../SingleDataSetIdentifierPredicate.java     | 25 +++--
 .../api/v1/IDssServiceRpcScreening.java       |  8 +-
 .../server/logic/ScreeningApiImpl.java        |  2 +-
 .../ExperimentIdentifierPredicate.java        |  4 +-
 .../PlateIdentifierPredicate.java             |  4 +-
 ...ateWellReferenceWithDatasetsValidator.java |  4 +-
 .../ScreeningExperimentValidator.java         |  4 +-
 .../ScreeningPlateListReadOnlyPredicate.java  |  4 +-
 .../ScreeningPlateValidator.java              |  4 +-
 .../WellIdentifierPredicate.java              |  4 +-
 .../shared/api/v1/IScreeningApiServer.java    | 14 +--
 .../server/DssServiceRpcScreeningTest.java    | 61 +++++++++---
 36 files changed, 550 insertions(+), 161 deletions(-)
 create mode 100644 datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DatasetSessionAuthorizer.java
 rename datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/{ => internal}/AuthorizationGuard.java (92%)
 rename datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/{ => internal}/DataSetAccessGuard.java (83%)
 rename datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/{ => internal}/DataSetCodeStringPredicate.java (61%)
 rename datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/{ => internal}/DataSetFileDTOPredicate.java (55%)
 create mode 100644 datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/DssSessionAuthorizationHolder.java
 rename datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/{ => internal}/IAuthorizationGuardPredicate.java (94%)
 rename datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/{ => internal}/IDssServiceRpcGenericInternal.java (85%)
 create mode 100644 datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/IDssSessionAuthorizer.java
 rename datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/{ => internal}/NewDataSetPredicate.java (75%)
 rename screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/{v1 => authorization/internal}/DatasetIdentifierPredicate.java (75%)
 rename screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/{v1 => authorization/internal}/SingleDataSetIdentifierPredicate.java (55%)
 rename screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/{ => internal}/ExperimentIdentifierPredicate.java (96%)
 rename screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/{ => internal}/PlateIdentifierPredicate.java (97%)
 rename screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/{ => internal}/PlateWellReferenceWithDatasetsValidator.java (95%)
 rename screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/{ => internal}/ScreeningExperimentValidator.java (93%)
 rename screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/{ => internal}/ScreeningPlateListReadOnlyPredicate.java (97%)
 rename screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/{ => internal}/ScreeningPlateValidator.java (94%)
 rename screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/{ => internal}/WellIdentifierPredicate.java (93%)

diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractDssServiceRpc.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractDssServiceRpc.java
index aa43628d42e..d3f2e494707 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractDssServiceRpc.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractDssServiceRpc.java
@@ -37,7 +37,6 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.utils.DatasetLocationUtil;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
 
 /**
  * Abstract superclass of DssServiceRpc implementations.
@@ -127,7 +126,7 @@ public abstract class AbstractDssServiceRpc<T> extends AbstractServiceWithLogger
      * Check with openBIS if the user with the given sessionToken is allowed to access the data set
      * specified by the dataSetCode.
      */
-    public boolean isDatasetAccessible(String sessionToken, String dataSetCode)
+    protected boolean isDatasetAccessible(String sessionToken, String dataSetCode)
     {
         boolean access;
         if (operationLog.isInfoEnabled())
@@ -148,27 +147,6 @@ public abstract class AbstractDssServiceRpc<T> extends AbstractServiceWithLogger
         return access;
     }
 
-    public boolean isSpaceWriteable(String sessionToken, SpaceIdentifier spaceId)
-    {
-        boolean access;
-        if (operationLog.isInfoEnabled())
-        {
-            operationLog.info(String.format("Check access to the space '%s' on openBIS server.",
-                    spaceId));
-        }
-
-        try
-        {
-            openBISService.checkSpaceAccess(sessionToken, spaceId);
-            access = true;
-        } catch (UserFailureException ex)
-        {
-            access = false;
-        }
-
-        return access;
-    }
-
     protected File getRootDirectory(String datasetCode)
     {
         List<ExternalData> list = getOpenBISService().listDataSetsByCode(Arrays.asList(datasetCode));
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServer.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServer.java
index d5bd514bf4f..d31d5ba2492 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServer.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServer.java
@@ -62,7 +62,8 @@ import ch.systemsx.cisd.openbis.dss.generic.server.ConfigParameters.PluginServle
 import ch.systemsx.cisd.openbis.dss.generic.server.api.v1.DssServiceRpcGeneric;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.IDssServiceRpcGenericInternal;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.DssSessionAuthorizationHolder;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.IDssServiceRpcGenericInternal;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.DataStoreApiUrlUtilities;
 import ch.systemsx.cisd.openbis.dss.generic.shared.utils.DssPropertyParametersUtil;
 import ch.systemsx.cisd.openbis.generic.shared.IServer;
@@ -85,6 +86,7 @@ public class DataStoreServer
         public void init() throws ServletException
         {
             target = ServiceProvider.getDataStoreServer();
+            DssSessionAuthorizationHolder.setAuthorizer(new DatasetSessionAuthorizer());
         }
 
         // Code copied from org.springframework.web.context.support.HttpRequestHandlerServlet
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DatasetSessionAuthorizer.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DatasetSessionAuthorizer.java
new file mode 100644
index 00000000000..1bd830546f6
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DatasetSessionAuthorizer.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2011 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.dss.generic.server;
+
+import java.util.List;
+
+import ch.systemsx.cisd.common.exceptions.Status;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
+import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.IDssSessionAuthorizer;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
+
+/**
+ * Implementation of {@link IDssSessionAuthorizer} that asks the openBIS application server to
+ * check the data set codes.
+ * 
+ * @author Bernd Rinn
+ */
+public class DatasetSessionAuthorizer implements IDssSessionAuthorizer
+{
+
+    public Status checkDatasetAccess(String sessionToken, List<String> datasetCodes)
+    {
+        final IEncapsulatedOpenBISService openBISService = ServiceProvider.getOpenBISService();
+
+        try
+        {
+            openBISService.checkDataSetCollectionAccess(sessionToken, datasetCodes);
+            return Status.OK;
+        } catch (UserFailureException ex)
+        {
+            return Status.createError(ex.getMessage());
+        }
+    }
+
+    public Status checkDatasetAccess(String sessionToken, String datasetCode)
+    {
+        final IEncapsulatedOpenBISService openBISService = ServiceProvider.getOpenBISService();
+
+        try
+        {
+            openBISService.checkDataSetAccess(sessionToken, datasetCode);
+            return Status.OK;
+        } catch (UserFailureException ex)
+        {
+            return Status.createError(ex.getMessage());
+        }
+    }
+
+    public Status checkSpaceWriteable(String sessionToken, SpaceIdentifier spaceId)
+    {
+        final IEncapsulatedOpenBISService openBISService = ServiceProvider.getOpenBISService();
+
+        try
+        {
+            openBISService.checkSpaceAccess(sessionToken, spaceId);
+            return Status.OK;
+        } catch (UserFailureException ex)
+        {
+            return Status.createError(ex.getMessage());
+        }
+    }
+
+    public Status checkInstanceAdminAuthorization(String sessionToken)
+    {
+        final IEncapsulatedOpenBISService openBISService = ServiceProvider.getOpenBISService();
+
+        try
+        {
+            openBISService.checkInstanceAdminAuthorization(sessionToken);
+            return Status.OK;
+        } catch (UserFailureException ex)
+        {
+            return Status.createError(ex.getMessage());
+        }
+    }
+
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DssServiceRpcAuthorizationAdvisor.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DssServiceRpcAuthorizationAdvisor.java
index dc99cbe01e1..46ee9bf5aa3 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DssServiceRpcAuthorizationAdvisor.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DssServiceRpcAuthorizationAdvisor.java
@@ -16,6 +16,7 @@
 
 package ch.systemsx.cisd.openbis.dss.generic.server;
 
+import java.lang.reflect.Method;
 import java.util.List;
 
 import org.aopalliance.intercept.MethodInterceptor;
@@ -24,6 +25,7 @@ import org.apache.log4j.Logger;
 import org.springframework.aop.support.DefaultPointcutAdvisor;
 import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
 
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
@@ -31,9 +33,11 @@ import ch.systemsx.cisd.common.utilities.AnnotationUtils;
 import ch.systemsx.cisd.common.utilities.AnnotationUtils.Parameter;
 import ch.systemsx.cisd.common.utilities.ClassUtils;
 import ch.systemsx.cisd.common.utilities.MethodUtils;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.AuthorizationGuard;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.DataSetAccessGuard;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.IAuthorizationGuardPredicate;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.AuthorizationGuard;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.DataSetAccessGuard;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.DssSessionAuthorizationHolder;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.IAuthorizationGuardPredicate;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.IDssSessionAuthorizer;
 
 /**
  * The advisor for authorization in the DSS RPC interfaces.
@@ -47,9 +51,9 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.IAuthorizat
  * code (second argument)</li>
  * </ul>
  * <p>
- * It does this check by invoking the method
- * {@link AbstractDssServiceRpc#isDatasetAccessible(String, String)} on the receiver of the method
- * containing the join point.
+ * It does this check by invoking method on {@link IDssSessionAuthorizer} which it gets from
+ * {@link DssSessionAuthorizationHolder}. The correct authorizer is expected to have been set in
+ * the holder at programm startup.
  * <p>
  * Though it is not necessary to subclass DefaultPointcutAdvisor for the implementation, we subclass
  * here because to make the configuration in spring a bit simpler.
@@ -60,6 +64,9 @@ public class DssServiceRpcAuthorizationAdvisor extends DefaultPointcutAdvisor
 {
     private static final long serialVersionUID = 1L;
 
+    private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION,
+            DssServiceRpcAuthorizationAdvisor.class);
+
     private static final Logger authorizationLog = LogFactory.getLogger(LogCategory.AUTH,
             DssServiceRpcAuthorizationAdvisor.class);
 
@@ -99,10 +106,18 @@ public class DssServiceRpcAuthorizationAdvisor extends DefaultPointcutAdvisor
             List<Parameter<AuthorizationGuard>> annotatedParameters =
                     AnnotationUtils.getAnnotatedParameters(methodInvocation.getMethod(),
                             AuthorizationGuard.class);
+            final boolean requiresInstanceAdmin =
+                    checkRequiresInstanceAdmin(methodInvocation.getMethod(), sessionToken);
             // At least one of the parameters must be annotated
-            assert annotatedParameters.size() > 0 : "No guard defined";
+            assert requiresInstanceAdmin || annotatedParameters.size() > 0 : "No guard defined";
+            
+            if (requiresInstanceAdmin)
+            {
+                // An instance admin is allowed to work on all data sets.
+                return methodInvocation.proceed();
+            }
 
-            Object recv = methodInvocation.getThis();
+            final Object recv = methodInvocation.getThis();
 
             for (Parameter<AuthorizationGuard> param : annotatedParameters)
             {
@@ -120,13 +135,46 @@ public class DssServiceRpcAuthorizationAdvisor extends DefaultPointcutAdvisor
                         errorMessage = status.tryGetErrorMessage();
                     }
 
-                    throw new IllegalArgumentException(errorMessage);
+                    throw new AuthorizationFailureException(errorMessage);
                 }
             }
 
             return methodInvocation.proceed();
         }
 
+        private boolean checkRequiresInstanceAdmin(final Method method, final String sessionToken)
+        {
+            final DataSetAccessGuard guard = method.getAnnotation(DataSetAccessGuard.class);
+            final boolean requiresInstanceAdmin =
+                    (guard != null) ? guard.requiresInstanceAdmin() : false;
+            if (operationLog.isInfoEnabled())
+            {
+                operationLog.info("Check instance admin privileges.");
+            }
+
+            if (requiresInstanceAdmin)
+            {
+                final Status status =
+                        DssSessionAuthorizationHolder.getAuthorizer()
+                                .checkInstanceAdminAuthorization(sessionToken);
+                if (status != Status.OK)
+                {
+                    authorizationLog.info(String.format(
+                            "[SESSION:'%s']: Authorization failure while "
+                                    + "invoking method '%s', user is not an instance admin.",
+                            sessionToken, MethodUtils.describeMethod(method)));
+                    String errorMessage = "You are not an instance administrator.";
+                    if (null != status.tryGetErrorMessage())
+                    {
+                        errorMessage = status.tryGetErrorMessage();
+                    }
+
+                    throw new AuthorizationFailureException(errorMessage);
+                }
+            }
+            return requiresInstanceAdmin;
+        }
+
         /**
          * Because the predicate is being invoked in a context in which its types are not known,
          * there is no way to do this in a statically type-safe way.
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGeneric.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGeneric.java
index 6dcfbfd5ae7..1dcdc77e995 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGeneric.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGeneric.java
@@ -27,7 +27,7 @@ import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.etlserver.api.v1.PutDataSetService;
 import ch.systemsx.cisd.openbis.dss.generic.server.AbstractDssServiceRpc;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.IDssServiceRpcGenericInternal;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.IDssServiceRpcGenericInternal;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.DataSetFileDTO;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssBuilder;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssDTO;
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericLogger.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericLogger.java
index 976b6623237..b5ec58f00c4 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericLogger.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericLogger.java
@@ -21,12 +21,11 @@ import java.io.InputStream;
 
 import ch.systemsx.cisd.base.exceptions.IOExceptionUnchecked;
 import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.IDssServiceRpcGenericInternal;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.IDssServiceRpcGenericInternal;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.DataSetFileDTO;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssDTO;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO;
 import ch.systemsx.cisd.openbis.generic.shared.AbstractServerLogger;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
 
 /**
  * 
@@ -96,18 +95,6 @@ public class DssServiceRpcGenericLogger extends AbstractServerLogger implements
         return null;
     }
 
-    public boolean isDatasetAccessible(String sessionToken, String dataSetCode)
-    {
-        // server already logs
-        return false;
-    }
-
-    public boolean isSpaceWriteable(String sessionToken, SpaceIdentifier spaceId)
-    {
-        // server already logs
-        return false;
-    }
-    
     public void setStoreDirectory(File aFile)
     {
     }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/AuthorizationGuard.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/AuthorizationGuard.java
similarity index 92%
rename from datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/AuthorizationGuard.java
rename to datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/AuthorizationGuard.java
index 89d1759696c..7462d2c4b8f 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/AuthorizationGuard.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/AuthorizationGuard.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization;
+package ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Inherited;
@@ -24,6 +24,8 @@ import java.lang.annotation.Target;
 
 /**
  * Parameter annotation to specify which authorization class should be used to check user access.
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
  * 
  * @author Chandrasekhar Ramakrishnan
  */
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/DataSetAccessGuard.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/DataSetAccessGuard.java
similarity index 83%
rename from datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/DataSetAccessGuard.java
rename to datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/DataSetAccessGuard.java
index adcbb47f83b..0f7394695da 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/DataSetAccessGuard.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/DataSetAccessGuard.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization;
+package ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Inherited;
@@ -25,6 +25,8 @@ import java.lang.annotation.Target;
 /**
  * Annotation for service methods to automagically check that the user invoking the method has
  * access to the data set.
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
  * 
  * @author Chandrasekhar Ramakrishnan
  */
@@ -33,5 +35,8 @@ import java.lang.annotation.Target;
 @Inherited
 public @interface DataSetAccessGuard
 {
-
+    /**
+     * If calling this method requires instance admin privileges.
+     */
+    boolean requiresInstanceAdmin() default false;
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/DataSetCodeStringPredicate.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/DataSetCodeStringPredicate.java
similarity index 61%
rename from datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/DataSetCodeStringPredicate.java
rename to datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/DataSetCodeStringPredicate.java
index 3906b6c795e..492e0ba9235 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/DataSetCodeStringPredicate.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/DataSetCodeStringPredicate.java
@@ -14,29 +14,39 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization;
+package ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal;
+
+import org.apache.log4j.Logger;
 
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.common.logging.LogCategory;
+import ch.systemsx.cisd.common.logging.LogFactory;
 
 /**
  * Predicate for checking that the current user has access to a data set specified by code.
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
  * 
  * @author Chandrasekhar Ramakrishnan
  */
 public class DataSetCodeStringPredicate implements
         IAuthorizationGuardPredicate<IDssServiceRpcGenericInternal, String>
 {
+    static protected final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION,
+            DataSetCodeStringPredicate.class);
+
     public Status evaluate(IDssServiceRpcGenericInternal receiver, String sessionToken,
-            String dataSetCode) throws UserFailureException
+            String datasetCode) throws UserFailureException
     {
-        if (receiver.isDatasetAccessible(sessionToken, dataSetCode))
+        if (operationLog.isInfoEnabled())
         {
-            return Status.OK;
-        } else
-        {
-            return Status.createError("Data set (" + dataSetCode + ") does not exist.");
+            operationLog.info(String.format("Check access to the data set '%s' on openBIS server.",
+                    datasetCode));
         }
+
+        return DssSessionAuthorizationHolder.getAuthorizer().checkDatasetAccess(sessionToken,
+                datasetCode);
     }
 
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/DataSetFileDTOPredicate.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/DataSetFileDTOPredicate.java
similarity index 55%
rename from datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/DataSetFileDTOPredicate.java
rename to datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/DataSetFileDTOPredicate.java
index 3317fc860f5..b83118343ab 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/DataSetFileDTOPredicate.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/DataSetFileDTOPredicate.java
@@ -14,32 +14,42 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization;
+package ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal;
+
+import org.apache.log4j.Logger;
 
 import ch.systemsx.cisd.common.exceptions.Status;
 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.openbis.dss.generic.shared.api.v1.DataSetFileDTO;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.IDssServiceRpcGeneric;
 
 /**
  * Predicate for checking that the current user has access to a data set specified by a
  * DataSetFileDTO
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
  * 
  * @author Chandrasekhar Ramakrishnan
  */
 public class DataSetFileDTOPredicate implements
-        IAuthorizationGuardPredicate<IDssServiceRpcGenericInternal, DataSetFileDTO>
+        IAuthorizationGuardPredicate<IDssServiceRpcGeneric, DataSetFileDTO>
 {
-    public Status evaluate(IDssServiceRpcGenericInternal receiver, String sessionToken,
+    static protected final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION,
+            DataSetFileDTOPredicate.class);
+
+    public Status evaluate(IDssServiceRpcGeneric receiver, String sessionToken,
             DataSetFileDTO dataSetFile) throws UserFailureException
     {
-        if (receiver.isDatasetAccessible(sessionToken, dataSetFile.getDataSetCode()))
+        if (operationLog.isInfoEnabled())
         {
-            return Status.OK;
-        } else
-        {
-            return Status.createError("Data set (" + dataSetFile.getDataSetCode()
-                    + ") does not exist.");
+            operationLog.info(String.format(
+                    "Check access to the data set file '%s' on openBIS server.", dataSetFile));
         }
+
+        return DssSessionAuthorizationHolder.getAuthorizer().checkDatasetAccess(sessionToken,
+                dataSetFile.getDataSetCode());
     }
 
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/DssSessionAuthorizationHolder.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/DssSessionAuthorizationHolder.java
new file mode 100644
index 00000000000..794c9186ee0
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/DssSessionAuthorizationHolder.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2011 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.dss.generic.shared.api.authorization.internal;
+
+import java.util.List;
+
+import ch.systemsx.cisd.common.exceptions.Status;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
+
+/**
+ * Holder object for {@link IDssSessionAuthorizer}.
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
+ * 
+ * @author Bernd Rinn
+ */
+public class DssSessionAuthorizationHolder
+{
+
+    private static IDssSessionAuthorizer authorizer = new IDssSessionAuthorizer()
+        {
+            public Status checkDatasetAccess(String sessionToken,
+                    List<String> datasetCodes)
+            {
+                return Status.createError("Data set authorizer not set.");
+            }
+
+            public Status checkDatasetAccess(String sessionToken, String datasetCode)
+            {
+                return Status.createError("Data set authorizer not set.");
+            }
+
+            public Status checkSpaceWriteable(String sessionToken, SpaceIdentifier spaceId)
+            {
+                return Status.createError("Data set authorizer not set.");
+            }
+
+            public Status checkInstanceAdminAuthorization(String sessionToken)
+            {
+                return Status.createError("Data set authorizer not set.");
+            }
+        };
+
+    /**
+     * Returns the authorizer that can be used to check whether a session is authorized to access a
+     * data set code.
+     */
+    public static IDssSessionAuthorizer getAuthorizer()
+    {
+        return authorizer;
+    }
+
+    /**
+     * Sets the authorizer.
+     * <p>
+     * <i>Only set this method once at program startup.</i>
+     */
+    public static void setAuthorizer(IDssSessionAuthorizer authorizer)
+    {
+        DssSessionAuthorizationHolder.authorizer = authorizer;
+    }
+
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/IAuthorizationGuardPredicate.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/IAuthorizationGuardPredicate.java
similarity index 94%
rename from datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/IAuthorizationGuardPredicate.java
rename to datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/IAuthorizationGuardPredicate.java
index b31739a7812..b31c748265d 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/IAuthorizationGuardPredicate.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/IAuthorizationGuardPredicate.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization;
+package ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal;
 
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
@@ -24,6 +24,8 @@ import ch.systemsx.cisd.common.exceptions.UserFailureException;
  * <p>
  * Predicates should return Status.OK if the user is authorized for the action; they should return a
  * status with an appropriate error message if the user is not authorized.
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
  * 
  * @author Chandrasekhar Ramakrishnan
  */
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/IDssServiceRpcGenericInternal.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/IDssServiceRpcGenericInternal.java
similarity index 85%
rename from datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/IDssServiceRpcGenericInternal.java
rename to datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/IDssServiceRpcGenericInternal.java
index c84a710d73e..9756e1c581c 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/IDssServiceRpcGenericInternal.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/IDssServiceRpcGenericInternal.java
@@ -14,13 +14,12 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization;
+package ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal;
 
 import java.io.File;
 
 import ch.systemsx.cisd.openbis.dss.generic.server.DataStoreServer;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.IDssServiceRpcGeneric;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
 
 /**
  * The IDssServiceRpcGeneric interface extended with methods that are internal to the DSS server.
@@ -28,6 +27,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
  * This interface is necessary because the implementation of IDssServiceRpcGeneric that is visible
  * to the {@link DataStoreServer} is a proxy. The methods here are used internally, but need to be
  * known to the proxy as well. (See the dssApplicationContext.xml file as well.)
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
  * 
  * @author Chandrasekhar Ramakrishnan
  */
@@ -36,8 +37,4 @@ public interface IDssServiceRpcGenericInternal extends IDssServiceRpcGeneric
     public void setStoreDirectory(File aFile);
 
     public void setIncomingDirectory(File aFile);
-
-    public boolean isDatasetAccessible(String sessionToken, String dataSetCode);
-
-    public boolean isSpaceWriteable(String sessionToken, SpaceIdentifier spaceId);
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/IDssSessionAuthorizer.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/IDssSessionAuthorizer.java
new file mode 100644
index 00000000000..4caaf333259
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/IDssSessionAuthorizer.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2011 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.dss.generic.shared.api.authorization.internal;
+
+import java.util.List;
+
+import ch.systemsx.cisd.common.exceptions.Status;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
+
+/**
+ * Role that allows to authorize calls in DSS for a given session.
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
+ * 
+ * @author Bernd Rinn
+ */
+public interface IDssSessionAuthorizer
+{
+    /**
+     * Checks whether the session identified by <var>sessionToken</var> is authorized to access the
+     * given <var>datasetCode</var>.
+     * 
+     * @return {@link Status#OK} if the access is granted, an error status otherwise. 
+     */
+    public Status checkDatasetAccess(String sessionToken, String datasetCode);
+
+    /**
+     * Checks whether the session identified by <var>sessionToken</var> is authorized to access the
+     * given <var>datasetCodes</var>.
+     * 
+     * @return {@link Status#OK} if the access is granted, an error status otherwise. 
+     */
+    public Status checkDatasetAccess(String sessionToken, List<String> datasetCodes);
+
+    /**
+     * Checks whether the session identified by <var>sessionToken</var> is authorized to write to
+     * the given <var>spaceId</var>.
+     * 
+     * @return {@link Status#OK} if the access is granted, an error status otherwise. 
+     */
+    public Status checkSpaceWriteable(String sessionToken, SpaceIdentifier spaceId);
+
+    /**
+     * Checks whether the session identified by <var>sessionToken</var> has openBIS instance admin
+     * privileges.
+     * 
+     * @return {@link Status#OK} if the access is granted, an error status otherwise. 
+     */
+    public Status checkInstanceAdminAuthorization(String sessionToken);
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/NewDataSetPredicate.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/NewDataSetPredicate.java
similarity index 75%
rename from datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/NewDataSetPredicate.java
rename to datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/NewDataSetPredicate.java
index 158f9f53c1b..f5567625d73 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/NewDataSetPredicate.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/internal/NewDataSetPredicate.java
@@ -14,10 +14,15 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization;
+package ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal;
+
+import org.apache.log4j.Logger;
 
 import ch.systemsx.cisd.common.exceptions.Status;
 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.openbis.dss.generic.shared.api.v1.IDssServiceRpcGeneric;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetOwner;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
@@ -29,23 +34,29 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
 /**
  * Predicate for checking that the new data set can be registered (i.e., user has access to the
  * space for the new data set).
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
  * 
  * @author Chandrasekhar Ramakrishnan
  */
 public class NewDataSetPredicate implements
-        IAuthorizationGuardPredicate<IDssServiceRpcGenericInternal, NewDataSetDTO>
+        IAuthorizationGuardPredicate<IDssServiceRpcGeneric, NewDataSetDTO>
 {
-    public Status evaluate(IDssServiceRpcGenericInternal receiver, String sessionToken,
+    static protected final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION,
+            NewDataSetPredicate.class);
+
+    public Status evaluate(IDssServiceRpcGeneric receiver, String sessionToken,
             NewDataSetDTO newDataSet) throws UserFailureException
     {
         SpaceIdentifier spaceId = getSpaceIdentifier(newDataSet);
-        if (receiver.isSpaceWriteable(sessionToken, spaceId))
+        if (operationLog.isInfoEnabled())
         {
-            return Status.OK;
-        } else
-        {
-            return Status.createError("Space (" + spaceId + ") is not writeable.");
+            operationLog.info(String.format("Check write access to space '%s' on openBIS server.",
+                    spaceId));
         }
+
+        return DssSessionAuthorizationHolder.getAuthorizer().checkSpaceWriteable(sessionToken,
+                spaceId);
     }
 
     private SpaceIdentifier getSpaceIdentifier(NewDataSetDTO newDataSet)
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/IDssServiceRpcGeneric.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/IDssServiceRpcGeneric.java
index 7976c9bf308..a462653c788 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/IDssServiceRpcGeneric.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/IDssServiceRpcGeneric.java
@@ -20,11 +20,11 @@ import java.io.InputStream;
 
 import ch.systemsx.cisd.base.exceptions.IOExceptionUnchecked;
 import ch.systemsx.cisd.common.api.IRpcService;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.AuthorizationGuard;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.DataSetAccessGuard;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.DataSetCodeStringPredicate;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.DataSetFileDTOPredicate;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.NewDataSetPredicate;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.AuthorizationGuard;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.DataSetAccessGuard;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.DataSetCodeStringPredicate;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.DataSetFileDTOPredicate;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.NewDataSetPredicate;
 
 /**
  * Generic functionality for interacting with the DSS.
diff --git a/datastore_server/source/java/dssApplicationContext.xml b/datastore_server/source/java/dssApplicationContext.xml
index 3f1e65f2a68..29ade5ec5b3 100644
--- a/datastore_server/source/java/dssApplicationContext.xml
+++ b/datastore_server/source/java/dssApplicationContext.xml
@@ -79,7 +79,7 @@
             <bean class="org.springframework.aop.framework.ProxyFactoryBean">
                 <property name="proxyInterfaces">
                     <list>
-                        <value>ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.IDssServiceRpcGenericInternal</value>
+                        <value>ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.IDssServiceRpcGenericInternal</value>
                     </list>
                 </property>
                 <property name="interceptorNames">
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponentTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponentTest.java
index 402125ec804..5e132b557af 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponentTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponentTest.java
@@ -32,6 +32,7 @@ import org.springframework.aop.TargetSource;
 import org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.beans.factory.support.StaticListableBeanFactory;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -42,14 +43,19 @@ import ch.systemsx.cisd.common.api.IRpcService;
 import ch.systemsx.cisd.common.api.IRpcServiceFactory;
 import ch.systemsx.cisd.common.api.RpcServiceInterfaceDTO;
 import ch.systemsx.cisd.common.api.RpcServiceInterfaceVersionDTO;
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
 import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.openbis.dss.client.api.v1.IDataSetDss;
 import ch.systemsx.cisd.openbis.dss.generic.server.AbstractDssServiceRpc;
+import ch.systemsx.cisd.openbis.dss.generic.server.DatasetSessionAuthorizer;
 import ch.systemsx.cisd.openbis.dss.generic.server.DssServiceRpcAuthorizationAdvisor;
 import ch.systemsx.cisd.openbis.dss.generic.server.api.v1.DssServiceRpcGeneric;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.IDssServiceRpcGenericInternal;
+import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.DssSessionAuthorizationHolder;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.IDssServiceRpcGenericInternal;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.DataSetFileDTO;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.DataStoreApiUrlUtilities;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssBuilder;
@@ -73,13 +79,15 @@ public class DssComponentTest extends AbstractFileSystemTestCase
 
     private IGeneralInformationService openBisService;
 
+    private IEncapsulatedOpenBISService etlService;
+
     private IRpcServiceFactory dssServiceFactory;
 
     private DssComponent dssComponent;
 
     private File randomDataFile;
 
-    private static final String DUMMY_SESSSION_TOKEN = "DummySessionToken";
+    private static final String DUMMY_SESSION_TOKEN = "DummySessionToken";
 
     private static final String DUMMY_DSS_DOWNLOAD_URL = "http://localhost/"
             + GenericSharedConstants.DATA_STORE_SERVER_WEB_APPLICATION_NAME;
@@ -127,11 +135,16 @@ public class DssComponentTest extends AbstractFileSystemTestCase
     public void setUp() throws IOException
     {
         super.setUp();
+        DssSessionAuthorizationHolder.setAuthorizer(new DatasetSessionAuthorizer());
+        final StaticListableBeanFactory applicationContext = new StaticListableBeanFactory();
+        ServiceProvider.setBeanFactory(applicationContext);
         context = new Mockery();
         openBisService = context.mock(IGeneralInformationService.class);
         dssServiceFactory = context.mock(IRpcServiceFactory.class);
         dssComponent = new DssComponent(openBisService, dssServiceFactory, null);
         randomDataFile = getFileWithRandomData(1);
+        etlService = context.mock(IEncapsulatedOpenBISService.class);
+        applicationContext.addBean("openBIS-service", etlService);
     }
 
     @AfterMethod
@@ -177,7 +190,7 @@ public class DssComponentTest extends AbstractFileSystemTestCase
     public void testListDataSetFilesNoLogin() throws IOException
     {
         dssComponent =
-                new DssComponent(openBisService, dssServiceFactory, DUMMY_SESSSION_TOKEN);
+                new DssComponent(openBisService, dssServiceFactory, DUMMY_SESSION_TOKEN);
         setupExpectationsNoLogin();
         IDataSetDss dataSetProxy = dssComponent.getDataSet(DUMMY_DATA_SET_CODE);
         FileInfoDssDTO[] fileInfos = dataSetProxy.listFiles("/", true);
@@ -196,9 +209,9 @@ public class DssComponentTest extends AbstractFileSystemTestCase
             IDataSetDss dataSetProxy = dssComponent.getDataSet(DUMMY_DATA_SET_CODE);
             dataSetProxy.listFiles("/", true);
             fail("Unauthorized access to data set should have thrown an exception.");
-        } catch (IllegalArgumentException ex)
+        } catch (AuthorizationFailureException ex)
         {
-            assertEquals("Data set (" + DUMMY_DATA_SET_CODE + ") does not exist.", ex.getMessage());
+            assertEquals("Authorization failure: Not allowed.", ex.getMessage());
         }
 
         context.assertIsSatisfied();
@@ -237,7 +250,7 @@ public class DssComponentTest extends AbstractFileSystemTestCase
     @Test
     public void testLinkToContentsEarlierVersion() throws IOException
     {
-        setupExpectations(true, true);
+        setupExpectations(null, true);
 
         dssComponent.login("foo", "bar");
         IDataSetDss dataSetProxy = dssComponent.getDataSet(DUMMY_DATA_SET_CODE);
@@ -256,7 +269,7 @@ public class DssComponentTest extends AbstractFileSystemTestCase
     @Test
     public void testUnsupportedInterface() throws IOException
     {
-        setupExpectations("Some Server Interface", true, true, false);
+        setupExpectations("Some Server Interface", true, null, false);
 
         dssComponent.login("foo", "bar");
         try
@@ -309,12 +322,12 @@ public class DssComponentTest extends AbstractFileSystemTestCase
         setupExpectations(true);
     }
 
-    private void setupExpectations(boolean isDataSetAccessible) throws IOException
+    private void setupExpectations(Boolean isDataSetAccessible) throws IOException
     {
         setupExpectations(IDssServiceRpcGeneric.DSS_SERVICE_NAME, true, isDataSetAccessible, false);
     }
 
-    private void setupExpectations(boolean isDataSetAccessible, boolean returnEarlierVersion)
+    private void setupExpectations(Boolean isDataSetAccessible, boolean returnEarlierVersion)
             throws IOException
     {
         setupExpectations(IDssServiceRpcGeneric.DSS_SERVICE_NAME, true, isDataSetAccessible,
@@ -327,7 +340,7 @@ public class DssComponentTest extends AbstractFileSystemTestCase
     }
 
     private void setupExpectations(String serviceName, final boolean needsLogin,
-            boolean isDataSetAccessible, boolean returnEarlierVersion) throws IOException
+            final Boolean isDataSetAccessible, boolean returnEarlierVersion) throws IOException
     {
         final SessionContextDTO session = getDummySession();
 
@@ -358,13 +371,28 @@ public class DssComponentTest extends AbstractFileSystemTestCase
 
         ifaces.add(iface);
 
+        if (isDataSetAccessible != null)
+        {
+            context.checking(new Expectations()
+                {
+                    {
+                        atLeast(1).of(etlService).checkDataSetAccess(DUMMY_SESSION_TOKEN,
+                                DUMMY_DATA_SET_CODE);
+                        if (isDataSetAccessible == false)
+                        {
+                            will(throwException(new UserFailureException("Not allowed.")));
+                        }
+                    }
+                });
+        }
+
         dssServiceV1_0 =
                 getAdvisedDssService(new MockDssServiceRpcV1_0(null, fileInfos,
-                        new FileInputStream(randomDataFile), isDataSetAccessible));
+                        new FileInputStream(randomDataFile), isDataSetAccessible == null ? true : isDataSetAccessible));
 
         dssServiceV1_1 =
                 getAdvisedDssService(new MockDssServiceRpcV1_1(null, fileInfos,
-                        new FileInputStream(randomDataFile), isDataSetAccessible));
+                        new FileInputStream(randomDataFile), isDataSetAccessible == null ? true : isDataSetAccessible));
 
         context.checking(new Expectations()
             {
@@ -396,7 +424,7 @@ public class DssComponentTest extends AbstractFileSystemTestCase
     private SessionContextDTO getDummySession()
     {
         final SessionContextDTO session = new SessionContextDTO();
-        session.setSessionToken(DUMMY_SESSSION_TOKEN);
+        session.setSessionToken(DUMMY_SESSION_TOKEN);
         return session;
     }
 
@@ -502,7 +530,7 @@ public class DssComponentTest extends AbstractFileSystemTestCase
         }
 
         @Override
-        public boolean isDatasetAccessible(String sessionToken, String dataSetCode)
+        protected boolean isDatasetAccessible(String sessionToken, String dataSetCode)
         {
             return isDataSetAccessible;
         }
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/DssServiceRpcV1Test.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/DssServiceRpcV1Test.java
index cda5e6076e1..f5de25a1b88 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/DssServiceRpcV1Test.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/DssServiceRpcV1Test.java
@@ -33,6 +33,7 @@ import org.aopalliance.intercept.MethodInvocation;
 import org.jmock.Expectations;
 import org.jmock.Mockery;
 import org.springframework.aop.framework.ProxyFactory;
+import org.springframework.beans.factory.support.StaticListableBeanFactory;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -58,7 +59,9 @@ import ch.systemsx.cisd.etlserver.validation.IDataSetValidator;
 import ch.systemsx.cisd.openbis.dss.generic.server.DssServiceRpcAuthorizationAdvisor.DssServiceRpcAuthorizationMethodInterceptor;
 import ch.systemsx.cisd.openbis.dss.generic.server.api.v1.DssServiceRpcGeneric;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.IDssServiceRpcGenericInternal;
+import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.DssSessionAuthorizationHolder;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.IDssServiceRpcGenericInternal;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.DataSetFileDTO;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssBuilder;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssDTO;
@@ -129,8 +132,12 @@ public class DssServiceRpcV1Test extends AbstractFileSystemTestCase
     public void setUp() throws IOException
     {
         super.setUp();
+        DssSessionAuthorizationHolder.setAuthorizer(new DatasetSessionAuthorizer());
+        final StaticListableBeanFactory applicationContext = new StaticListableBeanFactory();
+        ServiceProvider.setBeanFactory(applicationContext);
         context = new Mockery();
         openBisService = context.mock(IEncapsulatedOpenBISService.class);
+        applicationContext.addBean("openBIS-service", openBisService);
         mailClient = context.mock(IMailClient.class);
 
         codeExtractor = new DefaultDataSetInfoExtractor(new Properties());
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericTest.java
index e8f33bec83f..bf011541c11 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericTest.java
@@ -22,13 +22,17 @@ import java.util.Arrays;
 import org.jmock.Expectations;
 import org.jmock.Mockery;
 import org.springframework.aop.framework.ProxyFactoryBean;
+import org.springframework.beans.factory.support.StaticListableBeanFactory;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.base.tests.AbstractFileSystemTestCase;
+import ch.systemsx.cisd.openbis.dss.generic.server.DatasetSessionAuthorizer;
 import ch.systemsx.cisd.openbis.dss.generic.server.DssServiceRpcAuthorizationAdvisor;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
+import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.DssSessionAuthorizationHolder;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssDTO;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.IDssServiceRpcGeneric;
 import ch.systemsx.cisd.openbis.dss.generic.shared.utils.DatasetLocationUtil;
@@ -55,8 +59,12 @@ public class DssServiceRpcGenericTest extends AbstractFileSystemTestCase
     @BeforeMethod
     public void beforeMethod()
     {
+        DssSessionAuthorizationHolder.setAuthorizer(new DatasetSessionAuthorizer());
+        final StaticListableBeanFactory applicationContext = new StaticListableBeanFactory();
+        ServiceProvider.setBeanFactory(applicationContext);
         context = new Mockery();
         service = context.mock(IEncapsulatedOpenBISService.class);
+        applicationContext.addBean("openBIS-service", service);
         ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
         proxyFactoryBean.setInterfaces(new Class[] {IDssServiceRpcGeneric.class});
         DssServiceRpcGeneric nakedDssService = new DssServiceRpcGeneric(service);
diff --git a/screening/build/build.xml b/screening/build/build.xml
index 1fadeca8598..fa92902673d 100644
--- a/screening/build/build.xml
+++ b/screening/build/build.xml
@@ -347,12 +347,12 @@
       	<include name="ch/systemsx/cisd/openbis/dss/client/api/v1/**/*.class" />
       	<include name="ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/**/*.class" />
       	<include name="ch/systemsx/cisd/openbis/dss/generic/shared/api/authorization/**/*.class" />
-      	<include name="ch/systemsx/cisd/openbis/dss/screening/shared/api/v1/**/*.class" />
+      	<include name="ch/systemsx/cisd/openbis/dss/screening/shared/api/**/*.class" />
       	<include name="ch/systemsx/cisd/openbis/generic/shared/basic/**/*.class" />
-      	<include name="ch/systemsx/cisd/openbis/generic/shared/api/v1/**/*.class" />
+      	<include name="ch/systemsx/cisd/openbis/generic/shared/api/**/*.class" />
       	<include name="ch/systemsx/cisd/openbis/generic/shared/authorization/annotation/**/*.class" />
-      	<include name="ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/**/*.class" />
-       	<include name="ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/**/*.class" />
+      	<include name="ch/systemsx/cisd/openbis/plugin/screening/shared/api/**/*.class" />
+       	<include name="ch/systemsx/cisd/openbis/plugin/screening/client/api/**/*.class" />
        	<include name="ch/systemsx/cisd/openbis/plugin/screening/client/cli/**/*.class" />
        	<include name="${build.info.filename}" />
       </fileset>
diff --git a/screening/resource/dependency-structure.ddf b/screening/resource/dependency-structure.ddf
index e274815fcf6..1d5366d2a5f 100644
--- a/screening/resource/dependency-structure.ddf
+++ b/screening/resource/dependency-structure.ddf
@@ -7,10 +7,10 @@
 
 [screening_openbis] = ${screening}.*
 
-[dss_authorization] = ${root}.dss.generic.shared.api.authorization.*
+[dss_authorization] = ${root}.dss.generic.shared.api.authorization.internal.* ${root}.dss.screening.shared.api.authorization.internal.*
 [dss_api] = ${root}.dss.screening.shared.api.v1.** ${root}.dss.client.api.v1.** ${root}.dss.generic.shared.api.v1.**
 [dss] = ${root}.dss.* ch.systemsx.cisd.etlserver.* excluding [dss_api] [dss_authorization]
-check sets [screening_openbis] [dss]
+check sets [screening_openbis] [dss] [dss_api] [dss_authorization]
 
 check [screening_openbis] independentOf [dss]
 
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java
index 80a853c2622..6494c911cb0 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java
@@ -642,7 +642,6 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc
             List<IDatasetIdentifier> dataSetIdentifiers, String channel,
             IImageTransformerFactory transformerFactory)
     {
-        getOpenBISService().checkInstanceAdminAuthorization(sessionToken);
         for (IDatasetIdentifier datasetIdentifier : dataSetIdentifiers)
         {
             ImgDatasetDTO dataset = getImagingDataset(datasetIdentifier);
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/v1/DatasetIdentifierPredicate.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/authorization/internal/DatasetIdentifierPredicate.java
similarity index 75%
rename from screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/v1/DatasetIdentifierPredicate.java
rename to screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/authorization/internal/DatasetIdentifierPredicate.java
index f739a2afb35..958e1d19af2 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/v1/DatasetIdentifierPredicate.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/authorization/internal/DatasetIdentifierPredicate.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.dss.screening.shared.api.v1;
+package ch.systemsx.cisd.openbis.dss.screening.shared.api.authorization.internal;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -25,18 +25,19 @@ import ch.systemsx.cisd.common.exceptions.Status;
 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.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
-import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.IAuthorizationGuardPredicate;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.DssSessionAuthorizationHolder;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.IAuthorizationGuardPredicate;
+import ch.systemsx.cisd.openbis.dss.screening.shared.api.v1.IDssServiceRpcScreening;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IDatasetIdentifier;
 
 /**
  * Predicate that checks if the user has access to a collection of data set identifiers.
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
  * 
  * @author Chandrasekhar Ramakrishnan
  */
-public class DatasetIdentifierPredicate
-        implements
+public class DatasetIdentifierPredicate implements
         IAuthorizationGuardPredicate<IDssServiceRpcScreening, List<? extends IDatasetIdentifier>>
 {
 
@@ -46,22 +47,14 @@ public class DatasetIdentifierPredicate
     public Status evaluate(IDssServiceRpcScreening receiver, String sessionToken,
             List<? extends IDatasetIdentifier> datasetIdentifiers) throws UserFailureException
     {
-        final IEncapsulatedOpenBISService openBISService = ServiceProvider.getOpenBISService();
         if (operationLog.isInfoEnabled())
         {
             operationLog.info(String.format(
                     "Check access to the data sets '%s' on openBIS server.", datasetIdentifiers));
         }
 
-        try
-        {
-            openBISService.checkDataSetCollectionAccess(sessionToken,
-                    getDatasetCodes(datasetIdentifiers));
-            return Status.OK;
-        } catch (UserFailureException ex)
-        {
-            return Status.createError(ex.getMessage());
-        }
+        return DssSessionAuthorizationHolder.getAuthorizer().checkDatasetAccess(
+                sessionToken, getDatasetCodes(datasetIdentifiers));
     }
 
     private List<String> getDatasetCodes(List<? extends IDatasetIdentifier> datasetIdentifiers)
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/v1/SingleDataSetIdentifierPredicate.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/authorization/internal/SingleDataSetIdentifierPredicate.java
similarity index 55%
rename from screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/v1/SingleDataSetIdentifierPredicate.java
rename to screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/authorization/internal/SingleDataSetIdentifierPredicate.java
index 44fc0f5633c..24f9116aaae 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/v1/SingleDataSetIdentifierPredicate.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/authorization/internal/SingleDataSetIdentifierPredicate.java
@@ -14,17 +14,23 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.dss.screening.shared.api.v1;
+package ch.systemsx.cisd.openbis.dss.screening.shared.api.authorization.internal;
 
-import java.util.Collections;
+import org.apache.log4j.Logger;
 
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.IAuthorizationGuardPredicate;
+import ch.systemsx.cisd.common.logging.LogCategory;
+import ch.systemsx.cisd.common.logging.LogFactory;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.DssSessionAuthorizationHolder;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.IAuthorizationGuardPredicate;
+import ch.systemsx.cisd.openbis.dss.screening.shared.api.v1.IDssServiceRpcScreening;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IDatasetIdentifier;
 
 /**
  * A predicate for testing a single data set identifier.
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
  *
  * @author Franz-Josef Elmer
  */
@@ -32,13 +38,20 @@ public class SingleDataSetIdentifierPredicate implements
         IAuthorizationGuardPredicate<IDssServiceRpcScreening, IDatasetIdentifier>
 
 {
-    private static final DatasetIdentifierPredicate PREDICATE = new DatasetIdentifierPredicate();
+    static protected final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION,
+            DatasetIdentifierPredicate.class);
 
     public Status evaluate(IDssServiceRpcScreening receiver, String sessionToken,
             IDatasetIdentifier datasetIdentifier) throws UserFailureException
     {
-        return PREDICATE.evaluate(receiver, sessionToken,
-                Collections.singletonList(datasetIdentifier));
+        if (operationLog.isInfoEnabled())
+        {
+            operationLog.info(String.format(
+                    "Check access to the data set '%s' on openBIS server.", datasetIdentifier));
+        }
+
+        return DssSessionAuthorizationHolder.getAuthorizer().checkDatasetAccess(
+                sessionToken, datasetIdentifier.getDatasetCode());
     }
 
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/v1/IDssServiceRpcScreening.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/v1/IDssServiceRpcScreening.java
index 0b7a2f9d1e0..1ce2f1ed6ed 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/v1/IDssServiceRpcScreening.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/v1/IDssServiceRpcScreening.java
@@ -22,8 +22,10 @@ import java.util.List;
 import ch.systemsx.cisd.base.image.IImageTransformerFactory;
 import ch.systemsx.cisd.common.api.IRpcService;
 import ch.systemsx.cisd.common.api.MinimalMinorVersion;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.AuthorizationGuard;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.DataSetAccessGuard;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.AuthorizationGuard;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.DataSetAccessGuard;
+import ch.systemsx.cisd.openbis.dss.screening.shared.api.authorization.internal.DatasetIdentifierPredicate;
+import ch.systemsx.cisd.openbis.dss.screening.shared.api.authorization.internal.SingleDataSetIdentifierPredicate;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDataset;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetReference;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetWellReference;
@@ -307,7 +309,7 @@ public interface IDssServiceRpcScreening extends IRpcService
      * @since 1.4
      */
     @MinimalMinorVersion(4)
-    @DataSetAccessGuard
+    @DataSetAccessGuard(requiresInstanceAdmin = true)
     public void saveImageTransformerFactory(
             String sessionToken,
             @AuthorizationGuard(guardClass = DatasetIdentifierPredicate.class) List<IDatasetIdentifier> dataSetIdentifiers,
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java
index 229c378fa3a..9f68eaad7c8 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java
@@ -67,7 +67,7 @@ import ch.systemsx.cisd.openbis.generic.shared.util.SpaceCodeHelper;
 import ch.systemsx.cisd.openbis.plugin.screening.server.IScreeningBusinessObjectFactory;
 import ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.IScreeningQuery;
 import ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.PlateGeometryContainer;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.ScreeningExperimentValidator;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.internal.ScreeningExperimentValidator;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.DatasetIdentifier;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ExperimentIdentifier;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetReference;
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/ExperimentIdentifierPredicate.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/ExperimentIdentifierPredicate.java
similarity index 96%
rename from screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/ExperimentIdentifierPredicate.java
rename to screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/ExperimentIdentifierPredicate.java
index f775a7c38e2..69bf323f771 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/ExperimentIdentifierPredicate.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/ExperimentIdentifierPredicate.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization;
+package ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.internal;
 
 import java.util.List;
 
@@ -29,6 +29,8 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ExperimentIde
 
 /**
  * A predicate for {@link ExperimentIdentifier}.
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
  * 
  * @author Bernd Rinn
  */
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/PlateIdentifierPredicate.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/PlateIdentifierPredicate.java
similarity index 97%
rename from screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/PlateIdentifierPredicate.java
rename to screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/PlateIdentifierPredicate.java
index 51c86ff8a62..c6354b780fd 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/PlateIdentifierPredicate.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/PlateIdentifierPredicate.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization;
+package ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.internal;
 
 import java.util.List;
 
@@ -31,6 +31,8 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifi
 
 /**
  * A predicate for {@link PlateIdentifier}.
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
  * 
  * @author Piotr Buczek
  */
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/PlateWellReferenceWithDatasetsValidator.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/PlateWellReferenceWithDatasetsValidator.java
similarity index 95%
rename from screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/PlateWellReferenceWithDatasetsValidator.java
rename to screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/PlateWellReferenceWithDatasetsValidator.java
index b60c5980375..c2e02b88762 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/PlateWellReferenceWithDatasetsValidator.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/PlateWellReferenceWithDatasetsValidator.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization;
+package ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.internal;
 
 import java.util.Set;
 
@@ -26,6 +26,8 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateWellRefe
 
 /**
  * A validator for a list of {@link PlateWellReferenceWithDatasets} objects.
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
  * 
  * @author Bernd Rinn
  */
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/ScreeningExperimentValidator.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/ScreeningExperimentValidator.java
similarity index 93%
rename from screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/ScreeningExperimentValidator.java
rename to screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/ScreeningExperimentValidator.java
index f7e2a6a6bdd..30ef9dd8dfe 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/ScreeningExperimentValidator.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/ScreeningExperimentValidator.java
@@ -1,4 +1,4 @@
-package ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization;
+package ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.internal;
 
 import java.util.Set;
 
@@ -11,6 +11,8 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ExperimentIde
 /**
  * Filters the experiments for spaces to which the user has permissions. This code works only in the
  * case of one database instance.
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
  * 
  * @author Bernd Rinn
  */
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/ScreeningPlateListReadOnlyPredicate.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/ScreeningPlateListReadOnlyPredicate.java
similarity index 97%
rename from screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/ScreeningPlateListReadOnlyPredicate.java
rename to screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/ScreeningPlateListReadOnlyPredicate.java
index dc0fc3689bb..43f25cecc1f 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/ScreeningPlateListReadOnlyPredicate.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/ScreeningPlateListReadOnlyPredicate.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization;
+package ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.internal;
 
 import java.util.List;
 
@@ -32,6 +32,8 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifi
  * A predicate for lists of entities which have {@link PlateIdentifier} as their super-class. This
  * predicate authorizes for read-only access, i.e. it will allow access to shared samples for all
  * users.
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
  * 
  * @author Bernd Rinn
  */
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/ScreeningPlateValidator.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/ScreeningPlateValidator.java
similarity index 94%
rename from screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/ScreeningPlateValidator.java
rename to screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/ScreeningPlateValidator.java
index f02d401405c..20203908cee 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/ScreeningPlateValidator.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/ScreeningPlateValidator.java
@@ -1,4 +1,4 @@
-package ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization;
+package ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.internal;
 
 import java.util.Set;
 
@@ -11,6 +11,8 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.Plate;
 /**
  * Filters only samples from the spaces to which the user has rights. This code works only in the
  * case of one database instance.
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
  * 
  * @author Tomasz Pylak
  */
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/WellIdentifierPredicate.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/WellIdentifierPredicate.java
similarity index 93%
rename from screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/WellIdentifierPredicate.java
rename to screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/WellIdentifierPredicate.java
index 2394b5f5367..c4f50970607 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/WellIdentifierPredicate.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/authorization/internal/WellIdentifierPredicate.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization;
+package ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.internal;
 
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.DelegatedPredicate;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SamplePermIdPredicate;
@@ -23,6 +23,8 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.WellIdentifie
 
 /**
  * A predicate for {@link WellIdentifier}.
+ * <p>
+ * <i>This is an internal class. Do not use it as a user of the API.</i>
  * 
  * @author Piotr Buczek
  */
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/IScreeningApiServer.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/IScreeningApiServer.java
index f0ea5622ab9..fb6809309b3 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/IScreeningApiServer.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/IScreeningApiServer.java
@@ -28,13 +28,13 @@ import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.ReturnVa
 import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.DataSetCodeCollectionPredicate;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.ExperimentIdentifierPredicate;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.PlateIdentifierPredicate;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.PlateWellReferenceWithDatasetsValidator;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.ScreeningExperimentValidator;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.ScreeningPlateListReadOnlyPredicate;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.ScreeningPlateValidator;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.WellIdentifierPredicate;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.internal.ExperimentIdentifierPredicate;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.internal.PlateIdentifierPredicate;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.internal.PlateWellReferenceWithDatasetsValidator;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.internal.ScreeningExperimentValidator;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.internal.ScreeningPlateListReadOnlyPredicate;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.internal.ScreeningPlateValidator;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.authorization.internal.WellIdentifierPredicate;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ExperimentIdentifier;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetReference;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IDatasetIdentifier;
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java
index d69c21fbed2..b03bdd187bf 100644
--- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java
@@ -42,12 +42,15 @@ import ch.systemsx.cisd.base.image.IImageTransformer;
 import ch.systemsx.cisd.base.image.IImageTransformerFactory;
 import ch.systemsx.cisd.base.mdarray.MDFloatArray;
 import ch.systemsx.cisd.bds.hcs.Location;
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.io.ByteArrayBasedContent;
 import ch.systemsx.cisd.common.io.ConcatenatedFileOutputStreamWriter;
 import ch.systemsx.cisd.common.io.FileBasedContent;
 import ch.systemsx.cisd.common.io.IContent;
 import ch.systemsx.cisd.openbis.dss.etl.AbsoluteImageReference;
 import ch.systemsx.cisd.openbis.dss.etl.IImagingDatasetLoader;
+import ch.systemsx.cisd.openbis.dss.generic.server.DatasetSessionAuthorizer;
 import ch.systemsx.cisd.openbis.dss.generic.server.DssServiceRpcAuthorizationAdvisor;
 import ch.systemsx.cisd.openbis.dss.generic.server.DssServiceRpcAuthorizationAdvisor.DssServiceRpcAuthorizationMethodInterceptor;
 import ch.systemsx.cisd.openbis.dss.generic.server.images.ImageChannelsUtilsTest;
@@ -55,6 +58,7 @@ import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.ImageChannelStackR
 import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.RequestedImageSize;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.authorization.internal.DssSessionAuthorizationHolder;
 import ch.systemsx.cisd.openbis.dss.generic.shared.dto.Size;
 import ch.systemsx.cisd.openbis.dss.generic.shared.utils.ImageUtil;
 import ch.systemsx.cisd.openbis.dss.screening.shared.api.v1.IDssServiceRpcScreening;
@@ -125,8 +129,6 @@ public class DssServiceRpcScreeningTest extends AssertJUnit
 
     private IImagingReadonlyQueryDAO dao;
 
-    private StaticListableBeanFactory applicationContext;
-
     private IFeatureVectorDatasetIdentifier featureVectorDatasetIdentifier1;
 
     private IFeatureVectorDatasetIdentifier featureVectorDatasetIdentifier2;
@@ -144,7 +146,8 @@ public class DssServiceRpcScreeningTest extends AssertJUnit
     @BeforeMethod
     public void beforeMethod()
     {
-        applicationContext = new StaticListableBeanFactory();
+        DssSessionAuthorizationHolder.setAuthorizer(new DatasetSessionAuthorizer());
+        final StaticListableBeanFactory applicationContext = new StaticListableBeanFactory();
         ServiceProvider.setBeanFactory(applicationContext);
         context = new Mockery();
         service = context.mock(IEncapsulatedOpenBISService.class);
@@ -215,7 +218,7 @@ public class DssServiceRpcScreeningTest extends AssertJUnit
         final List<WellPosition> wellPositions = Arrays.asList(new WellPosition(1, 3));
         final String channel = "dapi";
         prepareGetHomeDatabaseInstance();
-        prepareAssetDataSetsAreAccessible(ds.getPermId());
+        prepareAssetDataSetIsAccessible(ds.getPermId());
         prepareListDataSetsByCode();
 
         List<PlateImageReference> plateImageReferences =
@@ -299,7 +302,7 @@ public class DssServiceRpcScreeningTest extends AssertJUnit
     {
         final String channel = CHANNEL_CODE;
         prepareGetHomeDatabaseInstance();
-        prepareAssetDataSetsAreAccessible(DATASET_CODE);
+        prepareAssetDataSetIsAccessible(DATASET_CODE);
         prepareListDataSetsByCode();
         context.checking(new Expectations()
             {
@@ -405,13 +408,40 @@ public class DssServiceRpcScreeningTest extends AssertJUnit
         context.assertIsSatisfied();
     }
 
+    @Test
+    public void testSaveImageTransformerFactoryForDatasetChannelFailedDueToInvalidAuthorization()
+    {
+        final DatasetIdentifier ds1 = new DatasetIdentifier(DATASET_CODE, "url1");
+        final DatasetIdentifier ds2 = new DatasetIdentifier("ds2", "url1");
+        final String channel = "dapi";
+        context.checking(new Expectations()
+            {
+                {
+                    one(service).checkInstanceAdminAuthorization(SESSION_TOKEN);
+                    will(throwException(new UserFailureException("You are not an admin.")));
+                }
+            });
+
+        try
+        {
+            screeningService.saveImageTransformerFactory(SESSION_TOKEN,
+                    Arrays.<IDatasetIdentifier> asList(ds1, ds2), channel, transformerFactory);
+            fail("Unauthorized access not detected.");
+        } catch (AuthorizationFailureException ex)
+        {
+            assertEquals("Authorization failure: You are not an admin.", ex.getMessage());
+        }
+
+        assertTrue(testMethodInterceptor.methodInvoked);
+        context.assertIsSatisfied();
+    }
+
     @Test
     public void testSaveImageTransformerFactoryForDatasetChannel()
     {
         final DatasetIdentifier ds1 = new DatasetIdentifier(DATASET_CODE, "url1");
         final DatasetIdentifier ds2 = new DatasetIdentifier("ds2", "url1");
         final String channel = "dapi";
-        prepareAssetDataSetsAreAccessible();
         context.checking(new Expectations()
             {
                 {
@@ -455,7 +485,6 @@ public class DssServiceRpcScreeningTest extends AssertJUnit
     public void testSaveImageTransformerFactoryForExperiment()
     {
         final DatasetIdentifier ds1 = new DatasetIdentifier(DATASET_CODE, "url1");
-        prepareAssetDataSetsAreAccessible(DATASET_CODE);
         context.checking(new Expectations()
             {
                 {
@@ -608,18 +637,28 @@ public class DssServiceRpcScreeningTest extends AssertJUnit
             });
     }
 
+    private void prepareAssetDataSetIsAccessible(final String dsCode)
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    one(service).checkDataSetAccess(SESSION_TOKEN, dsCode);
+                }
+            });
+    }
+
     private void prepareAssetDataSetsAreAccessible()
     {
         prepareAssetDataSetsAreAccessible("ds1", "ds2");
     }
-    
+
     private void prepareAssetDataSetsAreAccessible(final String... dsCodes)
     {
         context.checking(new Expectations()
             {
                 {
-                    one(service).checkDataSetCollectionAccess(SESSION_TOKEN,
-                            Arrays.asList(dsCodes));
+                    one(service)
+                            .checkDataSetCollectionAccess(SESSION_TOKEN, Arrays.asList(dsCodes));
                 }
             });
     }
@@ -655,8 +694,8 @@ public class DssServiceRpcScreeningTest extends AssertJUnit
         @Override
         public Object invoke(MethodInvocation methodInvocation) throws Throwable
         {
-            Object result = super.invoke(methodInvocation);
             methodInvoked = true;
+            Object result = super.invoke(methodInvocation);
             return result;
         }
     }
-- 
GitLab