Implemented OAuth2 client authentication.

Change-Id: Ia8b10116e72c3702f369d1cc04561bab5e269f95
diff --git a/core/src/main/java/de/ids_mannheim/korap/config/BeanConfiguration.java b/core/src/main/java/de/ids_mannheim/korap/config/BeanConfiguration.java
deleted file mode 100644
index 5e8aa36..0000000
--- a/core/src/main/java/de/ids_mannheim/korap/config/BeanConfiguration.java
+++ /dev/null
@@ -1,199 +0,0 @@
-package de.ids_mannheim.korap.config;
-
-import java.io.IOException;
-
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-import org.springframework.context.support.FileSystemXmlApplicationContext;
-
-import de.ids_mannheim.korap.interfaces.EncryptionIface;
-import de.ids_mannheim.korap.interfaces.ValidatorIface;
-import de.ids_mannheim.korap.interfaces.db.AuditingIface;
-import de.ids_mannheim.korap.interfaces.db.PersistenceClient;
-import de.ids_mannheim.korap.interfaces.db.ResourceOperationIface;
-import de.ids_mannheim.korap.interfaces.db.UserDataDbIface;
-import de.ids_mannheim.korap.interfaces.defaults.ApacheValidator;
-import de.ids_mannheim.korap.web.CoreResponseHandler;
-
-/**
- * User: hanl
- * Date: 10/9/13
- * Time: 11:20 AM
- */
-@Deprecated
-public class BeanConfiguration {
-
-    private static final String CONFIG_FILE = "light-config.xml";
-    public static final String KUSTVAKT_DB = "kustvakt_db";
-
-    public static final String KUSTVAKT_ENCRYPTION = "kustvakt_encryption";
-    public static final String KUSTVAKT_AUDITING = "kustvakt_auditing";
-    public static final String KUSTVAKT_CONFIG = "kustvakt_config";
-    public static final String KUSTVAKT_USERSETTINGS = "kustvakt_usersettings";
-    public static final String KUSTVAKT_USERDETAILS = "kustvakt_userdetails";
-
-    public static final String KUSTVAKT_AUTHENTICATION_MANAGER = "kustvakt_authenticationmanager";
-    public static final String KUSTVAKT_USERDB = "kustvakt_userdb";
-
-    private static BeanHolderHelper beans;
-
-
-    //todo: allow this for external plugin systems that are not kustvakt specific
-    @Deprecated
-    public static void setCustomBeansHolder (BeanHolderHelper holder) {
-        ApplicationContext context = beans.context;
-        holder.context = context;
-        BeanConfiguration.beans = holder;
-    }
-
-
-    public static BeanHolderHelper getBeans () {
-        return BeanConfiguration.beans;
-    }
-
-
-
-    public static boolean hasContext () {
-        return beans != null && beans.context != null;
-    }
-
-
-    public static void loadClasspathContext (String ... files) {
-        if (hasContext())
-            closeApplication();
-
-        ApplicationContext context;
-        if (files.length == 0)
-            context = new ClassPathXmlApplicationContext(CONFIG_FILE);
-        else
-            context = new ClassPathXmlApplicationContext(files);
-
-        BeanConfiguration.beans = new BeanHolderHelper(context);
-
-    }
-
-
-    public static void loadFileContext (String filepath) {
-        if (!hasContext()) {
-            ApplicationContext context = new FileSystemXmlApplicationContext(
-                    "file:" + filepath);
-            BeanConfiguration.beans = new BeanHolderHelper(context);
-        }
-    }
-
-
-    public static void closeApplication () {
-        if (hasContext())
-            beans.finish();
-        beans = null;
-    }
-
-
-    //todo: set response handler
-    @Deprecated
-    public static CoreResponseHandler getResponseHandler () {
-        return null;
-    }
-
-    public static class BeanHolderHelper {
-
-        private ApplicationContext context = null;
-        private DefaultHandler handler;
-
-
-        private BeanHolderHelper (ApplicationContext context) {
-            this.handler = new DefaultHandler();
-            this.context = context;
-            // todo: better method?!
-            new CoreResponseHandler(getAuditingProvider());
-        }
-
-
-        protected <T> T getBean (Class<T> clazz) {
-            if (context != null) {
-                try {
-                    return context.getBean(clazz);
-                }
-                catch (NoSuchBeanDefinitionException e) {
-                    // do nothing
-                }
-            }
-            return this.handler.getDefault(clazz);
-        }
-
-
-        protected <T> T getBean (String name) {
-            if (context != null) {
-                try {
-                    return (T) context.getBean(name);
-                }
-                catch (NoSuchBeanDefinitionException e) {
-                    // do nothing
-                }
-            }
-            return (T) this.handler.getDefault(name);
-        }
-
-
-        public AuditingIface getAuditingProvider () {
-            return (AuditingIface) getBean(KUSTVAKT_AUDITING);
-        }
-
-
-        public <T extends KustvaktConfiguration> T getConfiguration () {
-            return (T) getBean(KUSTVAKT_CONFIG);
-        }
-
-
-        public PersistenceClient getPersistenceClient () {
-            return getBean(KUSTVAKT_DB);
-        }
-
-
-        public UserDataDbIface getUserDetailsDao () {
-            return getBean(KUSTVAKT_USERDETAILS);
-        }
-
-
-        public UserDataDbIface getUserSettingsDao () {
-            return getBean(KUSTVAKT_USERSETTINGS);
-        }
-
-
-        public EncryptionIface getEncryption () {
-            return getBean(KUSTVAKT_ENCRYPTION);
-        }
-
-
-//        public AuthenticationManagerIface getAuthenticationManager () {
-//            return getBean(KUSTVAKT_AUTHENTICATION_MANAGER);
-//        }
-
-
-//        public EntityHandlerIface getUserDBHandler () {
-//            return getBean(KUSTVAKT_USERDB);
-//        }
-
-        public ValidatorIface getValidator()  {
-            try {
-                return new ApacheValidator();
-            } catch (IOException e) {
-                throw new RuntimeException("validator could not be loaded!");
-            }
-        }
-
-        // todo: !!!!!!!!!!!!!!!!!!!!!!!!!!
-        // todo: more specific --> collection provider, document provider, etc.
-        public ResourceOperationIface getResourceProvider () {
-            return getBean("resourceProvider");
-        }
-
-
-        private void finish () {
-            this.getAuditingProvider().finish();
-            context = null;
-        }
-
-    }
-}
diff --git a/core/src/main/java/de/ids_mannheim/korap/config/BeansFactory.java b/core/src/main/java/de/ids_mannheim/korap/config/BeansFactory.java
index d9e2a73..46d319e 100644
--- a/core/src/main/java/de/ids_mannheim/korap/config/BeansFactory.java
+++ b/core/src/main/java/de/ids_mannheim/korap/config/BeansFactory.java
@@ -8,6 +8,7 @@
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 import org.springframework.context.support.FileSystemXmlApplicationContext;
 
+import de.ids_mannheim.korap.interfaces.KustvaktTypeInterface;
 import de.ids_mannheim.korap.web.CoreResponseHandler;
 
 /**
diff --git a/core/src/main/java/de/ids_mannheim/korap/config/ClientInfo.java b/core/src/main/java/de/ids_mannheim/korap/config/ClientInfo.java
index bf98fe9..66cc6a0 100644
--- a/core/src/main/java/de/ids_mannheim/korap/config/ClientInfo.java
+++ b/core/src/main/java/de/ids_mannheim/korap/config/ClientInfo.java
@@ -10,6 +10,7 @@
  * @author hanl
  * @date 22/01/2014
  */
