diff --git a/logs/audit.log b/logs/audit.log
deleted file mode 100644
index 591c4a4..0000000
--- a/logs/audit.log
+++ /dev/null
@@ -1,48 +0,0 @@
-SERVICE AUDIT : 
-MichaelHanl@Tue Aug 11 15:50:35 CEST 2015
-Status 105; Args None; 
-SERVICE AUDIT : 
-MichaelHanl@Tue Aug 11 15:50:35 CEST 2015
-Status 105; Args None; 
-SERVICE AUDIT : 
-MichaelHanl@Tue Aug 11 15:50:35 CEST 2015
-Status 105; Args None; 
-SERVICE AUDIT : 
-MichaelHanl@Tue Aug 11 15:50:35 CEST 2015
-Status 105; Args None; 
-SERVICE AUDIT : 
-MichaelHanl@Tue Aug 11 15:50:35 CEST 2015
-Status 105; Args None; 
-SERVICE AUDIT : 
-MichaelHanl@Tue Aug 11 15:50:35 CEST 2015
-Status 105; Args None; 
-SERVICE AUDIT : 
-MichaelHanl@Tue Aug 11 15:50:35 CEST 2015
-Status 105; Args None; 
-SERVICE AUDIT : 
-MichaelHanl@Tue Aug 11 15:50:35 CEST 2015
-Status 105; Args None; 
-SERVICE AUDIT : 
-MichaelHanl@Tue Aug 11 15:50:35 CEST 2015
-Status 105; Args None; 
-SERVICE AUDIT : 
-MichaelHanl@Tue Aug 11 15:50:35 CEST 2015
-Status 105; Args None; 
-SERVICE AUDIT : 
-MichaelHanl@Tue Aug 11 15:50:35 CEST 2015
-Status 105; Args None; 
-SERVICE AUDIT : 
-MichaelHanl@Tue Aug 11 15:50:35 CEST 2015
-Status 105; Args None; 
-SERVICE AUDIT : 
-MichaelHanl@Tue Aug 11 15:50:35 CEST 2015
-Status 105; Args None; 
-SERVICE AUDIT : 
-MichaelHanl@Tue Aug 11 15:50:35 CEST 2015
-Status 105; Args None; 
-SERVICE AUDIT : 
-MichaelHanl@Tue Aug 11 15:50:35 CEST 2015
-Status 105; Args None; 
-SERVICE AUDIT : 
-MichaelHanl@Tue Aug 11 15:50:35 CEST 2015
-Status 105; Args None; 
diff --git a/logs/default_audit.log b/logs/default_audit.log
deleted file mode 100644
index e69de29..0000000
--- a/logs/default_audit.log
+++ /dev/null
diff --git a/src/main/java/de/ids_mannheim/korap/config/JWTSigner.java b/src/main/java/de/ids_mannheim/korap/config/JWTSigner.java
new file mode 100644
index 0000000..be9e9ce
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/config/JWTSigner.java
@@ -0,0 +1,170 @@
+package de.ids_mannheim.korap.config;
+
+import com.nimbusds.jose.*;
+import com.nimbusds.jose.crypto.MACSigner;
+import com.nimbusds.jose.crypto.MACVerifier;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.SignedJWT;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.user.Attributes;
+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;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.ParseException;
+import java.util.Map;
+
+/**
+ * @author hanl
+ * @date 19/05/2014
+ */
+public class JWTSigner {
+
+    private URL issuer;
+    private JWSSigner signer;
+    private JWSVerifier verifier;
+    private final int defaultttl;
+
+    public JWTSigner(final byte[] secret, URL issuer, final int defaultttl) {
+        this.issuer = issuer;
+        this.signer = new MACSigner(secret);
+        this.verifier = new MACVerifier(secret);
+        this.defaultttl = defaultttl;
+    }
+
+    public JWTSigner(final byte[] secret, String issuer)
+            throws MalformedURLException {
+        this(secret, new URL(issuer), 72 * 60 * 60);
+    }
+
+    public SignedJWT createJWT(User user, Map<String, Object> attr) {
+        return signContent(user, attr, defaultttl);
+    }
+
+    public SignedJWT signContent(User user, Map<String, Object> attr, int ttl) {
+        String scopes;
+
+        JWTClaimsSet cs = new JWTClaimsSet();
+        cs.setIssuerClaim(this.issuer.toString());
+
+        if ((scopes = (String) attr.get(Attributes.SCOPES)) != null) {
+            Map<String, Object> claims = Scopes
+                    .mapOpenIDConnectScopes(scopes, user.getDetails());
+            cs.setCustomClaims(claims);
+            cs.setCustomClaim(Attributes.SCOPES,
+                    ((String) attr.get(Attributes.SCOPES)).toLowerCase());
+        }
+
+        cs.setSubjectClaim(user.getUsername());
+        if (attr.get(Attributes.CLIENT_ID) != null)
+            cs.setAudienceClaim(
+                    new String[] { (String) attr.get(Attributes.CLIENT_ID) });
+        cs.setExpirationTimeClaim(
+                TimeUtils.getNow().plusSeconds(ttl).getMillis());
+        SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.HS256),
+                cs);
+        try {
+            signedJWT.sign(signer);
+        }catch (JOSEException e) {
+            return null;
+        }
+        return signedJWT;
+    }
+
+    /**
+     * @param username
+     * @param json
+     * @return
+     */
+    public SignedJWT signContent(String username, String userclient,
+            String json, int ttl) {
+        JWTClaimsSet cs = new JWTClaimsSet();
+        cs.setSubjectClaim(username);
+        if (!json.isEmpty())
+            cs.setCustomClaim("data", json);
+        cs.setExpirationTimeClaim(
+                TimeUtils.getNow().plusSeconds(ttl).getMillis());
+        cs.setIssuerClaim(this.issuer.toString());
+
+        if (!userclient.isEmpty())
+            cs.setCustomClaim("userip", userclient);
+
+        SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.HS256),
+                cs);
+        try {
+            signedJWT.sign(signer);
+        }catch (JOSEException e) {
+            return null;
+        }
+        return signedJWT;
+    }
+
+    public SignedJWT signContent(String username, String userclient,
+            String json) {
+        return signContent(username, userclient, json, defaultttl);
+    }
+
+    public SignedJWT createSignedToken(String username) {
+        return createSignedToken(username, defaultttl);
+    }
+
+    // add client info
+    public SignedJWT createSignedToken(String username, int ttl) {
+        return signContent(username, "", "", ttl);
+    }
+
+    private SignedJWT verifyToken(String token) throws KustvaktException {
+        SignedJWT client;
+        try {
+            client = SignedJWT.parse(token);
+            if (!client.verify(verifier))
+                throw new KustvaktException(StatusCodes.REQUEST_INVALID);
+
+            if (!new DateTime(client.getJWTClaimsSet().getExpirationTimeClaim())
+                    .isAfterNow())
+                throw new KustvaktException(StatusCodes.EXPIRED,
+                        "authentication token is expired", token);
+        }catch (ParseException | JOSEException e) {
+            //todo: message or entity, how to treat??!
+            throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT,
+                    "token could not be verified", token);
+        }
+        return client;
+    }
+
+    // does not care about expiration times
+    public String retrieveContent(String signedContent) throws
+            KustvaktException {
+        SignedJWT jwt;
+        try {
+            jwt = SignedJWT.parse(signedContent);
+            if (!jwt.verify(verifier))
+                throw new KustvaktException(StatusCodes.REQUEST_INVALID,
+                        "token invalid", signedContent);
+            return (String) jwt.getJWTClaimsSet().getCustomClaim("data");
+        }catch (ParseException | JOSEException e) {
+            return null;
+        }
+    }
+
+    public TokenContext getTokenContext(String idtoken)
+            throws ParseException, JOSEException, KustvaktException {
+        SignedJWT signedJWT = verifyToken(idtoken);
+
+        TokenContext c = new TokenContext(
+                signedJWT.getJWTClaimsSet().getSubjectClaim());
+        if (signedJWT.getJWTClaimsSet().getAudienceClaim() != null)
+            c.addContextParameter(Attributes.CLIENT_ID,
+                    signedJWT.getJWTClaimsSet().getAudienceClaim()[0]);
+        c.setExpirationTime(
+                signedJWT.getJWTClaimsSet().getExpirationTimeClaim());
+        c.setToken(idtoken);
+        c.setParameters(signedJWT.getJWTClaimsSet().getCustomClaims());
+        return c;
+    }
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/config/URIParam.java b/src/main/java/de/ids_mannheim/korap/config/URIParam.java
new file mode 100644
index 0000000..3ab3724
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/config/URIParam.java
@@ -0,0 +1,26 @@
+package de.ids_mannheim.korap.config;
+
+import lombok.Getter;
+
+/**
+ * @author hanl
+ * @date 15/07/15
+ */
+@Getter
+public class URIParam extends ParamFields.Param {
+
+    private final String uriFragment;
+    private final Long uriExpiration;
+
+    public URIParam(String uri, Long expire) {
+        this.uriFragment = uri;
+        this.uriExpiration = expire;
+    }
+
+    @Override
+    public boolean hasValues() {
+        return this.uriFragment != null && !this.uriFragment.isEmpty()
+                && this.uriExpiration != null;
+    }
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/APIAuthentication.java b/src/main/java/de/ids_mannheim/korap/security/auth/APIAuthentication.java
new file mode 100644
index 0000000..df9f1b8
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/APIAuthentication.java
@@ -0,0 +1,86 @@
+package de.ids_mannheim.korap.security.auth;
+
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jwt.SignedJWT;
+import de.ids_mannheim.korap.config.JWTSigner;
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
+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.Attributes;
+import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.utils.StringUtils;
+import lombok.AccessLevel;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Element;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+
+import java.text.ParseException;
+import java.util.Map;
+
+/**
+ * Created by hanl on 5/23/14.
+ */
+public class APIAuthentication implements AuthenticationIface {
+
+    private JWTSigner signedToken;
+
+    public APIAuthentication(KustvaktConfiguration bconfig) {
+        KustvaktConfiguration config = bconfig;
+        this.signedToken = new JWTSigner(config.getSharedSecret(),
+                config.getIssuer(), config.getTokenTTL());
+    }
+
+    @Cacheable(value = "id_tokens", key = "#authToken")
+    @Override
+    public TokenContext getUserStatus(String authToken)
+            throws KustvaktException {
+        try {
+            authToken = StringUtils.stripTokenType(authToken);
+            TokenContext c = signedToken.getTokenContext(authToken);
+            c.setTokenType(Attributes.API_AUTHENTICATION);
+            return c;
+        }catch (JOSEException | ParseException e) {
+            throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT);
+        }
+    }
+
+    @Override
+    public TokenContext createUserSession(User user, Map<String, Object> attr)
+            throws KustvaktException {
+        TokenContext c = new TokenContext(user.getUsername());
+        SignedJWT jwt = signedToken.createJWT(user, attr);
+        try {
+            c.setExpirationTime(jwt.getJWTClaimsSet().getExpirationTimeClaim());
+        }catch (ParseException e) {
+            throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT);
+        }
+        c.setTokenType(Attributes.API_AUTHENTICATION);
+        c.setToken(jwt.serialize());
+        CacheManager.getInstance().getCache("id_tokens")
+                .put(new Element(c.getToken(), c));
+
+        return c;
+    }
+
+    // todo: cache and set expiration to token expiration. if token in that cache, it is not to be used anymore!
+    @CacheEvict(value = "id_tokens", key = "#token")
+    @Override
+    public void removeUserSession(String token) throws KustvaktException {
+        // invalidate token!
+    }
+
+    @Override
+    public TokenContext refresh(TokenContext context) throws KustvaktException {
+        return null;
+    }
+
+
+    @Override
+    public String getIdentifier() {
+        return Attributes.API_AUTHENTICATION;
+    }
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/BasicHttpAuth.java b/src/main/java/de/ids_mannheim/korap/security/auth/BasicHttpAuth.java
new file mode 100644
index 0000000..07e8ace
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/BasicHttpAuth.java
@@ -0,0 +1,75 @@
+package de.ids_mannheim.korap.security.auth;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.interfaces.AuthenticationIface;
+import de.ids_mannheim.korap.user.Attributes;
+import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.utils.StringUtils;
+import org.apache.commons.codec.binary.Base64;
+
+import java.util.Map;
+
+/**
+ * @author hanl
+ * @date 28/04/2015
+ */
+public class BasicHttpAuth implements AuthenticationIface {
+
+    public static String[] decode(String token) {
+        if (StringUtils.getTokenType(token)
+                .equals(Attributes.BASIC_AUTHENTICATION)) {
+            token = StringUtils.stripTokenType(token);
+            String[] sp = new String(Base64.decodeBase64(token)).split(":", 2);
+            sp[0].replaceAll(" ", "");
+            sp[1].replaceAll(" ", "");
+            return sp;
+        }
+        return null;
+    }
+
+    public static String encode(String user, String pass) {
+        String s = user + ":" + pass;
+        return new String(Base64.encodeBase64(s.getBytes()));
+    }
+
+    @Override
+    public TokenContext getUserStatus(String authToken) throws
+            KustvaktException {
+        authToken = StringUtils.stripTokenType(authToken);
+        String[] values = decode(authToken);
+        if (values != null) {
+            TokenContext c = new TokenContext(values[0]);
+            c.setTokenType(Attributes.BASIC_AUTHENTICATION);
+            c.setSecureRequired(true);
+            c.setToken(authToken);
+            //            fixme: you can make queries, but user sensitive data is off limits?!
+            //            c.addContextParameter(Attributes.SCOPES,
+            //                    Scopes.Scope.search.toString());
+            return c;
+        }
+        return null;
+    }
+
+    // not supported!
+    @Override
+    public TokenContext createUserSession(User user, Map<String, Object> attr)
+            throws KustvaktException {
+        return null;
+    }
+
+    @Override
+    public void removeUserSession(String token) throws KustvaktException {
+    }
+
+    @Override
+    public TokenContext refresh(TokenContext context) throws KustvaktException {
+        return null;
+    }
+
+
+    @Override
+    public String getIdentifier() {
+        return Attributes.BASIC_AUTHENTICATION;
+    }
+}
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java b/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java
new file mode 100644
index 0000000..a703e39
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java
@@ -0,0 +1,691 @@
+package de.ids_mannheim.korap.security.auth;
+
+import de.ids_mannheim.korap.auditing.AuditRecord;
+import de.ids_mannheim.korap.config.BeanConfiguration;
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.config.URIParam;
+import de.ids_mannheim.korap.exceptions.*;
+import de.ids_mannheim.korap.interfaces.*;
+import de.ids_mannheim.korap.user.*;
+import de.ids_mannheim.korap.utils.KustvaktLogger;
+import de.ids_mannheim.korap.utils.StringUtils;
+import de.ids_mannheim.korap.utils.TimeUtils;
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Element;
+import org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.springframework.cache.annotation.CachePut;
+
+import java.io.UnsupportedEncodingException;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * contains the logic to authentication and registration processes. Uses
+ * interface implementations (AuthenticationIface) for different databases and handlers
+ *
+ * @author hanl
+ */
+public class KustvaktAuthenticationManager extends AuthenticationManagerIface {
+
+    private static String KEY = "kustvakt:key";
+    private static Logger jlog = KustvaktLogger
+            .initiate(KustvaktAuthenticationManager.class);
+    private EncryptionIface crypto;
+    private EntityHandlerIface entHandler;
+    private AuditingIface auditing;
+    private final LoginCounter counter;
+    private Cache user_cache;
+
+    public KustvaktAuthenticationManager(EntityHandlerIface userdb,
+            EncryptionIface crypto, KustvaktConfiguration config,
+            AuditingIface auditer) {
+        this.entHandler = userdb;
+        this.crypto = crypto;
+        this.auditing = auditer;
+        this.counter = new LoginCounter(config);
+        this.user_cache = CacheManager.getInstance().getCache("users");
+    }
+
+    /**
+     * get session object if token was a session token
+     *
+     * @param token
+     * @param host
+     * @param useragent
+     * @return
+     * @throws KustvaktException
+     */
+    public TokenContext getTokenStatus(String token, String host,
+            String useragent) throws KustvaktException {
+        jlog.info("getting session status of token '{}'", token);
+        AuthenticationIface provider = getProvider(
+                StringUtils.getTokenType(token));
+        TokenContext context = provider.getUserStatus(token);
+        if (!matchStatus(host, useragent, context))
+            provider.removeUserSession(token);
+        return context;
+    }
+
+    public User getUser(String username) throws KustvaktException {
+        User user;
+        String key = cache_key(username);
+        Element e = user_cache.get(key);
+
+        if (e != null) {
+            Map map = (Map) e.getObjectValue();
+            user = User.UserFactory.toUser(map);
+        }else {
+            try {
+                user = entHandler.getAccount(username);
+                user_cache.put(new Element(key, user.toCache()));
+                // todo: not valid. for the duration of the session, the host should not change!
+            }catch (EmptyResultException e1) {
+                // do nothing
+                return null;
+            }
+        }
+        //todo:
+        //        user.addField(Attributes.HOST, context.getHostAddress());
+        //        user.addField(Attributes.USER_AGENT, context.getUserAgent());
+        return user;
+    }
+
+    public TokenContext refresh(TokenContext context) throws KustvaktException {
+        AuthenticationIface provider = getProvider(context.getTokenType());
+        try {
+            provider.removeUserSession(context.getToken());
+            User user = getUser(context.getUsername());
+            return provider.createUserSession(user, context.getParameters());
+        }catch (KustvaktException e) {
+            throw new WrappedException(e, StatusCodes.LOGIN_FAILED);
+        }
+    }
+
+    /**
+     * @param type
+     * @param attributes contains username and password to authenticate the user.
+     *                   Depending of the authentication schema, may contain other values as well
+     * @return User
+     * @throws KustvaktException
+     */
+
+    public User authenticate(int type, String username, String password,
+            Map<String, Object> attributes) throws KustvaktException {
+        User user;
+        switch (type) {
+            case 1:
+                // todo:
+                user = authenticateShib(attributes);
+                break;
+            default:
+                user = authenticate(username, password, attributes);
+                break;
+        }
+        auditing.audit(AuditRecord
+                .serviceRecord(user.getId(), StatusCodes.LOGIN_SUCCESSFUL,
+                        user.toString()));
+        return user;
+    }
+
+    @CachePut(value = "users", key = "#user.getUsername()")
+    public TokenContext createTokenContext(User user, Map<String, Object> attr,
+            String provider_key) throws KustvaktException {
+        AuthenticationIface provider = getProvider(provider_key);
+
+        if (attr.get(Attributes.SCOPES) != null)
+            this.getUserDetails(user);
+
+        TokenContext context = provider.createUserSession(user, attr);
+        if (context == null)
+            throw new KustvaktException(StatusCodes.NOT_SUPPORTED);
+        context.setUserAgent((String) attr.get(Attributes.USER_AGENT));
+        context.setHostAddress(Attributes.HOST);
+        return context;
+    }
+
+    //todo: test
+    private boolean matchStatus(String host, String useragent,
+            TokenContext context) {
+        if (host.equals(context.getHostAddress())) {
+            if (useragent.equals(context.getUserAgent()))
+                return true;
+        }
+        return false;
+    }
+
+    private User authenticateShib(Map<String, Object> attributes)
+            throws KustvaktException {
+        // todo use persistent id, since eppn is not unique
+        String eppn = (String) attributes.get(Attributes.EPPN);
+
+        if (eppn == null || eppn.isEmpty())
+            throw new KustvaktException(StatusCodes.REQUEST_INVALID);
+
+        if (!attributes.containsKey(Attributes.EMAIL)
+                && crypto.validateEmail(eppn) != null)
+            attributes.put(Attributes.EMAIL, eppn);
+
+        // fixme?!
+        User user = isRegistered(eppn);
+        if (user == null)
+            user = createShibbUserAccount(attributes);
+        return user;
+    }
+
+    //todo: what if attributes null?
+    private User authenticate(String username, String password,
+            Map<String, Object> attr) throws KustvaktException {
+        Map<String, Object> attributes = crypto.validateMap(attr);
+        String uPassword, safeUS;
+        User unknown;
+        // just to make sure that the plain password does not appear anywhere in the logs!
+
+        try {
+            safeUS = crypto.validateString(username);
+        }catch (KustvaktException e) {
+            throw new WrappedException(e, StatusCodes.LOGIN_FAILED, username);
+        }
+
+        if (safeUS == null || safeUS.isEmpty())
+            throw new WrappedException(new KustvaktException(username,
+                    StatusCodes.BAD_CREDENTIALS), StatusCodes.LOGIN_FAILED);
+        else {
+            try {
+                unknown = entHandler.getAccount(safeUS);
+                unknown.setSettings(
+                        entHandler.getUserSettings(unknown.getId()));
+            }catch (EmptyResultException e) {
+                // mask exception to disable user guessing in possible attacks
+                throw new WrappedException(new KustvaktException(username,
+                        StatusCodes.BAD_CREDENTIALS), StatusCodes.LOGIN_FAILED,
+                        username);
+            }catch (KustvaktException e) {
+                throw new WrappedException(e, StatusCodes.LOGIN_FAILED,
+                        attributes.toString());
+            }
+        }
+        jlog.trace("Authentication: found user under name " + unknown
+                .getUsername());
+        if (unknown instanceof KorAPUser) {
+            if (password == null || password.isEmpty())
+                throw new WrappedException(
+                        new KustvaktException(unknown.getId(),
+                                StatusCodes.BAD_CREDENTIALS),
+                        StatusCodes.LOGIN_FAILED, username);
+
+            KorAPUser user = (KorAPUser) unknown;
+            boolean check = crypto.checkHash(password, user.getPassword());
+
+            if (!check) {
+                // the fail counter only applies for wrong password
+                jlog.warn("Wrong Password!");
+                processLoginFail(unknown);
+                throw new WrappedException(new KustvaktException(user.getId(),
+                        StatusCodes.BAD_CREDENTIALS), StatusCodes.LOGIN_FAILED,
+                        username);
+            }
+
+            // bad credentials error has presedence over account locked or unconfirmed codes
+            // since latter can lead to account guessing of third parties
+            if (user.isAccountLocked()) {
+                URIParam param = (URIParam) user.getField(URIParam.class);
+
+                if (param.hasValues()) {
+                    jlog.debug("Account is not yet activated for user '{}'",
+                            user.getUsername());
+                    if (TimeUtils.getNow().isAfter(param.getUriExpiration())) {
+                        KustvaktLogger.ERROR_LOGGER
+                                .error("URI token is expired. Deleting account for user {}",
+                                        user.getUsername());
+                        deleteAccount(user);
+                        throw new WrappedException(
+                                new KustvaktException(unknown.getId(),
+                                        StatusCodes.EXPIRED,
+                                        "account confirmation uri has expired",
+                                        param.getUriFragment()),
+                                StatusCodes.LOGIN_FAILED, username);
+                    }
+                    throw new WrappedException(
+                            new KustvaktException(unknown.getId(),
+                                    StatusCodes.UNCONFIRMED_ACCOUNT),
+                            StatusCodes.LOGIN_FAILED, username);
+                }
+                KustvaktLogger.ERROR_LOGGER
+                        .error("ACCESS DENIED: account not active for '{}'",
+                                unknown.getUsername());
+                throw new WrappedException(
+                        new KustvaktException(unknown.getId(),
+                                StatusCodes.ACCOUNT_DEACTIVATED),
+                        StatusCodes.LOGIN_FAILED, username);
+            }
+
+        }else if (unknown instanceof ShibUser) {
+            //todo
+        }
+        jlog.debug("Authentication done: " + safeUS);
+        return unknown;
+    }
+
+    public User isRegistered(String username) throws KustvaktException {
+        User user;
+        if (username == null || username.isEmpty())
+            throw new KustvaktException(username, StatusCodes.ILLEGAL_ARGUMENT,
+                    "username must be set", username);
+
+        try {
+            user = entHandler.getAccount(username);
+        }catch (EmptyResultException e) {
+            jlog.debug("user does not exist ({})", username);
+            return null;
+
+        }catch (KustvaktException e) {
+            KustvaktLogger.ERROR_LOGGER.error("KorAPException", e);
+            throw new KustvaktException(username, StatusCodes.ILLEGAL_ARGUMENT,
+                    "username invalid", username);
+        }
+        return user;
+    }
+
+    public void logout(TokenContext context) throws KustvaktException {
+        String key = cache_key(context.getUsername());
+        try {
+            AuthenticationIface provider = getProvider(context.getTokenType());
+            provider.removeUserSession(context.getToken());
+        }catch (KustvaktException e) {
+            throw new WrappedException(e, StatusCodes.LOGOUT_FAILED,
+                    context.toString());
+        }
+        auditing.audit(AuditRecord.serviceRecord(context.getUsername(),
+                StatusCodes.LOGOUT_SUCCESSFUL, context.toString()));
+        user_cache.remove(key);
+    }
+
+    private void processLoginFail(User user) throws KustvaktException {
+        counter.registerFail(user.getUsername());
+        if (!counter.validate(user.getUsername())) {
+            try {
+                this.lockAccount(user);
+            }catch (KustvaktException e) {
+                KustvaktLogger.ERROR_LOGGER
+                        .error("user account could not be locked!", e);
+                throw new WrappedException(e,
+                        StatusCodes.UPDATE_ACCOUNT_FAILED);
+            }
+            throw new WrappedException(new KustvaktException(user.getId(),
+                    StatusCodes.ACCOUNT_DEACTIVATED), StatusCodes.LOGIN_FAILED);
+        }
+    }
+
+    public void lockAccount(User user) throws KustvaktException {
+        if (!(user instanceof KorAPUser))
+            throw new KustvaktException(StatusCodes.REQUEST_INVALID);
+
+        KorAPUser u = (KorAPUser) user;
+        u.setAccountLocked(true);
+        jlog.info("locking account for user: {}", user.getUsername());
+        entHandler.updateAccount(u);
+    }
+
+    public KorAPUser checkPasswordAllowance(KorAPUser user, String oldPassword,
+            String newPassword) throws KustvaktException {
+        String dbPassword = user.getPassword();
+
+        if (oldPassword.trim().equals(newPassword.trim())) {
+            // TODO: special error StatusCodes for this?
+            throw new WrappedException(new KustvaktException(user.getId(),
+                    StatusCodes.ILLEGAL_ARGUMENT),
+                    StatusCodes.PASSWORD_RESET_FAILED, newPassword);
+        }
+
+        boolean check = crypto.checkHash(oldPassword, dbPassword);
+
+        if (!check)
+            throw new WrappedException(new KustvaktException(user.getId(),
+                    StatusCodes.BAD_CREDENTIALS),
+                    StatusCodes.PASSWORD_RESET_FAILED);
+
+        try {
+            user.setPassword(crypto.produceSecureHash(newPassword));
+        }catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
+            //            throw new KorAPException(StatusCodes.ILLEGAL_ARGUMENT,
+            //                    "Creating password hash failed!", "password");
+            throw new WrappedException(new KustvaktException(user.getId(),
+                    StatusCodes.ILLEGAL_ARGUMENT, "password invalid",
+                    newPassword), StatusCodes.PASSWORD_RESET_FAILED,
+                    user.toString(), newPassword);
+        }
+        return user;
+    }
+
+    //fixme: use clientinfo for logging/auditing?! = from where did he access the reset function?
+    @Override
+    public void resetPassword(String uriFragment, String username,
+            String newPassphrase) throws KustvaktException {
+        String safeUser, safePass;
+
+        try {
+            safeUser = crypto.validateString(username);
+            safePass = crypto.validatePassphrase(newPassphrase);
+        }catch (KustvaktException e) {
+            KustvaktLogger.ERROR_LOGGER.error("Error", e);
+            throw new WrappedException(new KustvaktException(username,
+                    StatusCodes.ILLEGAL_ARGUMENT, "password invalid",
+                    newPassphrase), StatusCodes.PASSWORD_RESET_FAILED, username,
+                    newPassphrase);
+        }
+
+        try {
+            safePass = crypto.produceSecureHash(safePass);
+        }catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
+            KustvaktLogger.ERROR_LOGGER.error("Encoding/Algorithm Error", e);
+            throw new WrappedException(new KustvaktException(username,
+                    StatusCodes.ILLEGAL_ARGUMENT, "password invalid",
+                    newPassphrase), StatusCodes.PASSWORD_RESET_FAILED, username,
+                    uriFragment, newPassphrase);
+        }
+        int result = entHandler
+                .resetPassphrase(safeUser, uriFragment, safePass);
+
+        if (result == 0)
+            throw new WrappedException(
+                    new KustvaktException(username, StatusCodes.EXPIRED,
+                            "URI fragment expired", uriFragment),
+                    StatusCodes.PASSWORD_RESET_FAILED, username, uriFragment);
+        else if (result == 1)
+            jlog.info("successfully reset password for user {}", safeUser);
+    }
+
+    public void confirmRegistration(String uriFragment, String username)
+            throws KustvaktException {
+        String safeUser;
+        try {
+            safeUser = crypto.validateString(username);
+        }catch (KustvaktException e) {
+            KustvaktLogger.ERROR_LOGGER.error("error", e);
+            throw new WrappedException(e,
+                    StatusCodes.ACCOUNT_CONFIRMATION_FAILED, username,
+                    uriFragment);
+        }
+        int r = entHandler.activateAccount(safeUser, uriFragment);
+        if (r == 0) {
+            User user;
+            try {
+                user = entHandler.getAccount(username);
+            }catch (EmptyResultException e) {
+                throw new WrappedException(new KustvaktException(username,
+                        StatusCodes.BAD_CREDENTIALS),
+                        StatusCodes.ACCOUNT_CONFIRMATION_FAILED, username,
+                        uriFragment);
+            }
+            entHandler.deleteAccount(user.getId());
+            throw new WrappedException(
+                    new KustvaktException(user.getId(), StatusCodes.EXPIRED),
+                    StatusCodes.ACCOUNT_CONFIRMATION_FAILED, username,
+                    uriFragment);
+        }else if (r == 1)
+            jlog.info("successfully confirmed user registration for user {}",
+                    safeUser);
+        // register successful audit!
+    }
+
+    /**
+     * @param attributes
+     * @return
+     * @throws KustvaktException
+     */
+    //fixme: remove clientinfo object (not needed), use json representation to get stuff
+    public User createUserAccount(Map<String, Object> attributes)
+            throws KustvaktException {
+        Map<String, Object> safeMap = crypto.validateMap(attributes);
+        if (safeMap.get(Attributes.USERNAME) == null || ((String) safeMap
+                .get(Attributes.USERNAME)).isEmpty())
+            throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT,
+                    "username must be set", "username");
+        if (safeMap.get(Attributes.PASSWORD) == null || ((String) safeMap
+                .get(Attributes.PASSWORD)).isEmpty())
+            throw new KustvaktException(safeMap.get(Attributes.USERNAME),
+                    StatusCodes.ILLEGAL_ARGUMENT, "password must be set",
+                    "password");
+
+        String safePass = crypto
+                .validatePassphrase((String) safeMap.get(Attributes.PASSWORD));
+        String hash;
+        try {
+            hash = crypto.produceSecureHash(safePass);
+        }catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
+            KustvaktLogger.ERROR_LOGGER.error("Encryption error", e);
+            throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT);
+        }
+
+        KorAPUser user = User.UserFactory
+                .getUser((String) safeMap.get(Attributes.USERNAME));
+        UserDetails det = UserDetails.newDetailsIterator(safeMap);
+        user.setDetails(det);
+        user.setSettings(new UserSettings());
+        user.setAccountLocked(true);
+        URIParam param = new URIParam(crypto.createToken(), TimeUtils
+                .plusSeconds(BeanConfiguration.getBeans().getConfiguration()
+                        .getShortTokenTTL()).getMillis());
+        user.addField(param);
+        user.setPassword(hash);
+        try {
+            entHandler.createAccount(user);
+        }catch (KustvaktException e) {
+            throw new WrappedException(e, StatusCodes.CREATE_ACCOUNT_FAILED,
+                    user.toString());
+        }
+
+        auditing.audit(AuditRecord.serviceRecord(user.getUsername(),
+                StatusCodes.CREATE_ACCOUNT_SUCCESSFUL));
+        return user;
+    }
+
+    //todo:
+    private ShibUser createShibbUserAccount(Map<String, Object> attributes)
+            throws KustvaktException {
+        jlog.debug("creating shibboleth user account for user attr: {}",
+                attributes);
+        Map<String, Object> safeMap = crypto.validateMap(attributes);
+
+        //todo eppn non-unique.join with idp or use persistent_id as username identifier
+        ShibUser user = User.UserFactory
+                .getShibInstance((String) safeMap.get(Attributes.EPPN),
+                        (String) safeMap.get(Attributes.MAIL),
+                        (String) safeMap.get(Attributes.CN));
+        user.setAffiliation((String) safeMap.get(Attributes.EDU_AFFIL));
+        UserDetails det = UserDetails
+                .newDetailsIterator(new HashMap<String, Object>());
+        user.setDetails(det);
+        user.setSettings(new UserSettings());
+        user.setAccountCreation(TimeUtils.getNow().getMillis());
+        entHandler.createAccount(user);
+        return user;
+    }
+
+    /**
+     * link shibboleth and korap user account to one another.
+     *
+     * @param current    currently logged in user
+     * @param for_name   foreign user name the current account should be linked to
+     * @param transstrat transfer status of user data (details, settings, user queries)
+     *                   0 = the currently logged in data should be kept
+     *                   1 = the foreign account data should be kept
+     * @throws NotAuthorizedException
+     * @throws KustvaktException
+     */
+    // todo:
+    public void accountLink(User current, String for_name, int transstrat)
+            throws KustvaktException {
+        //        User foreign = entHandler.getAccount(for_name);
+
+        //        if (current.getAccountLink() == null && current.getAccountLink()
+        //                .isEmpty()) {
+        //            if (current instanceof KorAPUser && foreign instanceof ShibUser) {
+        //                if (transstrat == 1)
+        //                    current.transfer(foreign);
+        ////                foreign.setAccountLink(current.getUsername());
+        ////                current.setAccountLink(foreign.getUsername());
+        //                //                entHandler.purgeDetails(foreign);
+        //                //                entHandler.purgeSettings(foreign);
+        //            }else if (foreign instanceof KorAPUser
+        //                    && current instanceof ShibUser) {
+        //                if (transstrat == 0)
+        //                    foreign.transfer(current);
+        ////                current.setAccountLink(foreign.getUsername());
+        //                //                entHandler.purgeDetails(current);
+        //                //                entHandler.purgeSettings(current);
+        //                //                entHandler.purgeSettings(current);
+        //            }
+        //        entHandler.updateAccount(current);
+        //        entHandler.updateAccount(foreign);
+        //        }
+    }
+
+    @Override
+    public boolean updateAccount(User user) throws KustvaktException {
+        boolean result;
+        String key = cache_key(user.getUsername());
+        if (user instanceof DemoUser)
+            throw new KustvaktException(user.getId(),
+                    StatusCodes.REQUEST_INVALID,
+                    "account not updateable for demo user", user.getUsername());
+        else {
+            crypto.validate(user);
+            try {
+                result = entHandler.updateAccount(user) > 0;
+            }catch (KustvaktException e) {
+                KustvaktLogger.ERROR_LOGGER.error("Error ", e);
+                throw new WrappedException(e,
+                        StatusCodes.UPDATE_ACCOUNT_FAILED);
+            }
+        }
+        if (result) {
+            user_cache.remove(key);
+            auditing.audit(AuditRecord.serviceRecord(user.getId(),
+                    StatusCodes.UPDATE_ACCOUNT_SUCCESSFUL, user.toString()));
+        }
+        return result;
+    }
+
+    public boolean deleteAccount(User user) throws KustvaktException {
+        boolean result;
+        String key = cache_key(user.getUsername());
+        if (user instanceof DemoUser)
+            return true;
+        else {
+            try {
+                result = entHandler.deleteAccount(user.getId()) > 0;
+            }catch (KustvaktException e) {
+                KustvaktLogger.ERROR_LOGGER.error("Error ", e);
+                throw new WrappedException(e,
+                        StatusCodes.DELETE_ACCOUNT_FAILED);
+            }
+        }
+        if (result) {
+            user_cache.remove(key);
+            auditing.audit(AuditRecord.serviceRecord(user.getUsername(),
+                    StatusCodes.DELETE_ACCOUNT_SUCCESSFUL, user.toString()));
+        }
+        return result;
+    }
+
+    public Object[] validateResetPasswordRequest(String username, String email)
+            throws KustvaktException {
+        String mail, uritoken;
+        mail = crypto.validateEmail(email);
+        User ident;
+        try {
+            ident = entHandler.getAccount(username);
+            if (ident instanceof DemoUser)
+                //            throw new NotAuthorizedException(StatusCodes.PERMISSION_DENIED,
+                //                    "password reset now allowed for DemoUser", "");
+                throw new WrappedException(username,
+                        StatusCodes.PASSWORD_RESET_FAILED, username);
+        }catch (EmptyResultException e) {
+            throw new WrappedException(new KustvaktException(username,
+                    StatusCodes.ILLEGAL_ARGUMENT, "username not found",
+                    username), StatusCodes.PASSWORD_RESET_FAILED, username);
+        }
+
+        getUserDetails(ident);
+        KorAPUser user = (KorAPUser) ident;
+        if (!mail.equals(user.getDetails().getEmail()))
+            //            throw new NotAuthorizedException(StatusCodes.ILLEGAL_ARGUMENT,
+            //                    "invalid parameter: email", "email");
+            throw new WrappedException(new KustvaktException(user.getId(),
+                    StatusCodes.ILLEGAL_ARGUMENT, "email invalid", email),
+                    StatusCodes.PASSWORD_RESET_FAILED, email);
+        uritoken = crypto.encodeBase();
+        URIParam param = new URIParam(uritoken,
+                TimeUtils.plusHours(24).getMillis());
+        user.addField(param);
+
+        try {
+            entHandler.updateAccount(user);
+        }catch (KustvaktException e) {
+            KustvaktLogger.ERROR_LOGGER.error("Error ", e);
+            throw new WrappedException(e, StatusCodes.PASSWORD_RESET_FAILED);
+        }
+        return new Object[] { uritoken,
+                new DateTime(param.getUriExpiration()) };
+    }
+
+    public void updateUserSettings(User user, UserSettings settings)
+            throws KustvaktException {
+        if (user instanceof DemoUser)
+            return;
+        else {
+            crypto.validate(settings);
+            try {
+                entHandler.updateSettings(settings);
+            }catch (KustvaktException e) {
+                KustvaktLogger.ERROR_LOGGER.error("Error ", e);
+                throw new WrappedException(e,
+                        StatusCodes.UPDATE_ACCOUNT_FAILED);
+            }
+        }
+    }
+
+    public void updateUserDetails(User user, UserDetails details)
+            throws KustvaktException {
+        if (user instanceof DemoUser)
+            return;
+        else {
+            crypto.validate(details);
+            try {
+                entHandler.updateUserDetails(details);
+            }catch (KustvaktException e) {
+                KustvaktLogger.ERROR_LOGGER.error("Error ", e);
+                throw new WrappedException(e,
+                        StatusCodes.UPDATE_ACCOUNT_FAILED);
+            }
+        }
+    }
+
+    public UserDetails getUserDetails(User user) throws KustvaktException {
+        try {
+            if (user.getDetails() == null)
+                user.setDetails(entHandler.getUserDetails(user.getId()));
+        }catch (KustvaktException e) {
+            throw new WrappedException(e, StatusCodes.GET_ACCOUNT_FAILED);
+        }
+        return user.getDetails();
+    }
+
+    public UserSettings getUserSettings(User user) throws KustvaktException {
+        try {
+            if (user.getSettings() == null)
+                user.setSettings(entHandler.getUserSettings(user.getId()));
+        }catch (KustvaktException e) {
+            throw new WrappedException(e, StatusCodes.GET_ACCOUNT_FAILED);
+        }
+        return user.getSettings();
+    }
+
+    private String cache_key(String input) {
+        return crypto.hash(KEY + "@" + input);
+    }
+}
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/LoginCounter.java b/src/main/java/de/ids_mannheim/korap/security/auth/LoginCounter.java
new file mode 100644
index 0000000..c38bc02
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/LoginCounter.java
@@ -0,0 +1,62 @@
+package de.ids_mannheim.korap.security.auth;
+
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.utils.KustvaktLogger;
+import de.ids_mannheim.korap.utils.TimeUtils;
+import org.slf4j.Logger;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author hanl
+ * @date 11/11/2014
+ */
+public class LoginCounter {
+
+    private static Logger jlog = KustvaktLogger.initiate(LoginCounter.class);
+    private final Map<String, Long[]> failedLogins;
+    private KustvaktConfiguration config;
+
+    public LoginCounter(KustvaktConfiguration config) {
+        jlog.debug("init login counter for authentication management");
+        this.config = config;
+        this.failedLogins = new HashMap<>();
+    }
+
+    public void resetFailedCounter(String username) {
+        failedLogins.remove(username);
+    }
+
+    public void registerFail(String username) {
+        long expires = TimeUtils.plusSeconds(config.getLoginAttemptTTL())
+                .getMillis();
+        long fail = 1;
+        Long[] set = failedLogins.get(username);
+        if (set != null)
+            fail = set[0] + 1;
+        else
+            set = new Long[2];
+        set[0] = fail;
+        set[1] = expires;
+
+        failedLogins.put(username, set);
+        jlog.warn("user failed to login ({}) ",
+                Arrays.asList(failedLogins.get(username)));
+    }
+
+    public boolean validate(String username) {
+        Long[] set = failedLogins.get(username);
+        if (set != null) {
+            if (TimeUtils.isPassed(set[1])) {
+                failedLogins.remove(username);
+                return true;
+            }else if (set[0] < config.getLoginAttemptNum())
+                return true;
+            return false;
+        }
+        return true;
+    }
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/OpenIDconnectAuthentication.java b/src/main/java/de/ids_mannheim/korap/security/auth/OpenIDconnectAuthentication.java
new file mode 100644
index 0000000..cae5e2d
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/OpenIDconnectAuthentication.java
@@ -0,0 +1,81 @@
+package de.ids_mannheim.korap.security.auth;
+
+import com.nimbusds.jwt.SignedJWT;
+import de.ids_mannheim.korap.config.JWTSigner;
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
+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.PersistenceClient;
+import de.ids_mannheim.korap.user.Attributes;
+import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.utils.StringUtils;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Element;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+
+import java.text.ParseException;
+import java.util.Map;
+
+/**
+ * @author hanl
+ * @date 12/11/2014
+ */
+public class OpenIDconnectAuthentication implements AuthenticationIface {
+
+    private OAuthDb database;
+    private KustvaktConfiguration config;
+
+    public OpenIDconnectAuthentication(KustvaktConfiguration config,
+            PersistenceClient client) {
+        this.database = new OAuthDb(client);
+        this.config = config;
+    }
+
+    @Cacheable(value = "id_tokens", key = "#authToken")
+    @Override
+    public TokenContext getUserStatus(String authToken)
+            throws KustvaktException {
+        authToken = StringUtils.stripTokenType(authToken);
+        return this.database.getContext(authToken);
+    }
+
+    @Override
+    public TokenContext createUserSession(User user, Map<String, Object> attr)
+            throws KustvaktException {
+        JWTSigner signer = new JWTSigner(
+                ((String) attr.get(Attributes.CLIENT_SECRET)).getBytes(),
+                config.getIssuer(), config.getTokenTTL());
+        TokenContext c = new TokenContext(user.getUsername());
+        SignedJWT jwt = signer.createJWT(user, attr);
+        try {
+            c.setExpirationTime(jwt.getJWTClaimsSet().getExpirationTimeClaim());
+        }catch (ParseException e) {
+            throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT);
+        }
+        c.setTokenType(Attributes.OPENID_AUTHENTICATION);
+        c.setToken(jwt.serialize());
+        CacheManager.getInstance().getCache("id_tokens")
+                .put(new Element(c.getToken(), c));
+        return c;
+    }
+
+    @CacheEvict(value = "id_tokens", key = "#token")
+    @Override
+    public void removeUserSession(String token) throws KustvaktException {
+        // emit token from cache only
+    }
+
+    @Override
+    public TokenContext refresh(TokenContext context) throws KustvaktException {
+        throw new UnsupportedOperationException("method not supported");
+    }
+
+    @Override
+    public String getIdentifier() {
+        return Attributes.OPENID_AUTHENTICATION;
+    }
+}
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/SessionAuthentication.java b/src/main/java/de/ids_mannheim/korap/security/auth/SessionAuthentication.java
new file mode 100644
index 0000000..99ebd89
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/SessionAuthentication.java
@@ -0,0 +1,93 @@
+package de.ids_mannheim.korap.security.auth;
+
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
+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.user.Attributes;
+import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.utils.KustvaktLogger;
+import de.ids_mannheim.korap.utils.TimeUtils;
+import org.joda.time.DateTime;
+import org.slf4j.Logger;
+
+import java.util.Map;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * implementation of the AuthenticationIface to handle korap authentication
+ * internals
+ *
+ * @author hanl
+ */
+public class SessionAuthentication implements AuthenticationIface {
+
+    private static Logger jlog = KustvaktLogger
+            .initiate(SessionAuthentication.class);
+    private SessionFactory sessions;
+    private ScheduledThreadPoolExecutor scheduled;
+    private EncryptionIface crypto;
+    private KustvaktConfiguration config;
+
+    public SessionAuthentication(KustvaktConfiguration config,
+            EncryptionIface crypto) {
+        jlog.info("initialize session authentication handler");
+        this.crypto = crypto;
+        this.config = config;
+        this.scheduled = new ScheduledThreadPoolExecutor(1);
+        this.sessions = new SessionFactory(this.config.isAllowMultiLogIn(),
+                this.config.getInactiveTime());
+        this.scheduled.scheduleAtFixedRate(this.sessions,
+                this.config.getInactiveTime() / 2,
+                this.config.getInactiveTime(), TimeUnit.SECONDS);
+    }
+
+    @Override
+    public TokenContext getUserStatus(String authenticationToken)
+            throws KustvaktException {
+        jlog.debug("retrieving user session for user '{}'",
+                authenticationToken);
+        if (authenticationToken == null)
+            throw new KustvaktException(StatusCodes.PERMISSION_DENIED);
+        return this.sessions.getSession(authenticationToken);
+    }
+
+    @Override
+    public TokenContext createUserSession(User user, Map attr)
+            throws KustvaktException {
+        DateTime now = TimeUtils.getNow();
+        DateTime ex = TimeUtils
+                .getExpiration(now.getMillis(), config.getExpiration());
+        String token = crypto
+                .createToken(true, user.getUsername(), now.getMillis());
+        TokenContext ctx = new TokenContext(user.getUsername());
+        ctx.setUsername(user.getUsername());
+        ctx.setTokenType(Attributes.SESSION_AUTHENTICATION);
+        ctx.setToken(token);
+        ctx.setExpirationTime(ex.getMillis());
+        ctx.setHostAddress(attr.get(Attributes.HOST).toString());
+        ctx.setUserAgent(attr.get(Attributes.USER_AGENT).toString());
+        this.sessions.putSession(token, ctx);
+        jlog.info("create session for user: " + user.getUsername());
+        return ctx;
+    }
+
+    @Override
+    public void removeUserSession(String token) {
+        this.sessions.removeSession(token);
+    }
+
+    @Override
+    public TokenContext refresh(TokenContext context) throws KustvaktException {
+        throw new UnsupportedOperationException("method not supported");
+    }
+
+    @Override
+    public String getIdentifier() {
+        return Attributes.SESSION_AUTHENTICATION;
+    }
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/SessionFactory.java b/src/main/java/de/ids_mannheim/korap/security/auth/SessionFactory.java
new file mode 100644
index 0000000..26e316a
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/SessionFactory.java
@@ -0,0 +1,171 @@
+package de.ids_mannheim.korap.security.auth;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+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.KustvaktLogger;
+import de.ids_mannheim.korap.utils.TimeUtils;
+import org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+
+import java.util.HashSet;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * session object to hold current user sessions and track inactive time to close
+ * unused sessions. Inactive sessions are not enforced until user makes a
+ * request through thrift
+ *
+ * @author hanl
+ */
+public class SessionFactory implements Runnable {
+
+    private static Logger jlog = KustvaktLogger.initiate(SessionFactory.class);
+
+    private final ConcurrentMap<String, TokenContext> sessionsObject;
+    private final ConcurrentMap<String, DateTime> timeCheck;
+    private final ConcurrentMultiMap<String, String> loggedInRecord;
+    //    private final ConcurrentMultiMap<String, Long> failedLogins;
+    private final boolean multipleEnabled;
+    private final int inactive;
+
+    public SessionFactory(boolean multipleEnabled, int inactive) {
+        jlog.debug("allow multiple sessions per user: '{}'", multipleEnabled);
+        this.multipleEnabled = multipleEnabled;
+        this.inactive = inactive;
+        this.sessionsObject = new ConcurrentHashMap<>();
+        this.timeCheck = new ConcurrentHashMap<>();
+        this.loggedInRecord = new ConcurrentMultiMap<>();
+    }
+
+    public boolean hasSession(TokenContext context) {
+        if (context.getUsername().equalsIgnoreCase(DemoUser.DEMOUSER_NAME))
+            return false;
+        if (loggedInRecord.containsKey(context.getUsername()) && !loggedInRecord
+                .get(context.getUsername()).isEmpty())
+            return true;
+        return false;
+    }
+
+    @Cacheable("session")
+    public TokenContext getSession(String token) throws KustvaktException {
+        jlog.debug("logged in users: {}", loggedInRecord);
+        TokenContext context = sessionsObject.get(token);
+        if (context != null) {
+            if (isUserSessionValid(token)) {
+                resetInterval(token);
+                return context;
+            }else
+                throw new KustvaktException(StatusCodes.EXPIRED);
+
+        }else
+            throw new KustvaktException(StatusCodes.PERMISSION_DENIED);
+    }
+
+    //todo: ?!
+    @CacheEvict(value = "session", key = "#session.token")
+    public void putSession(final String token, final TokenContext activeUser)
+            throws KustvaktException {
+        if (!hasSession(activeUser) | multipleEnabled) {
+            loggedInRecord.put(activeUser.getUsername(), token);
+            sessionsObject.put(token, activeUser);
+            timeCheck.put(token, TimeUtils.getNow());
+        }else {
+            removeAll(activeUser);
+            throw new KustvaktException(StatusCodes.ALREADY_LOGGED_IN);
+        }
+    }
+
+    public void removeAll(final TokenContext activeUser) {
+        for (String existing : loggedInRecord.get(activeUser.getUsername())) {
+            timeCheck.remove(existing);
+            sessionsObject.remove(existing);
+        }
+        loggedInRecord.remove(activeUser.getUsername());
+    }
+
+    @CacheEvict(value = "session", key = "#session.token")
+    public void removeSession(String token) {
+        String username = sessionsObject.get(token).getUsername();
+        loggedInRecord.remove(username, token);
+        if (loggedInRecord.get(username).isEmpty())
+            loggedInRecord.remove(username);
+        timeCheck.remove(token);
+        sessionsObject.remove(token);
+    }
+
+    /**
+     * reset inactive time interval to 0
+     *
+     * @param token
+     */
+    private void resetInterval(String token) {
+        timeCheck.put(token, TimeUtils.getNow());
+    }
+
+    /**
+     * if user possesses a valid non-expired session token
+     *
+     * @param token
+     * @return validity of user to request a backend function
+     */
+    private boolean isUserSessionValid(String token) {
+        if (timeCheck.containsKey(token)) {
+            if (TimeUtils.plusSeconds(timeCheck.get(token).getMillis(),
+                    inactive).isAfterNow()) {
+                jlog.debug("user has session");
+                return true;
+            }else
+                jlog.debug("user with token {} has an invalid session", token);
+        }
+        return false;
+    }
+
+    /**
+     * clean inactive sessions from session object
+     * TODO: persist userdata to database when session times out!
+     */
+    private void timeoutMaintenance() {
+        jlog.debug("running session cleanup thread");
+        Set<String> inactive = new HashSet<>();
+        for (Entry<String, DateTime> entry : timeCheck.entrySet()) {
+            if (!isUserSessionValid(entry.getKey())) {
+                TokenContext user = sessionsObject.get(entry.getKey());
+                jlog.debug("removing user session for user {}",
+                        user.getUsername());
+                inactive.add(user.getUsername());
+                removeSession(entry.getKey());
+            }
+        }
+        if (inactive.size() > 0)
+            jlog.debug("removing inactive user session for users '{}' ",
+                    inactive);
+
+        //        keys:
+        //        for (String key : failedLogins.getKeySet()) {
+        //            DateTime d = new DateTime(failedLogins.get(key).get(1));
+        //            if (d.isBeforeNow()) {
+        //                failedLogins.remove(key);
+        //                jlog.info("removed failed login counts due to expiration for user {}", key);
+        //                continue keys;
+        //            }
+        //        }
+    }
+
+    /**
+     * run cleanup-thread
+     */
+    @Override
+    public void run() {
+        timeoutMaintenance();
+        jlog.debug("logged users: {}", loggedInRecord.toString());
+
+    }
+}