+@Deprecated
 @Data
 public class ClientInfo {
 
diff --git a/core/src/main/java/de/ids_mannheim/korap/config/ExceptionBuilder.java b/core/src/main/java/de/ids_mannheim/korap/config/ExceptionBuilder.java
deleted file mode 100644
index 84b2046..0000000
--- a/core/src/main/java/de/ids_mannheim/korap/config/ExceptionBuilder.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package de.ids_mannheim.korap.config;
-
-/**
- * @author hanl
- * @date 10/02/2016
- */
-// todo:
-// run simple queries to determine the exception cause (e.g. policy could not be created because resource doesnt exist, etc.)
-public class ExceptionBuilder {
-    // use sqlbuilder to build the respective query (one instance per dao interface)
-
-}
diff --git a/core/src/main/java/de/ids_mannheim/korap/config/KustvaktContext.java b/core/src/main/java/de/ids_mannheim/korap/config/KustvaktContext.java
deleted file mode 100644
index ed3b5dc..0000000
--- a/core/src/main/java/de/ids_mannheim/korap/config/KustvaktContext.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package de.ids_mannheim.korap.config;
-
-/**
- * @author hanl
- * @date 14/03/2016
- */
-public class KustvaktContext {
-
-
-    private KustvaktContext context;
-
-
-
-}
diff --git a/core/src/main/java/de/ids_mannheim/korap/exceptions/KustvaktException.java b/core/src/main/java/de/ids_mannheim/korap/exceptions/KustvaktException.java
index ac73909..52dc54a 100644
--- a/core/src/main/java/de/ids_mannheim/korap/exceptions/KustvaktException.java
+++ b/core/src/main/java/de/ids_mannheim/korap/exceptions/KustvaktException.java
@@ -5,7 +5,7 @@
 import java.util.List;
 
 import de.ids_mannheim.korap.auditing.AuditRecord;
-import de.ids_mannheim.korap.config.TokenType;
+//import de.ids_mannheim.korap.constant.TokenType;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -23,7 +23,7 @@
     private String entity;
     private String notification;
     private boolean isNotification;
-    private TokenType authType;
+//    private TokenType authType;
 
     public KustvaktException (int status) {
         this.statusCode = status;
@@ -74,13 +74,6 @@
         this.userid = String.valueOf(userid);
     }
 
-    public KustvaktException (TokenType type, int status, String message, String entity) {
-        super(message);
-        this.statusCode = status;
-        this.entity = entity;
-        this.authType = type;
-    }
-    
     public KustvaktException (int status, String message, String entity) {
         super(message);
         this.statusCode = status;
diff --git a/core/src/main/java/de/ids_mannheim/korap/exceptions/StatusCodes.java b/core/src/main/java/de/ids_mannheim/korap/exceptions/StatusCodes.java
index 1c78ef0..7d4cf09 100644
--- a/core/src/main/java/de/ids_mannheim/korap/exceptions/StatusCodes.java
+++ b/core/src/main/java/de/ids_mannheim/korap/exceptions/StatusCodes.java
@@ -15,7 +15,7 @@
      */
     public static final int DEFAULT_ERROR = 100;
     public static final int NO_RESULT_FOUND = 101;
-
+    public static final int UNSUPPORTED_AUTHENTICATION_SCHEME = 102;
     public static final int UNSUPPORTED_OPERATION = 103;
     public static final int ILLEGAL_ARGUMENT = 104;
     public static final int MISSING_ARGUMENT = 105;
@@ -23,28 +23,28 @@
     public static final int INVALID_ARGUMENT = 107;
     public static final int NOT_SUPPORTED = 108;
     public static final int NOT_ALLOWED = 109;
-    
+
     /**
      * 300 status codes for query language and serialization
      */
 
     public static final int NO_QUERY = 301;
-//    public static final int INVALID_TYPE = 302;
+    //    public static final int INVALID_TYPE = 302;
     public static final int MISSING_ATTRIBUTE = 303;
     public static final int INVALID_ATTRIBUTE = 304;
     public static final int UNSUPPORTED_VALUE = 305;
     public static final int SERIALIZATION_FAILED = 306;
     public static final int DESERIALIZATION_FAILED = 307;
-    
+
     /**
      *  400 status codes for authorization and rewrite functions
      */
 
     // fixme: use unsupported resource and include type in return message
     public static final int POLICY_ERROR_DEFAULT = 400;
-    
+
     public static final int UNSUPPORTED_RESOURCE = 402;
-//    public static final int REWRITE_FAILED = 403;
+    //    public static final int REWRITE_FAILED = 403;
     //public static final int UNSUPPORTED_FOUNDRY = 403;
     //public static final int UNSUPPORTED_CORPUS = 404;
     //public static final int UNSUPPORTED_LAYER = 405;
@@ -53,14 +53,14 @@
     //public static final int CORPUS_REWRITE = 407;
     //public static final int FOUNDRY_REWRITE = 408;
     //public static final int FOUNDRY_INJECTION = 409;
-//    public static final int MISSING_RESOURCE = 405;
+    //    public static final int MISSING_RESOURCE = 405;
     public static final int NO_POLICY_TARGET = 406;
     public static final int NO_POLICY_CONDITION = 407;
     public static final int NO_POLICY_PERMISSION = 408;
     public static final int NO_POLICIES = 409;
 
-    
-    
+
+
     /**
      * 500 status codes for access control related components (also
      * policy rewrite)
@@ -80,8 +80,8 @@
     public static final int DB_DELETE_SUCCESSFUL = 506;
     public static final int DB_UPDATE_SUCCESSFUL = 507;
     public static final int DB_ENTRY_EXISTS = 508;
-    
-    
+
+
     // User group and member 
     public static final int GROUP_MEMBER_EXISTS = 601;
     public static final int GROUP_MEMBER_INACTIVE = 602;
@@ -90,9 +90,9 @@
     public static final int INVITATION_EXPIRED = 605;
     public static final int GROUP_NOT_FOUND = 606;
     public static final int GROUP_DELETED = 607;
-    
 
-//    public static final int ARGUMENT_VALIDATION_FAILURE = 700;
+
+    //    public static final int ARGUMENT_VALIDATION_FAILURE = 700;
     // public static final int ARGUMENT_VALIDATION_FAILURE = 701;
 
     // service status codes
@@ -105,8 +105,8 @@
 
     public static final int GET_ACCOUNT_SUCCESSFUL = 706;
     public static final int GET_ACCOUNT_FAILED = 707;
-    
-    
+
+
     public static final int STATUS_OK = 1000;
     public static final int NOTHING_CHANGED = 1001;
     public static final int REQUEST_INVALID = 1002;
@@ -118,20 +118,25 @@
 
     public static final int CLIENT_REGISTRATION_FAILED = 1800;
     public static final int CLIENT_REMOVAL_FAILURE = 1801;
+    public static final int CLIENT_AUTHENTICATION_FAILED = 1802;
+    public static final int CLIENT_NOT_FOUND = 1803;
     
+    public static final int UNSUPPORTED_GRANT_TYPE = 1810;
+    
+
     /**
      * 1900 User account and logins
      */
 
     public static final int LOGIN_SUCCESSFUL = 1900;
     public static final int ALREADY_LOGGED_IN = 1901;
-    
+
     public static final int LOGOUT_SUCCESSFUL = 1902;
     public static final int LOGOUT_FAILED = 1903;
-    
+
     public static final int ACCOUNT_CONFIRMATION_FAILED = 1904;
     public static final int PASSWORD_RESET_FAILED = 1905;
-    
+
     /**
      * 2000 status and error codes concerning authentication
      * 
@@ -148,29 +153,28 @@
     public static final int ACCOUNT_NOT_CONFIRMED = 2004;
     public static final int ACCOUNT_DEACTIVATED = 2005;
 
-//    public static final int CLIENT_AUTHORIZATION_FAILED = 2013;
+    //    public static final int CLIENT_AUTHORIZATION_FAILED = 2013;
     public static final int AUTHORIZATION_FAILED = 2010;
-    
+
     // 2020 - 2029 reserviert für LDAP-Fehlercodes - 21.04.17/FB
     public static final int LDAP_BASE_ERRCODE = 2020;
-    
+
     /**/
     private static StatusCodes codes;
 
     private final Properties props;
 
-    private StatusCodes() {
+    private StatusCodes () {
         this.props = ConfigLoader.loadProperties("codes.info");
     }
 
 
-    public static final String getMessage(int code) {
+    public static final String getMessage (int code) {
         return getCodes().props.getProperty(String.valueOf(code));
     }
 
-    public static StatusCodes getCodes() {
-            if (codes == null)
-                codes = new StatusCodes();
+    public static StatusCodes getCodes () {
+        if (codes == null) codes = new StatusCodes();
         return codes;
     }
 
diff --git a/core/src/main/java/de/ids_mannheim/korap/config/KustvaktBaseDaoInterface.java b/core/src/main/java/de/ids_mannheim/korap/interfaces/KustvaktBaseDaoInterface.java
similarity index 75%
rename from core/src/main/java/de/ids_mannheim/korap/config/KustvaktBaseDaoInterface.java
rename to core/src/main/java/de/ids_mannheim/korap/interfaces/KustvaktBaseDaoInterface.java
index 2543d73..42a2a74 100644
--- a/core/src/main/java/de/ids_mannheim/korap/config/KustvaktBaseDaoInterface.java
+++ b/core/src/main/java/de/ids_mannheim/korap/interfaces/KustvaktBaseDaoInterface.java
@@ -1,4 +1,4 @@
-package de.ids_mannheim.korap.config;
+package de.ids_mannheim.korap.interfaces;
 
 /**
  * @author hanl
diff --git a/core/src/main/java/de/ids_mannheim/korap/config/KustvaktTypeInterface.java b/core/src/main/java/de/ids_mannheim/korap/interfaces/KustvaktTypeInterface.java
similarity index 73%
rename from core/src/main/java/de/ids_mannheim/korap/config/KustvaktTypeInterface.java
rename to core/src/main/java/de/ids_mannheim/korap/interfaces/KustvaktTypeInterface.java
index 5980aa2..2f66b95 100644
--- a/core/src/main/java/de/ids_mannheim/korap/config/KustvaktTypeInterface.java
+++ b/core/src/main/java/de/ids_mannheim/korap/interfaces/KustvaktTypeInterface.java
@@ -1,4 +1,4 @@
-package de.ids_mannheim.korap.config;
+package de.ids_mannheim.korap.interfaces;
 
 /**
  * @author hanl
diff --git a/core/src/main/java/de/ids_mannheim/korap/interfaces/db/ResourceOperationIface.java b/core/src/main/java/de/ids_mannheim/korap/interfaces/db/ResourceOperationIface.java
index 565ceec..c27f3b6 100644
--- a/core/src/main/java/de/ids_mannheim/korap/interfaces/db/ResourceOperationIface.java
+++ b/core/src/main/java/de/ids_mannheim/korap/interfaces/db/ResourceOperationIface.java
@@ -1,8 +1,8 @@
 package de.ids_mannheim.korap.interfaces.db;
 
-import de.ids_mannheim.korap.config.KustvaktBaseDaoInterface;
-import de.ids_mannheim.korap.config.KustvaktTypeInterface;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.interfaces.KustvaktBaseDaoInterface;
+import de.ids_mannheim.korap.interfaces.KustvaktTypeInterface;
 import de.ids_mannheim.korap.resources.KustvaktResource;
 import de.ids_mannheim.korap.user.User;
 
diff --git a/core/src/main/java/de/ids_mannheim/korap/interfaces/db/UserDataDbIface.java b/core/src/main/java/de/ids_mannheim/korap/interfaces/db/UserDataDbIface.java
index a475dae..23dfbc4 100644
--- a/core/src/main/java/de/ids_mannheim/korap/interfaces/db/UserDataDbIface.java
+++ b/core/src/main/java/de/ids_mannheim/korap/interfaces/db/UserDataDbIface.java
@@ -1,7 +1,7 @@
 package de.ids_mannheim.korap.interfaces.db;
 
-import de.ids_mannheim.korap.config.KustvaktTypeInterface;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.interfaces.KustvaktTypeInterface;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.user.Userdata;
 
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/APIAuthentication.java b/full/src/main/java/de/ids_mannheim/korap/authentication/APIAuthentication.java
index 7b7da01..b90889b 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/APIAuthentication.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/APIAuthentication.java
@@ -8,11 +8,11 @@
 
 import de.ids_mannheim.korap.config.JWTSigner;
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
-import de.ids_mannheim.korap.config.TokenType;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.interfaces.AuthenticationIface;
-import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import net.sf.ehcache.Cache;
 import net.sf.ehcache.CacheManager;
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/BasicAuthentication.java b/full/src/main/java/de/ids_mannheim/korap/authentication/BasicAuthentication.java
index c353884..2a3b676 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/BasicAuthentication.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/BasicAuthentication.java
@@ -9,12 +9,12 @@
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.FullConfiguration;
 import de.ids_mannheim.korap.config.Scopes;
-import de.ids_mannheim.korap.config.TokenType;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.dao.UserDao;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.interfaces.AuthenticationIface;
-import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.StringUtils;
 import de.ids_mannheim.korap.utils.TimeUtils;
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java b/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
index 73728a4..acef1d5 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
@@ -22,11 +22,11 @@
 
 import de.ids_mannheim.korap.auditing.AuditRecord;
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.AuthenticationMethod;
 import de.ids_mannheim.korap.config.BeansFactory;
 import de.ids_mannheim.korap.config.FullConfiguration;
-import de.ids_mannheim.korap.config.TokenType;
 import de.ids_mannheim.korap.config.URIParam;
+import de.ids_mannheim.korap.constant.AuthenticationMethod;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.dao.AdminDao;
 import de.ids_mannheim.korap.exceptions.EmptyResultException;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
@@ -41,10 +41,10 @@
 import de.ids_mannheim.korap.interfaces.db.AuditingIface;
 import de.ids_mannheim.korap.interfaces.db.UserDataDbIface;
 import de.ids_mannheim.korap.interfaces.defaults.ApacheValidator;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.DemoUser;
 import de.ids_mannheim.korap.user.KorAPUser;
 import de.ids_mannheim.korap.user.ShibUser;
-import de.ids_mannheim.korap.user.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.user.User.CorpusAccess;
 import de.ids_mannheim.korap.user.User.Location;
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/LdapAuth3.java b/full/src/main/java/de/ids_mannheim/korap/authentication/LdapAuth3.java
index 44ed646..0cdd3d3 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/LdapAuth3.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/LdapAuth3.java
@@ -28,8 +28,8 @@
 
 import com.unboundid.ldap.sdk.*;
 
-import de.ids_mannheim.korap.config.TokenType;
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.constant.TokenType;
 
 import java.io.*;
 import java.util.*;
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/OpenIDconnectAuthentication.java b/full/src/main/java/de/ids_mannheim/korap/authentication/OpenIDconnectAuthentication.java
index 368c390..1cc6150 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/OpenIDconnectAuthentication.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/OpenIDconnectAuthentication.java
@@ -3,14 +3,14 @@
 import com.nimbusds.jwt.SignedJWT;
 import de.ids_mannheim.korap.config.JWTSigner;
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.handlers.OAuthDb;
 import de.ids_mannheim.korap.interfaces.AuthenticationIface;
 import de.ids_mannheim.korap.interfaces.db.PersistenceClient;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.TokenType;
-import de.ids_mannheim.korap.user.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.NamingUtils;
 import de.ids_mannheim.korap.utils.StringUtils;
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/SessionAuthentication.java b/full/src/main/java/de/ids_mannheim/korap/authentication/SessionAuthentication.java
index b32879e..23e83c3 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/SessionAuthentication.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/SessionAuthentication.java
@@ -1,13 +1,13 @@
 package de.ids_mannheim.korap.authentication;
 
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.interfaces.AuthenticationIface;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.TokenType;
-import de.ids_mannheim.korap.user.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.TimeUtils;
 import org.joda.time.DateTime;
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/SessionFactory.java b/full/src/main/java/de/ids_mannheim/korap/authentication/SessionFactory.java
index 1817799..7292ad0 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/SessionFactory.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/SessionFactory.java
@@ -2,8 +2,8 @@
 
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.DemoUser;
-import de.ids_mannheim.korap.user.TokenContext;
 import de.ids_mannheim.korap.utils.ConcurrentMultiMap;
 import de.ids_mannheim.korap.utils.TimeUtils;
 import org.joda.time.DateTime;
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/http/AuthorizationData.java b/full/src/main/java/de/ids_mannheim/korap/authentication/http/AuthorizationData.java
index a1ad185..236f26a 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/http/AuthorizationData.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/http/AuthorizationData.java
@@ -1,6 +1,6 @@
 package de.ids_mannheim.korap.authentication.http;
 
-import de.ids_mannheim.korap.config.AuthenticationScheme;
+import de.ids_mannheim.korap.constant.AuthenticationScheme;
 import lombok.Getter;
 import lombok.Setter;
 
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/http/HttpAuthorizationHandler.java b/full/src/main/java/de/ids_mannheim/korap/authentication/http/HttpAuthorizationHandler.java
index bea9bc1..7796345 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/http/HttpAuthorizationHandler.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/http/HttpAuthorizationHandler.java
@@ -3,7 +3,7 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import de.ids_mannheim.korap.config.AuthenticationScheme;
+import de.ids_mannheim.korap.constant.AuthenticationScheme;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.utils.ParameterChecker;
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/http/HttpUnauthorizedHandler.java b/full/src/main/java/de/ids_mannheim/korap/authentication/http/HttpUnauthorizedHandler.java
index 8e296bc..845d9ae 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/http/HttpUnauthorizedHandler.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/http/HttpUnauthorizedHandler.java
@@ -8,7 +8,7 @@
 
 import org.springframework.stereotype.Component;
 
-import de.ids_mannheim.korap.config.AuthenticationScheme;
+import de.ids_mannheim.korap.constant.AuthenticationScheme;
 
 /** Implementation of HTTP authentication scheme (see RFC 7253 and 7617)
  *  for server creating responses with status 401 Unauthorized and 
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/spring/BasicAuthenticationManager.java b/full/src/main/java/de/ids_mannheim/korap/authentication/spring/BasicAuthenticationManager.java
index 49ec065..808cbf4 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/spring/BasicAuthenticationManager.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/spring/BasicAuthenticationManager.java
@@ -8,11 +8,11 @@
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
 import de.ids_mannheim.korap.config.Scopes;
-import de.ids_mannheim.korap.config.TokenType;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.dao.UserDao;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.KorAPUser;
-import de.ids_mannheim.korap.user.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.TimeUtils;
 
diff --git a/core/src/main/java/de/ids_mannheim/korap/config/AuthCodeInfo.java b/full/src/main/java/de/ids_mannheim/korap/config/AuthCodeInfo.java
similarity index 100%
rename from core/src/main/java/de/ids_mannheim/korap/config/AuthCodeInfo.java
rename to full/src/main/java/de/ids_mannheim/korap/config/AuthCodeInfo.java
diff --git a/core/src/main/java/de/ids_mannheim/korap/config/JWTSigner.java b/full/src/main/java/de/ids_mannheim/korap/config/JWTSigner.java
similarity index 98%
rename from core/src/main/java/de/ids_mannheim/korap/config/JWTSigner.java
rename to full/src/main/java/de/ids_mannheim/korap/config/JWTSigner.java
index 40cb90d..426a873 100644
--- a/core/src/main/java/de/ids_mannheim/korap/config/JWTSigner.java
+++ b/full/src/main/java/de/ids_mannheim/korap/config/JWTSigner.java
@@ -7,8 +7,8 @@
 import com.nimbusds.jwt.SignedJWT;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.GenericUserData;
-import de.ids_mannheim.korap.user.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.user.Userdata;
 import de.ids_mannheim.korap.utils.TimeUtils;
diff --git a/full/src/main/java/de/ids_mannheim/korap/config/AuthenticationMethod.java b/full/src/main/java/de/ids_mannheim/korap/constant/AuthenticationMethod.java
similarity index 87%
rename from full/src/main/java/de/ids_mannheim/korap/config/AuthenticationMethod.java
rename to full/src/main/java/de/ids_mannheim/korap/constant/AuthenticationMethod.java
index b44d0a0..1beec64 100644
--- a/full/src/main/java/de/ids_mannheim/korap/config/AuthenticationMethod.java
+++ b/full/src/main/java/de/ids_mannheim/korap/constant/AuthenticationMethod.java
@@ -1,4 +1,4 @@
-package de.ids_mannheim.korap.config;
+package de.ids_mannheim.korap.constant;
 
 /** Lists possible actual authentication methods. Multiple 
  *  {@link AuthenticationScheme} may use an identical 
diff --git a/full/src/main/java/de/ids_mannheim/korap/config/AuthenticationScheme.java b/full/src/main/java/de/ids_mannheim/korap/constant/AuthenticationScheme.java
similarity index 90%
rename from full/src/main/java/de/ids_mannheim/korap/config/AuthenticationScheme.java
rename to full/src/main/java/de/ids_mannheim/korap/constant/AuthenticationScheme.java
index 4459e56..42f296c 100644
--- a/full/src/main/java/de/ids_mannheim/korap/config/AuthenticationScheme.java
+++ b/full/src/main/java/de/ids_mannheim/korap/constant/AuthenticationScheme.java
@@ -1,4 +1,4 @@
-package de.ids_mannheim.korap.config;
+package de.ids_mannheim.korap.constant;
 
 import org.apache.commons.lang.WordUtils;
 
diff --git a/full/src/main/java/de/ids_mannheim/korap/constant/ClientType.java b/full/src/main/java/de/ids_mannheim/korap/constant/OAuth2ClientType.java
similarity index 95%
rename from full/src/main/java/de/ids_mannheim/korap/constant/ClientType.java
rename to full/src/main/java/de/ids_mannheim/korap/constant/OAuth2ClientType.java
index eb78b40..1584aef 100644
--- a/full/src/main/java/de/ids_mannheim/korap/constant/ClientType.java
+++ b/full/src/main/java/de/ids_mannheim/korap/constant/OAuth2ClientType.java
@@ -1,6 +1,6 @@
 package de.ids_mannheim.korap.constant;
 
-public enum ClientType {
+public enum OAuth2ClientType {
 
     // EM: from RFC 6749
         
diff --git a/core/src/main/java/de/ids_mannheim/korap/config/TokenType.java b/full/src/main/java/de/ids_mannheim/korap/constant/TokenType.java
similarity index 76%
rename from core/src/main/java/de/ids_mannheim/korap/config/TokenType.java
rename to full/src/main/java/de/ids_mannheim/korap/constant/TokenType.java
index db99dd9..dce97fa 100644
--- a/core/src/main/java/de/ids_mannheim/korap/config/TokenType.java
+++ b/full/src/main/java/de/ids_mannheim/korap/constant/TokenType.java
@@ -1,11 +1,13 @@
-package de.ids_mannheim.korap.config;
+package de.ids_mannheim.korap.constant;
 
 public enum TokenType {
     BASIC, API, SESSION, 
     // openid token, e.g. within oauth2 response (json body)
     ID_TOKEN,
     // OAuth2 access_token, practically formulated identical as TokenType.API
-    BEARER; 
+    BEARER,
+    // OAuth2 client
+    CLIENT; 
 
     public String displayName () {
         return name().toLowerCase();
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java
index 09d801a..94ad319 100644
--- a/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java
@@ -1,15 +1,22 @@
 package de.ids_mannheim.korap.dao;
 
 import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
 import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
 import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
 
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Transactional;
 
-import de.ids_mannheim.korap.constant.ClientType;
+import de.ids_mannheim.korap.constant.OAuth2ClientType;
 import de.ids_mannheim.korap.entity.OAuth2Client;
+import de.ids_mannheim.korap.entity.OAuth2Client_;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.utils.ParameterChecker;
 
 @Transactional
@@ -20,13 +27,14 @@
     private EntityManager entityManager;
 
     public void registerClient (String id, String secret, String name,
-            ClientType type, String url, String redirectURI)
-            throws KustvaktException {
+            OAuth2ClientType type, String url, String redirectURI,
+            String registeredBy) throws KustvaktException {
         ParameterChecker.checkStringValue(id, "client id");
         ParameterChecker.checkStringValue(name, "client name");
         ParameterChecker.checkObjectValue(type, "client type");
         ParameterChecker.checkStringValue(url, "client url");
         ParameterChecker.checkStringValue(redirectURI, "client redirect uri");
+        ParameterChecker.checkStringValue(registeredBy, "registeredBy");
 
         OAuth2Client client = new OAuth2Client();
         client.setId(id);
@@ -35,9 +43,31 @@
         client.setType(type);
         client.setUrl(url);
         client.setRedirectURI(redirectURI);
+        client.setRegisteredBy(registeredBy);
 
         entityManager.persist(client);
     }
 
+    public OAuth2Client retrieveClientById (String clientId)
+            throws KustvaktException {
+
+        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+        CriteriaQuery<OAuth2Client> query =
+                builder.createQuery(OAuth2Client.class);
+
+        Root<OAuth2Client> root = query.from(OAuth2Client.class);
+        query.select(root);
+        query.where(builder.equal(root.get(OAuth2Client_.id), clientId));
+
+        Query q = entityManager.createQuery(query);
+        try {
+            return (OAuth2Client) q.getSingleResult();
+        }
+        catch (NoResultException e) {
+            throw new KustvaktException(StatusCodes.CLIENT_NOT_FOUND,
+                    "Client with id " + clientId + "is not found");
+        }
+    }
+
 
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/dto/OAuth2ClientDto.java b/full/src/main/java/de/ids_mannheim/korap/dto/OAuth2ClientDto.java
new file mode 100644
index 0000000..1840fd3
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/dto/OAuth2ClientDto.java
@@ -0,0 +1,22 @@
+package de.ids_mannheim.korap.dto;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class OAuth2ClientDto {
+
+    private String client_id;
+    @JsonInclude(JsonInclude.Include.NON_EMPTY)
+    private String client_secret;
+
+    public OAuth2ClientDto () {}
+
+    public OAuth2ClientDto (String id, String secret) {
+        this.client_id = id;
+        this.client_secret = secret;
+    }
+}
\ No newline at end of file
diff --git a/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java b/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java
index c299a22..9d91d93 100644
--- a/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java
+++ b/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java
@@ -7,7 +7,7 @@
 import javax.persistence.Id;
 import javax.persistence.Table;
 
-import de.ids_mannheim.korap.constant.ClientType;
+import de.ids_mannheim.korap.constant.OAuth2ClientType;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -23,17 +23,20 @@
 
     @Id
     private String id;
+    private String name;
     private String secret;
     @Enumerated(EnumType.STRING)
-    private ClientType type;
+    private OAuth2ClientType type;
+    private String url;
     @Column(name = "redirect_uri")
     private String redirectURI;
-    private String url;
-    private String name;
+    private String registeredBy;
+
 
     @Override
     public String toString () {
         return "id=" + id + ", secret=" + secret + ", type=" + type + ", name="
-                + name + ", url=" + url + ", redirectURI=" + redirectURI;
+                + name + ", url=" + url + ", redirectURI=" + redirectURI
+                + ", registeredBy=" + registeredBy;
     }
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java b/full/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java
index 35c7cbc..fd3c1e8 100644
--- a/full/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java
@@ -1,6 +1,5 @@
 package de.ids_mannheim.korap.handlers;
 
-import de.ids_mannheim.korap.config.KustvaktBaseDaoInterface;
 import de.ids_mannheim.korap.config.ParamFields;
 import de.ids_mannheim.korap.config.URIParam;
 import de.ids_mannheim.korap.exceptions.EmptyResultException;
@@ -8,6 +7,7 @@
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.exceptions.DatabaseException;
 import de.ids_mannheim.korap.interfaces.EntityHandlerIface;
+import de.ids_mannheim.korap.interfaces.KustvaktBaseDaoInterface;
 import de.ids_mannheim.korap.interfaces.db.PersistenceClient;
 import de.ids_mannheim.korap.user.KorAPUser;
 import de.ids_mannheim.korap.user.ShibUser;
diff --git a/full/src/main/java/de/ids_mannheim/korap/handlers/OAuthDb.java b/full/src/main/java/de/ids_mannheim/korap/handlers/OAuthDb.java
index 72d15cb..828d61e 100644
--- a/full/src/main/java/de/ids_mannheim/korap/handlers/OAuthDb.java
+++ b/full/src/main/java/de/ids_mannheim/korap/handlers/OAuthDb.java
@@ -1,13 +1,13 @@
 package de.ids_mannheim.korap.handlers;
 
 import de.ids_mannheim.korap.config.ClientInfo;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.exceptions.DatabaseException;
 import de.ids_mannheim.korap.interfaces.db.PersistenceClient;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.TokenType;
-import de.ids_mannheim.korap.user.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.BooleanUtils;
 import de.ids_mannheim.korap.utils.TimeUtils;
diff --git a/full/src/main/java/de/ids_mannheim/korap/interfaces/AuthenticationIface.java b/full/src/main/java/de/ids_mannheim/korap/interfaces/AuthenticationIface.java
index 8d715a7..140ef6b 100644
--- a/full/src/main/java/de/ids_mannheim/korap/interfaces/AuthenticationIface.java
+++ b/full/src/main/java/de/ids_mannheim/korap/interfaces/AuthenticationIface.java
@@ -2,9 +2,9 @@
 
 import java.util.Map;
 
-import de.ids_mannheim.korap.config.TokenType;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.User;
 
 public interface AuthenticationIface {
diff --git a/full/src/main/java/de/ids_mannheim/korap/interfaces/AuthenticationManagerIface.java b/full/src/main/java/de/ids_mannheim/korap/interfaces/AuthenticationManagerIface.java
index cf37422..4f3fcc0 100644
--- a/full/src/main/java/de/ids_mannheim/korap/interfaces/AuthenticationManagerIface.java
+++ b/full/src/main/java/de/ids_mannheim/korap/interfaces/AuthenticationManagerIface.java
@@ -6,11 +6,11 @@
 
 import javax.ws.rs.core.HttpHeaders;
 
-import de.ids_mannheim.korap.config.AuthenticationMethod;
 import de.ids_mannheim.korap.config.KustvaktCacheable;
-import de.ids_mannheim.korap.config.TokenType;
+import de.ids_mannheim.korap.constant.AuthenticationMethod;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.user.Userdata;
 
diff --git a/core/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktContext.java b/full/src/main/java/de/ids_mannheim/korap/security/context/KustvaktContext.java
similarity index 89%
rename from core/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktContext.java
rename to full/src/main/java/de/ids_mannheim/korap/security/context/KustvaktContext.java
index f34cd43..6d36199 100644
--- a/core/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktContext.java
+++ b/full/src/main/java/de/ids_mannheim/korap/security/context/KustvaktContext.java
@@ -1,8 +1,7 @@
-package de.ids_mannheim.korap.web.utils;
-
-import de.ids_mannheim.korap.user.TokenContext;
+package de.ids_mannheim.korap.security.context;
 
 import javax.ws.rs.core.SecurityContext;
+
 import java.security.Principal;
 
 /**
diff --git a/core/src/main/java/de/ids_mannheim/korap/user/TokenContext.java b/full/src/main/java/de/ids_mannheim/korap/security/context/TokenContext.java
similarity index 95%
rename from core/src/main/java/de/ids_mannheim/korap/user/TokenContext.java
rename to full/src/main/java/de/ids_mannheim/korap/security/context/TokenContext.java
index df3b7db..becdf9b 100644
--- a/core/src/main/java/de/ids_mannheim/korap/user/TokenContext.java
+++ b/full/src/main/java/de/ids_mannheim/korap/security/context/TokenContext.java
@@ -1,4 +1,4 @@
-package de.ids_mannheim.korap.user;
+package de.ids_mannheim.korap.security.context;
 
 import java.io.Serializable;
 import java.util.HashMap;
@@ -7,8 +7,10 @@
 import com.fasterxml.jackson.databind.JsonNode;
 
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.TokenType;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.user.User.UserFactory;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.utils.TimeUtils;
 import lombok.AccessLevel;
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java b/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java
index dbfdc2e..ec146fd 100644
--- a/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java
@@ -1,14 +1,21 @@
 package de.ids_mannheim.korap.service;
 
 import org.apache.commons.validator.routines.UrlValidator;
+import org.apache.oltu.oauth2.common.message.types.GrantType;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import de.ids_mannheim.korap.constant.ClientType;
+import de.ids_mannheim.korap.authentication.http.AuthorizationData;
+import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
+import de.ids_mannheim.korap.constant.AuthenticationScheme;
+import de.ids_mannheim.korap.constant.OAuth2ClientType;
 import de.ids_mannheim.korap.dao.OAuth2ClientDao;
+import de.ids_mannheim.korap.dto.OAuth2ClientDto;
+import de.ids_mannheim.korap.entity.OAuth2Client;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.web.input.OAuth2ClientJson;
 
 @Service
@@ -20,10 +27,11 @@
     private UrlValidator urlValidator;
     @Autowired
     private EncryptionIface encryption;
+    @Autowired
+    private HttpAuthorizationHandler authorizationHandler;
 
-
-    public void registerClient (OAuth2ClientJson clientJson)
-            throws KustvaktException {
+    public OAuth2ClientDto registerClient (OAuth2ClientJson clientJson,
+            String registeredBy) throws KustvaktException {
         if (!urlValidator.isValid(clientJson.getUrl())) {
             throw new KustvaktException(StatusCodes.INVALID_ARGUMENT,
                     clientJson.getUrl() + " is invalid.", clientJson.getUrl());
@@ -35,14 +43,83 @@
         }
 
         String secret = null;
-        if (clientJson.getType().equals(ClientType.CONFIDENTIAL)) {
+        if (clientJson.getType().equals(OAuth2ClientType.CONFIDENTIAL)) {
             secret = encryption.createToken();
         }
 
         String id = encryption.createRandomNumber();
-        
+
         clientDao.registerClient(id, secret, clientJson.getName(),
                 clientJson.getType(), clientJson.getUrl(),
-                clientJson.getRedirectURI());
+                clientJson.getRedirectURI(), registeredBy);
+
+        return new OAuth2ClientDto(id, secret);
+    }
+
+
+    public OAuth2ClientDto deregisterClient (String clientId, String username) {
+
+
+        return null;
+    }
+
+
+    public TokenContext requestAccessTokenByClientCredentials (
+            String authorization, String grantType) throws KustvaktException {
+
+        return null;
+    }
+
+    /** According to RFC 6749, an authorization server MUST: 
+     * <ul>
+     * <li>
+     * require client authentication for confidential clients or for any
+     * client that was issued client credentials (or with other authentication 
+     * requirements),
+     * </li>
+     * 
+     * <li>authenticate the client if client authentication is included
+     * </li>
+     * </ul>
+     * 
+     * @param authorization
+     * @param grantType
+     * @param client_id
+     * @return
+     * @throws KustvaktException
+     */
+    public OAuth2Client authenticateClient (String authorization,
+            GrantType grantType, String client_id) throws KustvaktException {
+
+        OAuth2Client client = clientDao.retrieveClientById(client_id);
+
+        if (authorization == null || authorization.isEmpty()) {
+            if (client.getType().equals(OAuth2ClientType.CONFIDENTIAL)
+                    || grantType.equals(GrantType.CLIENT_CREDENTIALS)) {
+                new KustvaktException(StatusCodes.CLIENT_AUTHENTICATION_FAILED,
+                        "Authorization header is not found.");
+            }
+            // OAuth2 does not require client authentication
+        }
+        else {
+            AuthorizationData authData = authorizationHandler
+                    .parseAuthorizationHeaderValue(authorization);
+            if (authData.getAuthenticationScheme()
+                    .equals(AuthenticationScheme.BASIC)) {
+                if (!client.getSecret().equals(authData.getPassword())) {
+                    new KustvaktException(
+                            StatusCodes.CLIENT_AUTHENTICATION_FAILED,
+                            "Client credentials are incorrect.");
+                }
+            }
+            else {
+                throw new KustvaktException(
+                        StatusCodes.UNSUPPORTED_AUTHENTICATION_SCHEME,
+                        authData.getAuthenticationScheme().displayName()
+                                + "is unsupported for client authentication.",
+                        authData.getAuthenticationScheme().displayName());
+            }
+        }
+        return client;
     }
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/OAuth2Service.java b/full/src/main/java/de/ids_mannheim/korap/service/OAuth2Service.java
new file mode 100644
index 0000000..aee6b13
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/service/OAuth2Service.java
@@ -0,0 +1,57 @@
+package de.ids_mannheim.korap.service;
+
+import org.apache.oltu.oauth2.common.message.types.GrantType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import de.ids_mannheim.korap.entity.OAuth2Client;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+
+@Service
+public class OAuth2Service {
+
+    @Autowired
+    private OAuth2ClientService clientService;
+
+    /** 
+     *  RFC 6749:
+     *  
+     *  If the client type is confidential or the client was issued client
+     *  credentials, the client MUST authenticate with the authorization server.
+     *  
+     * @param authorization
+     * @param grantType
+     * @param scope 
+     * @param password 
+     * @param username 
+     * @param client_id 
+     * @param redirectURI 
+     * @param authorizationCode 
+     * @throws KustvaktException
+     */
+    public void requestAccessToken (String authorization, GrantType grantType,
+            String authorizationCode, String redirectURI, String client_id,
+            String username, String password, String scope)
+            throws KustvaktException {
+
+        OAuth2Client client = clientService.authenticateClient(authorization,
+                grantType, client_id);
+
+        if (grantType.equals(GrantType.AUTHORIZATION_CODE)) {
+
+        }
+        else if (grantType.equals(GrantType.PASSWORD)) {
+
+        }
+        else if (grantType.equals(GrantType.CLIENT_CREDENTIALS)) {
+
+        }
+        else {
+            throw new KustvaktException(StatusCodes.UNSUPPORTED_GRANT_TYPE,
+                    "Grant type " + grantType.name() + " is unsupported.",
+                    grantType.name());
+        }
+
+    }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/AnnotationController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/AnnotationController.java
index a49c276..09cebff 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/AnnotationController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/AnnotationController.java
@@ -9,16 +9,15 @@
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.jersey.spi.container.ResourceFilters;
 
+import de.ids_mannheim.korap.dto.FoundryDto;
+import de.ids_mannheim.korap.dto.LayerDto;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.service.AnnotationService;
@@ -35,13 +34,13 @@
  */
 @Controller
 @Path("annotation/")
-@ResourceFilters({DemoUserFilter.class, PiwikFilter.class })
+@ResourceFilters({ DemoUserFilter.class, PiwikFilter.class })
 @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
 public class AnnotationController {
 
     @Autowired
     CoreResponseHandler responseHandler;
-    
+
     @Autowired
     private AnnotationService annotationService;
 
@@ -52,13 +51,8 @@
      */
     @GET
     @Path("layers")
-    public Response getLayers () {
-        try {
-            return Response.ok(JsonUtils.toJSON(annotationService.getLayerDtos())).build();
-        }
-        catch (KustvaktException e) {
-            throw responseHandler.throwit(e);
-        }
+    public List<LayerDto> getLayers () {
+        return annotationService.getLayerDtos();
     }
 
 
@@ -75,13 +69,13 @@
     @POST
     @Path("description")
     @Consumes(MediaType.APPLICATION_JSON)
-    public Response getFoundryDescriptions (String json) {
+    public List<FoundryDto> getFoundryDescriptions (String json) {
         if (json == null || json.isEmpty()) {
             throw responseHandler
                     .throwit(new KustvaktException(StatusCodes.MISSING_ARGUMENT,
                             "Missing a json string.", ""));
         }
-        
+
         JsonNode node;
         try {
             node = JsonUtils.readTree(json);
@@ -125,16 +119,12 @@
                             "No result found.", "codes:[]"));
         }
 
-        String result;
         try {
-            result = JsonUtils
-                    .toJSON(annotationService.getFoundryDtos(codes, language));
+            return annotationService.getFoundryDtos(codes, language);
         }
         catch (KustvaktException e) {
             throw responseHandler.throwit(e);
         }
-        return Response.ok(result).build();
     }
-
 }
 
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/AuthenticationController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/AuthenticationController.java
index d5d6a5b..1e783c2 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/AuthenticationController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/AuthenticationController.java
@@ -31,15 +31,15 @@
 import de.ids_mannheim.korap.authentication.http.AuthorizationData;
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.AuthenticationMethod;
-import de.ids_mannheim.korap.config.AuthenticationScheme;
-import de.ids_mannheim.korap.config.TokenType;
 import de.ids_mannheim.korap.config.BeansFactory;
+import de.ids_mannheim.korap.constant.AuthenticationMethod;
+import de.ids_mannheim.korap.constant.AuthenticationScheme;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.KorAPUser;
-import de.ids_mannheim.korap.user.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.utils.KustvaktLogger;
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2Controller.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2Controller.java
new file mode 100644
index 0000000..7cd3311
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2Controller.java
@@ -0,0 +1,61 @@
+package de.ids_mannheim.korap.web.controller;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+
+import org.apache.oltu.oauth2.common.message.types.GrantType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.service.OAuth2Service;
+import de.ids_mannheim.korap.web.FullResponseHandler;
+
+@Controller
+@Path("/oauth2")
+public class OAuth2Controller {
+
+    @Autowired
+    private FullResponseHandler responseHandler;
+    @Autowired
+    private OAuth2Service oauth2Service;
+
+    @POST
+    @Path("token")
+    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public Response requestAccessToken (
+            @Context SecurityContext securityContext,
+            @HeaderParam("Authorization") String authorization,
+            // required for all grants
+            @FormParam("grant_type") GrantType grantType,
+            // required for Authorization Code Grant
+            @FormParam("code") String authorizationCode,
+            @FormParam("redirect_uri") String redirectURI,
+            @FormParam("client_id") String client_id,
+            // required for Resource Owner Password Credentials Grant
+            @FormParam("username") String username,
+            @FormParam("password") String password,
+            // optional for Resource Owner Password and Client Credentials Grants
+            @FormParam("scope") String scope) {
+
+        try {
+            oauth2Service.requestAccessToken(authorization, grantType,
+                    authorizationCode, redirectURI, client_id, username,
+                    password, scope);
+
+            return Response.ok().build();
+        }
+        catch (KustvaktException e) {
+            throw responseHandler.throwit(e);
+        }
+    }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java
index b0b88e4..d766537 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java
@@ -6,7 +6,6 @@
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
 import javax.ws.rs.core.SecurityContext;
 
 import org.springframework.beans.factory.annotation.Autowired;
@@ -14,7 +13,9 @@
 
 import com.sun.jersey.spi.container.ResourceFilters;
 
+import de.ids_mannheim.korap.dto.OAuth2ClientDto;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.service.OAuth2ClientService;
 import de.ids_mannheim.korap.web.FullResponseHandler;
 import de.ids_mannheim.korap.web.filter.AuthenticationFilter;
@@ -23,9 +24,7 @@
 
 
 @Controller
-@Path("/client")
-//@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
-//@ResourceFilters({ AuthenticationFilter.class, BlockingFilter.class })
+@Path("/oauth2/client")
 public class OAuthClientController {
 
     @Autowired
@@ -33,27 +32,77 @@
     @Autowired
     private FullResponseHandler responseHandler;
 
-    /** EM: who can register a client?
+    /** Registers a client application. Before starting an OAuth process, 
+     * client applications have to be registered first. Only registered
+     * users are allowed to register client applications.
      * 
+     * From RFC 6749:
      * The authorization server SHOULD document the size of any identifier 
      * it issues.
      * 
      * @param context
-     * @param clientJson
-     * @return
+     * @param clientJson a JSON object describing the client
+     * @return client id and secret if the client type is confidential
      */
     @POST
     @Path("register")
     @Consumes(MediaType.APPLICATION_JSON)
-    public Response registerClient (@Context SecurityContext context,
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    @ResourceFilters({ AuthenticationFilter.class, BlockingFilter.class })
+    public OAuth2ClientDto registerClient (
+            @Context SecurityContext securityContext,
             OAuth2ClientJson clientJson) {
+        TokenContext context =
+                (TokenContext) securityContext.getUserPrincipal();
         try {
-            clientService.registerClient(clientJson);
+            return clientService.registerClient(clientJson,
+                    context.getUsername());
         }
         catch (KustvaktException e) {
-            responseHandler.throwit(e);
+            throw responseHandler.throwit(e);
         }
-        return Response.ok().build();
     }
 
+
+    //    /** Deregisters a client via owner authentication. 
+    //     * 
+    //     * EM: who can deregister clients? The user registered the clients or the client itself?
+    //     * 
+    //     * @param securityContext
+    //     * @param clientId
+    //     * @return HTTP Response OK if successful.
+    //     */
+    //    @POST
+    //    @Path("deregister")
+    //    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+    //    @ResourceFilters({ AuthenticationFilter.class, BlockingFilter.class })
+    //    public OAuth2ClientDto deregisterClient (
+    //            @Context SecurityContext securityContext,
+    //            @FormParam("client_id") String clientId) {
+    //        TokenContext context =
+    //                (TokenContext) securityContext.getUserPrincipal();
+    //        try {
+    //            return clientService.deregisterClient(clientId,
+    //                    context.getUsername());
+    //        }
+    //        catch (KustvaktException e) {
+    //            throw responseHandler.throwit(e);
+    //        }
+    //    }
+    //
+    //    @POST
+    //    @Path("deregister")
+    //    @ResourceFilters({ OAuth2ClientAuthenticationFilter.class,
+    //            BlockingFilter.class })
+    //    public OAuth2ClientDto deregisterClient (
+    //            @Context SecurityContext securityContext) {
+    //        TokenContext context =
+    //                (TokenContext) securityContext.getUserPrincipal();
+    //        try {
+    //            return clientService.deregisterClient();
+    //        }
+    //        catch (KustvaktException e) {
+    //            throw responseHandler.throwit(e);
+    //        }
+    //    }
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthController.java
index fdc2046..47e5968 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthController.java
@@ -43,18 +43,18 @@
 
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.AuthCodeInfo;
-import de.ids_mannheim.korap.config.AuthenticationMethod;
 import de.ids_mannheim.korap.config.BeansFactory;
 import de.ids_mannheim.korap.config.ClientInfo;
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
 import de.ids_mannheim.korap.config.Scopes;
-import de.ids_mannheim.korap.config.TokenType;
+import de.ids_mannheim.korap.constant.AuthenticationMethod;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.handlers.OAuth2Handler;
 import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
-import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.user.UserDetails;
 import de.ids_mannheim.korap.user.Userdata;
@@ -73,7 +73,7 @@
  */
 //todo: only allow oauth2 access_token requests GET methods?
 //todo: allow refresh tokens
-@Path("/oauth2")
+//@Path("/oauth2")
 public class OAuthController {
 
     @Autowired
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/ResourceController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/ResourceController.java
index d64e5bd..a603489 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/ResourceController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/ResourceController.java
@@ -1,5 +1,7 @@
 package de.ids_mannheim.korap.web.controller;
 
+import java.util.List;
+
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
@@ -11,6 +13,7 @@
 
 import com.sun.jersey.spi.container.ResourceFilters;
 
+import de.ids_mannheim.korap.dto.ResourceDto;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.service.ResourceService;
 import de.ids_mannheim.korap.utils.JsonUtils;
@@ -40,15 +43,7 @@
      */
     @GET
     @Path("info")
-    public Response getAllResourceInfo () {
-        String result = "";
-        try {
-            result = JsonUtils.toJSON(resourceService.getResourceDtos());
-        }
-        catch (KustvaktException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        return Response.ok(result).build();
+    public List<ResourceDto> getAllResourceInfo () {
+        return resourceService.getResourceDtos();
     }
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
index 27b17e1..d97052b 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
@@ -49,7 +49,7 @@
 import de.ids_mannheim.korap.resources.ResourceFactory;
 import de.ids_mannheim.korap.resources.VirtualCollection;
 import de.ids_mannheim.korap.rewrite.FullRewriteHandler;
-import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.user.User.CorpusAccess;
 import de.ids_mannheim.korap.utils.JsonUtils;
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserController.java
index a0b2923..670840b 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserController.java
@@ -42,8 +42,8 @@
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.KorAPUser;
-import de.ids_mannheim.korap.user.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.user.UserDetails;
 import de.ids_mannheim.korap.user.UserQuery;
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
index e96ec0a..5781520 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
@@ -24,9 +24,8 @@
 import de.ids_mannheim.korap.constant.UserGroupStatus;
 import de.ids_mannheim.korap.dto.UserGroupDto;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.service.UserGroupService;
-import de.ids_mannheim.korap.user.TokenContext;
-import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.web.FullResponseHandler;
 import de.ids_mannheim.korap.web.filter.AuthenticationFilter;
 import de.ids_mannheim.korap.web.filter.BlockingFilter;
@@ -46,7 +45,6 @@
  */
 @Controller
 @Path("group")
-@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
 @ResourceFilters({ AuthenticationFilter.class, BlockingFilter.class,
         PiwikFilter.class })
 public class UserGroupController {
@@ -66,14 +64,13 @@
      */
     @GET
     @Path("list")
-    public Response getUserGroup (@Context SecurityContext securityContext) {
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public List<UserGroupDto> getUserGroup (
+            @Context SecurityContext securityContext) {
         TokenContext context =
                 (TokenContext) securityContext.getUserPrincipal();
         try {
-            List<UserGroupDto> dtos =
-                    service.retrieveUserGroup(context.getUsername());
-            String result = JsonUtils.toJSON(dtos);
-            return Response.ok(result).build();
+            return service.retrieveUserGroup(context.getUsername());
         }
         catch (KustvaktException e) {
             throw responseHandler.throwit(e);
@@ -92,17 +89,16 @@
      */
     @GET
     @Path("list/system-admin")
-    public Response getUserGroupBySystemAdmin (
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public List<UserGroupDto> getUserGroupBySystemAdmin (
             @Context SecurityContext securityContext,
             @QueryParam("username") String username,
             @QueryParam("status") UserGroupStatus status) {
         TokenContext context =
                 (TokenContext) securityContext.getUserPrincipal();
         try {
-            List<UserGroupDto> dtos = service.retrieveUserGroupByStatus(
-                    username, context.getUsername(), status);
-            String result = JsonUtils.toJSON(dtos);
-            return Response.ok(result).build();
+            return service.retrieveUserGroupByStatus(username,
+                    context.getUsername(), status);
         }
         catch (KustvaktException e) {
             throw responseHandler.throwit(e);
@@ -117,20 +113,19 @@
      */
     @GET
     @Path("{groupId}")
-    public Response searchUserGroup (@Context SecurityContext securityContext,
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public UserGroupDto searchUserGroup (
+            @Context SecurityContext securityContext,
             @PathParam("groupId") int groupId) {
-        String result;
         TokenContext context =
                 (TokenContext) securityContext.getUserPrincipal();
         try {
-            UserGroupDto dto =
-                    service.searchById(context.getUsername(), groupId);
-            result = JsonUtils.toJSON(dto);
+            return service.searchById(context.getUsername(), groupId);
         }
         catch (KustvaktException e) {
             throw responseHandler.throwit(e);
         }
-        return Response.ok(result).build();
+
     }
 
     /** Creates a user group where the user in token context is the 
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
index a0f937f..b68ab2d 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
@@ -16,8 +16,6 @@
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.SecurityContext;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 
@@ -28,9 +26,8 @@
 import de.ids_mannheim.korap.dto.VirtualCorpusAccessDto;
 import de.ids_mannheim.korap.dto.VirtualCorpusDto;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.service.VirtualCorpusService;
-import de.ids_mannheim.korap.user.TokenContext;
-import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.web.FullResponseHandler;
 import de.ids_mannheim.korap.web.filter.AuthenticationFilter;
 import de.ids_mannheim.korap.web.filter.BlockingFilter;
@@ -53,14 +50,10 @@
  */
 @Controller
 @Path("vc")
-@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
 @ResourceFilters({ AuthenticationFilter.class, BlockingFilter.class,
         PiwikFilter.class })
 public class VirtualCorpusController {
 
-    private static Logger jlog =
-            LoggerFactory.getLogger(VirtualCorpusController.class);
-
     @Autowired
     private FullResponseHandler responseHandler;
     @Autowired
@@ -81,8 +74,6 @@
     public Response createVC (@Context SecurityContext securityContext,
             VirtualCorpusJson vc) {
         try {
-            jlog.debug(vc.toString());
-
             // get user info
             TokenContext context =
                     (TokenContext) securityContext.getUserPrincipal();
@@ -131,20 +122,17 @@
      */
     @GET
     @Path("search/{vcId}")
-    public Response searchVC (@Context SecurityContext securityContext,
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public VirtualCorpusDto searchVC (@Context SecurityContext securityContext,
             @PathParam("vcId") int vcId) {
-        String result;
         TokenContext context =
                 (TokenContext) securityContext.getUserPrincipal();
         try {
-            VirtualCorpusDto dto =
-                    service.searchVCById(context.getUsername(), vcId);
-            result = JsonUtils.toJSON(dto);
+            return service.searchVCById(context.getUsername(), vcId);
         }
         catch (KustvaktException e) {
             throw responseHandler.throwit(e);
         }
-        return Response.ok(result).build();
     }
 
     /** Lists not only private virtual corpora but all virtual corpora 
@@ -160,20 +148,18 @@
      */
     @GET
     @Path("list")
-    public Response listVCByUser (@Context SecurityContext securityContext,
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public List<VirtualCorpusDto> listVCByUser (
+            @Context SecurityContext securityContext,
             @QueryParam("createdBy") String createdBy) {
-        String result;
         TokenContext context =
                 (TokenContext) securityContext.getUserPrincipal();
         try {
-            List<VirtualCorpusDto> dtos =
-                    service.listVCByUser(context.getUsername(), createdBy);
-            result = JsonUtils.toJSON(dtos);
+            return service.listVCByUser(context.getUsername(), createdBy);
         }
         catch (KustvaktException e) {
             throw responseHandler.throwit(e);
         }
-        return Response.ok(result).build();
     }
 
     /** Lists all virtual corpora created by a user
@@ -184,19 +170,17 @@
      */
     @GET
     @Path("list/user")
-    public Response listUserVC (@Context SecurityContext securityContext) {
-        String result;
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public List<VirtualCorpusDto> listUserVC (
+            @Context SecurityContext securityContext) {
         TokenContext context =
                 (TokenContext) securityContext.getUserPrincipal();
         try {
-            List<VirtualCorpusDto> dtos =
-                    service.listOwnerVC(context.getUsername());
-            result = JsonUtils.toJSON(dtos);
+            return service.listOwnerVC(context.getUsername());
         }
         catch (KustvaktException e) {
             throw responseHandler.throwit(e);
         }
-        return Response.ok(result).build();
     }
 
     /** Lists virtual corpora by creator and type. This is a controller for 
@@ -213,21 +197,19 @@
      */
     @GET
     @Path("list/system-admin")
-    public Response listVCByStatus (@Context SecurityContext securityContext,
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public List<VirtualCorpusDto> listVCByStatus (
+            @Context SecurityContext securityContext,
             @QueryParam("createdBy") String createdBy,
             @QueryParam("type") VirtualCorpusType type) {
-        String result;
         TokenContext context =
                 (TokenContext) securityContext.getUserPrincipal();
         try {
-            List<VirtualCorpusDto> dtos = service
-                    .listVCByType(context.getUsername(), createdBy, type);
-            result = JsonUtils.toJSON(dtos);
+            return service.listVCByType(context.getUsername(), createdBy, type);
         }
         catch (KustvaktException e) {
             throw responseHandler.throwit(e);
         }
-        return Response.ok(result).build();
     }
 
     /** Only the VC owner and system admins can delete VC. VCA admins 
@@ -312,20 +294,18 @@
      */
     @GET
     @Path("access/list")
-    public Response listVCAccess (@Context SecurityContext securityContext,
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public List<VirtualCorpusAccessDto> listVCAccess (
+            @Context SecurityContext securityContext,
             @QueryParam("vcId") int vcId) {
         TokenContext context =
                 (TokenContext) securityContext.getUserPrincipal();
-        String result;
         try {
-            List<VirtualCorpusAccessDto> dtos =
-                    service.listVCAccessByVC(context.getUsername(), vcId);
-            result = JsonUtils.toJSON(dtos);
+            return service.listVCAccessByVC(context.getUsername(), vcId);
         }
         catch (KustvaktException e) {
             throw responseHandler.throwit(e);
         }
-        return Response.ok(result).build();
     }
 
     /** Lists active VC-accesses available for a user-group. 
@@ -338,20 +318,17 @@
      */
     @GET
     @Path("access/list/byGroup")
-    public Response listVCAccessByGroup (
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public List<VirtualCorpusAccessDto> listVCAccessByGroup (
             @Context SecurityContext securityContext,
             @QueryParam("groupId") int groupId) {
         TokenContext context =
                 (TokenContext) securityContext.getUserPrincipal();
-        String result;
         try {
-            List<VirtualCorpusAccessDto> dtos =
-                    service.listVCAccessByGroup(context.getUsername(), groupId);
-            result = JsonUtils.toJSON(dtos);
+            return service.listVCAccessByGroup(context.getUsername(), groupId);
         }
         catch (KustvaktException e) {
             throw responseHandler.throwit(e);
         }
-        return Response.ok(result).build();
     }
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java b/full/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java
index 5b3d68a..aa3b0ad 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java
@@ -18,16 +18,16 @@
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.authentication.http.TransferEncoding;
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.AuthenticationMethod;
+import de.ids_mannheim.korap.constant.AuthenticationMethod;
 import de.ids_mannheim.korap.dao.AdminDao;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
-import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.security.context.KustvaktContext;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.StringUtils;
 import de.ids_mannheim.korap.web.FullResponseHandler;
-import de.ids_mannheim.korap.web.utils.KustvaktContext;
 
 /**
  * @author hanl, margaretha
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/filter/AuthenticationFilter.java b/full/src/main/java/de/ids_mannheim/korap/web/filter/AuthenticationFilter.java
index 75ef3cc..118f780 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/filter/AuthenticationFilter.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/filter/AuthenticationFilter.java
@@ -12,14 +12,14 @@
 
 import de.ids_mannheim.korap.authentication.http.AuthorizationData;
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
-import de.ids_mannheim.korap.config.TokenType;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
-import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.security.context.KustvaktContext;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.utils.TimeUtils;
 import de.ids_mannheim.korap.web.FullResponseHandler;
-import de.ids_mannheim.korap.web.utils.KustvaktContext;
 
 /**
  * @author hanl, margaretha
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/filter/BlockingFilter.java b/full/src/main/java/de/ids_mannheim/korap/web/filter/BlockingFilter.java
index 4cc7f99..107d102 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/filter/BlockingFilter.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/filter/BlockingFilter.java
@@ -12,7 +12,7 @@
 
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
-import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.web.FullResponseHandler;
 
 /**
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/filter/DemoFilter.java b/full/src/main/java/de/ids_mannheim/korap/web/filter/DemoFilter.java
index d3f2cd9..321417d 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/filter/DemoFilter.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/filter/DemoFilter.java
@@ -11,10 +11,10 @@
 import com.sun.jersey.spi.container.ResourceFilter;
 
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
-import de.ids_mannheim.korap.config.TokenType;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.user.TokenContext;
-import de.ids_mannheim.korap.web.utils.KustvaktContext;
+import de.ids_mannheim.korap.security.context.KustvaktContext;
+import de.ids_mannheim.korap.security.context.TokenContext;
 
 /**
  * @author hanl
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/filter/DemoUserFilter.java b/full/src/main/java/de/ids_mannheim/korap/web/filter/DemoUserFilter.java
index 106c180..78138bb 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/filter/DemoUserFilter.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/filter/DemoUserFilter.java
@@ -6,11 +6,11 @@
 import com.sun.jersey.spi.container.ResourceFilter;
 import de.ids_mannheim.korap.config.BeansFactory;
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
-import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.security.context.KustvaktContext;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.TimeUtils;
 import de.ids_mannheim.korap.web.CoreResponseHandler;
-import de.ids_mannheim.korap.web.utils.KustvaktContext;
 
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.UriInfo;
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/filter/NonDemoBlockingFilter.java b/full/src/main/java/de/ids_mannheim/korap/web/filter/NonDemoBlockingFilter.java
index 3efa619..d47e1da 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/filter/NonDemoBlockingFilter.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/filter/NonDemoBlockingFilter.java
@@ -12,7 +12,7 @@
 
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
-import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.web.FullResponseHandler;
 
 /**
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/filter/PiwikFilter.java b/full/src/main/java/de/ids_mannheim/korap/web/filter/PiwikFilter.java
index ee8ee15..abf2eb9 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/filter/PiwikFilter.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/filter/PiwikFilter.java
@@ -14,6 +14,7 @@
 import de.ids_mannheim.korap.config.BeansFactory;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.*;
 import net.minidev.json.JSONArray;
 import org.slf4j.Logger;
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/input/OAuth2ClientJson.java b/full/src/main/java/de/ids_mannheim/korap/web/input/OAuth2ClientJson.java
index 28a2a6a..80c5fba 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/input/OAuth2ClientJson.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/input/OAuth2ClientJson.java
@@ -1,6 +1,6 @@
 package de.ids_mannheim.korap.web.input;
 
-import de.ids_mannheim.korap.constant.ClientType;
+import de.ids_mannheim.korap.constant.OAuth2ClientType;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -10,7 +10,7 @@
     
     // all required for registration
     private String name;
-    private ClientType type;
+    private OAuth2ClientType type;
     private String url;
     private String redirectURI;
 }
diff --git a/full/src/main/resources/db/new-mysql/V1.4__oauth2_tables.sql b/full/src/main/resources/db/new-mysql/V1.4__oauth2_tables.sql
index e36b0f9..c228c08 100644
--- a/full/src/main/resources/db/new-mysql/V1.4__oauth2_tables.sql
+++ b/full/src/main/resources/db/new-mysql/V1.4__oauth2_tables.sql
@@ -3,12 +3,13 @@
 -- oauth2 db tables
 create table if not exists oauth2_client (
 	id VARCHAR(100) UNIQUE PRIMARY KEY,
+	name VARCHAR(200) NOT NULL,
 	secret VARCHAR(200),
 	type VARCHAR(200) NOT NULL,
+	url TEXT UNIQUE NOT NULL,
 	redirect_uri TEXT NOT NULL,
 --is_confidential BOOLEAN DEFAULT FALSE,
-	url TEXT UNIQUE NOT NULL,
-	name VARCHAR(200) NOT NULL
+	registeredBy VARCHAR(100) NOT NULL
 );
 
 
diff --git a/full/src/main/resources/db/new-sqlite/V1.4__oauth2_tables.sql b/full/src/main/resources/db/new-sqlite/V1.4__oauth2_tables.sql
index ecf7a24..fe0391f 100644
--- a/full/src/main/resources/db/new-sqlite/V1.4__oauth2_tables.sql
+++ b/full/src/main/resources/db/new-sqlite/V1.4__oauth2_tables.sql
@@ -3,9 +3,10 @@
 -- oauth2 db tables
 create table IF NOT EXISTS oauth2_client (
 	id VARCHAR(100) NOT NULL,
+	name VARCHAR(200) NOT NULL,
 	secret VARCHAR(200) NOT NULL,
 	type VARCHAR(200) NOT NULL,
-	redirect_uri TEXT NOT NULL,
 	url TEXT UNIQUE NOT NULL,
-	name VARCHAR(200) NOT NULL
+	redirect_uri TEXT NOT NULL,
+	registeredBy VARCHAR(100) NOT NULL
 );
diff --git a/full/src/main/resources/default-config.xml b/full/src/main/resources/default-config.xml
index 2844538..b3bf566 100644
--- a/full/src/main/resources/default-config.xml
+++ b/full/src/main/resources/default-config.xml
@@ -1,11 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xmlns:p="http://www.springframework.org/schema/p" 
-	xmlns:util="http://www.springframework.org/schema/util"
-	xmlns:aop="http://www.springframework.org/schema/aop" 
-	xmlns:tx="http://www.springframework.org/schema/tx"
-	xmlns="http://www.springframework.org/schema/beans" 
-	xmlns:context="http://www.springframework.org/schema/context"
+	xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util"
+	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
+	xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
 	xmlns:cache="http://www.springframework.org/schema/cache"
 	xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
@@ -21,9 +18,8 @@
 	<context:component-scan base-package="de.ids_mannheim.korap" />
 	<context:annotation-config />
 
-	<!-- <bean id="test" class="de.ids_mannheim.korap.web.Test">
-		<property name="config" ref="kustvakt_config" />
-	</bean> -->
+	<!-- <bean id="test" class="de.ids_mannheim.korap.web.Test"> <property name="config" 
+		ref="kustvakt_config" /> </bean> -->
 
 	<bean id="props"
 		class="org.springframework.beans.factory.config.PropertiesFactoryBean">
@@ -46,7 +42,7 @@
 				<value>classpath:properties/mail.properties</value>
 				<value>file:./mail.properties</value>
 				<value>classpath:properties/hibernate.properties</value>
-				
+
 				<value>classpath:kustvakt.conf</value>
 				<value>file:./kustvakt.conf</value>
 			</array>
@@ -91,11 +87,11 @@
 		<property name="username" value="${jdbc.username}" />
 		<property name="password" value="${jdbc.password}" />
 		<property name="connectionProperties">
-            <props>
-                <prop key="date_string_format">yyyy-MM-dd HH:mm:ss</prop>
-            </props>
-        </property>
-        
+			<props>
+				<prop key="date_string_format">yyyy-MM-dd HH:mm:ss</prop>
+			</props>
+		</property>
+
 		<!-- relevant for single connection datasource and sqlite -->
 		<property name="suppressClose">
 			<value>true</value>
@@ -113,8 +109,8 @@
 		<!-- <property name="dataSource" ref="dataSource" /> -->
 		<property name="dataSource" ref="sqliteDataSource" />
 	</bean>
-	
-	
+
+
 	<bean id="kustvakt_db" class="de.ids_mannheim.korap.handlers.JDBCClient">
 		<constructor-arg index="0" ref="dataSource" />
 		<!-- deprecated property -->
@@ -125,7 +121,7 @@
 		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
 		<!-- <property name="dataSource" ref="dataSource" /> -->
 		<property name="dataSource" ref="sqliteDataSource" />
-		
+
 		<property name="packagesToScan" value="de.ids_mannheim.korap.entity" />
 		<property name="jpaVendorAdapter">
 			<bean id="jpaVendorAdapter"
@@ -150,7 +146,7 @@
 
 	<tx:annotation-driven proxy-target-class="true"
 		transaction-manager="transactionManager" />
-		
+
 	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
 		<property name="entityManagerFactory" ref="entityManagerFactory" />
 	</bean>
@@ -161,20 +157,20 @@
 	</bean>
 
 	<!-- Data access objects -->
-	<bean id="resourceDao" class="de.ids_mannheim.korap.dao.ResourceDao"/>
+	<bean id="resourceDao" class="de.ids_mannheim.korap.dao.ResourceDao" />
 	<!-- <bean id="annotationDao" class="de.ids_mannheim.korap.dao.AnnotationDao"/> -->
 
 	<!-- Krill -->
 	<bean id="search_krill" class="de.ids_mannheim.korap.web.SearchKrill">
-		<constructor-arg value="${krill.indexDir}"/>
+		<constructor-arg value="${krill.indexDir}" />
 	</bean>
 
 	<!-- URLValidator -->
 	<bean id="urlValidator" class="org.apache.commons.validator.routines.UrlValidator">
-		<constructor-arg value="http,https"/>
+		<constructor-arg value="http,https" />
 	</bean>
-	
-	
+
+
 	<bean id="kustvakt_rewrite" class="de.ids_mannheim.korap.rewrite.FullRewriteHandler">
 		<constructor-arg ref="kustvakt_config" />
 	</bean>
@@ -183,11 +179,10 @@
 		<constructor-arg ref="kustvakt_db" />
 	</bean>
 
-	<bean id="kustvakt_response"
-          class="de.ids_mannheim.korap.web.FullResponseHandler">
-          <constructor-arg index="0" name="iface" ref="kustvakt_auditing"/>
-    </bean>
-    
+	<bean id="kustvakt_response" class="de.ids_mannheim.korap.web.FullResponseHandler">
+		<constructor-arg index="0" name="iface" ref="kustvakt_auditing" />
+	</bean>
+
 	<bean id="kustvakt_userdb" class="de.ids_mannheim.korap.handlers.EntityDao">
 		<constructor-arg ref="kustvakt_db" />
 	</bean>
@@ -206,11 +201,13 @@
 	</bean>
 
 	<!-- authentication providers to use -->
-	<!-- <bean id="api_auth" class="de.ids_mannheim.korap.authentication.APIAuthentication">
-		<constructor-arg type="de.ids_mannheim.korap.config.KustvaktConfiguration"
-			ref="kustvakt_config" />
-	</bean> -->
-	
+	<!-- <bean id="api_auth" class="de.ids_mannheim.korap.authentication.APIAuthentication"> 
+		<constructor-arg type="de.ids_mannheim.korap.config.KustvaktConfiguration" 
+		ref="kustvakt_config" /> </bean> -->
+
+	<bean id="client_auth"
+		class="de.ids_mannheim.korap.authentication.OAuth2ClientAuthentication" />
+
 	<bean id="ldap_auth" class="de.ids_mannheim.korap.authentication.LdapAuth3">
 		<constructor-arg type="de.ids_mannheim.korap.config.KustvaktConfiguration"
 			ref="kustvakt_config" />
@@ -238,6 +235,7 @@
 		<ref bean="session_auth" />
 		<!-- <ref bean="api_auth" /> -->
 		<ref bean="openid_auth" />
+		<ref bean="client_auth" />
 	</util:list>
 
 
@@ -265,8 +263,8 @@
 	<!-- specify type for constructor argument -->
 	<bean id="kustvakt_authenticationmanager"
 		class="de.ids_mannheim.korap.authentication.KustvaktAuthenticationManager">
-		<constructor-arg
-			type="de.ids_mannheim.korap.interfaces.EntityHandlerIface" ref="kustvakt_userdb" />
+		<constructor-arg type="de.ids_mannheim.korap.interfaces.EntityHandlerIface"
+			ref="kustvakt_userdb" />
 		<constructor-arg type="de.ids_mannheim.korap.interfaces.EncryptionIface"
 			ref="kustvakt_encryption" />
 		<constructor-arg ref="kustvakt_config" />
@@ -305,11 +303,11 @@
 		<!-- <property name="dataSource" ref="dataSource" /> -->
 		<property name="dataSource" ref="sqliteDataSource" />
 	</bean>
-	
+
 	<!-- mail -->
-		<bean id="authenticator" class="de.ids_mannheim.korap.service.MailAuthenticator">
-		<constructor-arg index="0" value="${mail.username}"/>
-		<constructor-arg index="1" value="${mail.password}"/>
+	<bean id="authenticator" class="de.ids_mannheim.korap.service.MailAuthenticator">
+		<constructor-arg index="0" value="${mail.username}" />
+		<constructor-arg index="1" value="${mail.password}" />
 	</bean>
 	<bean id="smtpSession" class="javax.mail.Session" factory-method="getInstance">
 		<constructor-arg index="0">
@@ -322,18 +320,19 @@
 				<prop key="mail.smtp.connectiontimeout">${mail.connectiontimeout}</prop>
 			</props>
 		</constructor-arg>
-		<constructor-arg index="1" ref="authenticator"/>
+		<constructor-arg index="1" ref="authenticator" />
 	</bean>
 	<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
 		<property name="username" value="${mail.username}" />
-	    <property name="password" value="${mail.password}" />
+		<property name="password" value="${mail.password}" />
 		<property name="session" ref="smtpSession" />
 	</bean>
 	<bean id="velocityEngine" class="org.apache.velocity.app.VelocityEngine">
 		<constructor-arg index="0">
 			<props>
 				<prop key="resource.loader">class</prop>
-				<prop key="class.resource.loader.class">org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader</prop>
+				<prop key="class.resource.loader.class">org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
+				</prop>
 			</props>
 		</constructor-arg>
 	</bean>
diff --git a/full/src/test/java/de/ids_mannheim/korap/authentication/APIAuthenticationTest.java b/full/src/test/java/de/ids_mannheim/korap/authentication/APIAuthenticationTest.java
index b1d43fa..0fca0b8 100644
--- a/full/src/test/java/de/ids_mannheim/korap/authentication/APIAuthenticationTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/authentication/APIAuthenticationTest.java
@@ -12,10 +12,10 @@
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
 import de.ids_mannheim.korap.config.SpringJerseyTest;
-import de.ids_mannheim.korap.config.TokenType;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.KorAPUser;
-import de.ids_mannheim.korap.user.TokenContext;
 import de.ids_mannheim.korap.user.User;
 
 public class APIAuthenticationTest extends SpringJerseyTest {
diff --git a/full/src/test/java/de/ids_mannheim/korap/config/TestHelper.java b/full/src/test/java/de/ids_mannheim/korap/config/TestHelper.java
index a2b9d72..765e8f4 100644
--- a/full/src/test/java/de/ids_mannheim/korap/config/TestHelper.java
+++ b/full/src/test/java/de/ids_mannheim/korap/config/TestHelper.java
@@ -34,6 +34,7 @@
 import de.ids_mannheim.korap.handlers.ResourceDao;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
 import de.ids_mannheim.korap.interfaces.EntityHandlerIface;
+import de.ids_mannheim.korap.interfaces.KustvaktBaseDaoInterface;
 import de.ids_mannheim.korap.interfaces.db.PersistenceClient;
 import de.ids_mannheim.korap.resources.KustvaktResource;
 import de.ids_mannheim.korap.user.User;
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/FilterTest.java b/full/src/test/java/de/ids_mannheim/korap/web/FilterTest.java
index 7dcfa32..64000cc 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/FilterTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/FilterTest.java
@@ -13,8 +13,8 @@
 
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.TokenType;
 import de.ids_mannheim.korap.config.TestHelper;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 
 /** EM: fix tests. new DB does not save users.
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/OAuth2HandlerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/OAuth2HandlerTest.java
index 52c266e..a8742fa 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/OAuth2HandlerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/OAuth2HandlerTest.java
@@ -15,7 +15,7 @@
 import de.ids_mannheim.korap.handlers.OAuth2Handler;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
 import de.ids_mannheim.korap.interfaces.db.PersistenceClient;
-import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.security.context.TokenContext;
 
 /**
  * EM: To do: not implemented in the new DB yet
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/AuthenticationControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/AuthenticationControllerTest.java
index 79aa8fe..abdb3f3 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/AuthenticationControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/AuthenticationControllerTest.java
@@ -17,8 +17,8 @@
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.authentication.http.TransferEncoding;
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.TokenType;
 import de.ids_mannheim.korap.config.TestHelper;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.user.User;
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java
index 26a11bc..97cce38 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java
@@ -1,34 +1,54 @@
 package de.ids_mannheim.korap.web.controller;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
 import org.apache.http.entity.ContentType;
 import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
 
+import com.fasterxml.jackson.databind.JsonNode;
 import com.google.common.net.HttpHeaders;
 import com.sun.jersey.api.client.ClientResponse;
 import com.sun.jersey.api.client.ClientResponse.Status;
 
+import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
+import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.SpringJerseyTest;
-import de.ids_mannheim.korap.constant.ClientType;
+import de.ids_mannheim.korap.constant.OAuth2ClientType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.web.input.OAuth2ClientJson;
 
 public class OAuth2ClientControllerTest extends SpringJerseyTest {
 
+    @Autowired
+    private HttpAuthorizationHandler handler;
+    private String username = "OAuth2ClientControllerTest";
+    
     @Test
     public void testRegisterClient () throws KustvaktException {
 
         OAuth2ClientJson json = new OAuth2ClientJson();
-        json.setName("OAuth2ClientControllerTest");
-        json.setType(ClientType.CONFIDENTIAL);
+        json.setName("OAuth2ClientTest");
+        json.setType(OAuth2ClientType.CONFIDENTIAL);
         json.setUrl("http://example.client.com");
         json.setRedirectURI("http://example.client.com/redirect");
 
-        ClientResponse response = resource().path("client").path("register")
+        ClientResponse response = resource().path("oauth2").path("client")
+                .path("register")
+                .header(Attributes.AUTHORIZATION,
+                        handler.createBasicAuthorizationHeaderValue(username,
+                                "pass"))
+                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
                 .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
                 .entity(json).post(ClientResponse.class);
 
+        String entity = response.getEntity(String.class);
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
+        
+        JsonNode node = JsonUtils.readTree(entity);
+        assertNotNull(node.at("/client_id").asText());
+        assertNotNull(node.at("/client_secret").asText());
     }
 }
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2EndpointTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2EndpointTest.java
index 4cf05dc..95d3d38 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2EndpointTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2EndpointTest.java
@@ -16,8 +16,8 @@
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.authentication.http.TransferEncoding;
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.TokenType;
 import de.ids_mannheim.korap.config.TestHelper;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.web.FastJerseyTest;
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/QuerySerializationControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/QuerySerializationControllerTest.java
index 138ca08..abd743b 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/QuerySerializationControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/QuerySerializationControllerTest.java
@@ -21,7 +21,7 @@
 
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.TokenType;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.web.FastJerseyTest;
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/ResourceControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/ResourceControllerTest.java
index ef47198..6a0bb64 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/ResourceControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/ResourceControllerTest.java
@@ -19,7 +19,7 @@
 
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.TokenType;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.handlers.ResourceDao;
 import de.ids_mannheim.korap.resources.KustvaktResource;
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/ResourceInfoControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/ResourceInfoControllerTest.java
index 2a43ec4..e96e523 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/ResourceInfoControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/ResourceInfoControllerTest.java
@@ -14,7 +14,7 @@
 
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.TokenType;
+import de.ids_mannheim.korap.constant.TokenType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.web.FastJerseyTest;
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java
index 7ef7361..956ae6e 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java
@@ -29,8 +29,8 @@
 
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.AuthenticationScheme;
 import de.ids_mannheim.korap.config.SpringJerseyTest;
+import de.ids_mannheim.korap.constant.AuthenticationScheme;
 import de.ids_mannheim.korap.constant.VirtualCorpusType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;