From cced86e2524c0cba0c54d220446f120c732b4eee Mon Sep 17 00:00:00 2001
From: Joze RIHTARSIC <joze.RIHTARSIC@ext.ec.europa.eu>
Date: Mon, 9 May 2022 06:58:18 +0200
Subject: [PATCH] Fix regression issues for CAS

---
 .../tomcat-mysql-smp-sml/docker-compose.yml   |   1 +
 .../images/tomcat-mysql-smp-sml/Dockerfile    |   8 +-
 .../images/tomcat-mysql-smp-sml/entrypoint.sh |  10 +-
 smp-server-library/pom.xml                    |   5 +-
 .../smp/auth/SMPAuthenticationToken.java      |  45 +++--
 .../ec/edelivery/smp/auth/SMPUserDetails.java |  84 +++++++++
 .../smp/auth/UILoginAuthenticationToken.java  |  18 ++
 .../smp/config/PropertyInitialization.java    |  13 +-
 ...09CertificateToCertificateROConverter.java |   5 +-
 .../ec/edelivery/smp/data/ui/UserRO.java      |  29 +--
 .../smp/data/ui/auth/SMPAuthority.java        |  39 +++-
 .../ui/databind/SMPAuthorityDeserializer.java |   2 +-
 .../smp/data/ui/enums/SMPPropertyEnum.java    |   7 +-
 .../smp/services/CRLVerifierService.java      |   6 +-
 .../smp/services/ConfigurationService.java    |  12 +-
 .../smp/services/ui/UIKeystoreService.java    |  18 +-
 .../smp/services/ui/UITruststoreService.java  |  23 ++-
 .../smp/services/ui/UIUserService.java        |   9 +-
 .../smp/utils/SessionSecurityUtils.java       |  77 +++++++-
 .../smp/utils/X509CertificateUtils.java       | 175 ------------------
 .../smp/utils/SessionSecurityUtilsTest.java   | 124 +++++++++++++
 .../smp/utils/X509CertificateUtilsTest.java   |   7 +-
 smp-webapp/pom.xml                            |   4 -
 .../smp/auth/SMPAuthenticationProvider.java   |  56 ++++--
 .../auth/SMPAuthenticationProviderForUI.java  |  48 ++++-
 .../smp/auth/SMPAuthenticationService.java    |  23 ++-
 .../smp/auth/SMPAuthorizationService.java     | 113 +++++++----
 .../smp/auth/cas/SMPCasUserService.java       |  22 ++-
 .../smp/ui/AuthenticationResource.java        |  59 ++----
 .../smp/ui/external/ServiceGroupResource.java |  39 ++--
 .../smp/ui/external/TruststoreResource.java   |  13 --
 .../ui/internal/TruststoreAdminResource.java  |   4 +-
 .../smp/ui/internal/UserAdminResource.java    |  11 +-
 .../auth/SMPAuthenticationProviderTest.java   |  13 +-
 .../smp/auth/SMPAuthorizationServiceTest.java |  92 ++++++++-
 .../smp/ui/AuthenticationResourceTest.java    | 107 +++++------
 .../external/UserResourceIntegrationTest.java |   1 -
 ...ruststoreAdminResourceIntegrationTest.java |   6 +-
 38 files changed, 817 insertions(+), 511 deletions(-)
 create mode 100644 smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPUserDetails.java
 create mode 100644 smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/auth/UILoginAuthenticationToken.java
 delete mode 100644 smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/X509CertificateUtils.java
 create mode 100644 smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/SessionSecurityUtilsTest.java

diff --git a/smp-docker/compose/tomcat-mysql-smp-sml/docker-compose.yml b/smp-docker/compose/tomcat-mysql-smp-sml/docker-compose.yml
index 63bc8ddd7..29724dc55 100644
--- a/smp-docker/compose/tomcat-mysql-smp-sml/docker-compose.yml
+++ b/smp-docker/compose/tomcat-mysql-smp-sml/docker-compose.yml
@@ -21,6 +21,7 @@ services:
       - "8982:8080"
       - "6902:6901"
       - "8953:53"
+      - "5005:5005"
 
   eulogin-mock-server:
     image: edelivery-docker.devops.tech.ec.europa.eu/eulogin/mockserver:6.2.7
diff --git a/smp-docker/images/tomcat-mysql-smp-sml/Dockerfile b/smp-docker/images/tomcat-mysql-smp-sml/Dockerfile
index 76e0e3bbe..133ff6156 100755
--- a/smp-docker/images/tomcat-mysql-smp-sml/Dockerfile
+++ b/smp-docker/images/tomcat-mysql-smp-sml/Dockerfile
@@ -31,7 +31,10 @@ ENV SMP_HOME=/opt/smp  \
 # misc variables
    JACOCO_VERSION=0.8.4 \
    LANG=en_US.utf8  \
-   LD_LIBRARY_PATH=/usr/local/apr/lib
+   LD_LIBRARY_PATH=/usr/local/apr/lib \
+   # set debug
+   JPDA_ADDRESS="5005" \
+   JPDA_TRANSPORT="dt_socket"
 
 
 # Exposing ports used in entrypoint.sh ..
@@ -39,7 +42,8 @@ ENV SMP_HOME=/opt/smp  \
 # - 6901 JaCoCo port
 # - 8080 Tomcat port
 # - 53 dns port
-EXPOSE 3306 8080 6901 53
+# - JDPA debug port
+EXPOSE 3306 8080 6901 53 5005
 
 
 
diff --git a/smp-docker/images/tomcat-mysql-smp-sml/entrypoint.sh b/smp-docker/images/tomcat-mysql-smp-sml/entrypoint.sh
index e5067b1d8..7a4a0f4de 100755
--- a/smp-docker/images/tomcat-mysql-smp-sml/entrypoint.sh
+++ b/smp-docker/images/tomcat-mysql-smp-sml/entrypoint.sh
@@ -24,10 +24,14 @@ if [ ! -d ${DATA_DIR} ]; then
 fi
 
 init_tomcat() {
-  # add java code coverage angent to image
+  # add java code coverage agent to image
   if [ -e /opt/jacoco/jacoco-agent.jar ]; then
     JAVA_OPTS="-javaagent:/opt/jacoco/jacoco-agent.jar=output=tcpserver,address=*,port=6901,includes=eu.europa.ec.edelivery.smp.* $JAVA_OPTS"
   fi
+
+  # for debugging
+  JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=localhost"
+  JAVA_OPTS="$JAVA_OPTS -Xms512m -Xmx512m -server "
   # add allow encoded slashes and disable scheme for proxy
   JAVA_OPTS="$JAVA_OPTS -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true -Djdk.http.auth.tunneling.disabledSchemes="
   # add truststore for eulogin
@@ -36,8 +40,10 @@ init_tomcat() {
       JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=/tmp/keystores/smp-eulogin-mock.p12 -Djavax.net.ssl.trustStoreType=PKCS12 -Djavax.net.ssl.trustStorePassword=test123"
    fi
 
+  echo "[INFO] init tomcat JAVA_OPTS: $JAVA_OPTS"
   export  JAVA_OPTS
 
+
   echo "[INFO] init tomcat folders: $tfile"
   if [ ! -d ${TOMCAT_DIR} ]; then
     mkdir -p ${TOMCAT_DIR}
@@ -248,7 +254,7 @@ echo '[INFO] start running SMP'
 chmod u+x $SMP_HOME/apache-tomcat-$TOMCAT_VERSION/bin/*.sh
 cd $SMP_HOME/apache-tomcat-$TOMCAT_VERSION/
 # run from this folder in order to be smp log in logs folder
-exec ./bin/catalina.sh run
+exec ./bin/catalina.sh jpda run
 
 
 
diff --git a/smp-server-library/pom.xml b/smp-server-library/pom.xml
index 0bffa3e2a..0006fd33f 100644
--- a/smp-server-library/pom.xml
+++ b/smp-server-library/pom.xml
@@ -69,10 +69,13 @@
             <groupId>org.springframework</groupId>
             <artifactId>spring-context</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-cas</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-context-support</artifactId>
-            <version>${spring.version}</version>
         </dependency>
         <dependency>
             <groupId>org.freemarker</groupId>
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationToken.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationToken.java
index adf1c0621..b15b775cc 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationToken.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationToken.java
@@ -1,43 +1,40 @@
 package eu.europa.ec.edelivery.smp.auth;
 
-import eu.europa.ec.edelivery.smp.data.model.DBUser;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 import eu.europa.ec.edelivery.smp.utils.SecurityUtils;
 import org.springframework.security.authentication.AbstractAuthenticationToken;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.GrantedAuthority;
 
-import java.util.Collection;
 import java.util.Objects;
 
+/**
+ * UI and web service authentication token. The authentication is created by the authentication provider
+ *
+ * @author Joze Rihtarsic
+ * @since 4.1
+ */
 public class SMPAuthenticationToken extends UsernamePasswordAuthenticationToken {
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(SMPAuthenticationToken.class);
-    private final DBUser user;
-    // session encryption key to encrypt sensitive data
-    // at the moment used for UI sessions
-    private SecurityUtils.Secret secret = null;
+    SMPUserDetails userDetails;
 
-    public SMPAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
-        this(principal, credentials, authorities, null);
+    public SMPAuthenticationToken(Object principal, Object credentials, SMPUserDetails userDetails) {
+        super(principal, credentials, userDetails.getAuthorities());
+        setDetails(userDetails);
+        this.userDetails = userDetails;
     }
 
-    public SMPAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities, DBUser user) {
-        super(principal, credentials, authorities);
-        this.user = user;
-    }
+    public SecurityUtils.Secret getSecret() {
 
-    public DBUser getUser() {
-        return user;
+        if (userDetails == null) {
+            LOG.warn("Can not retrieve security token for session. User details is null!");
+            return null;
+        }
+        return userDetails.getSessionSecret();
     }
 
-    public SecurityUtils.Secret getSecret() {
-        if (secret == null) {
-            LOG.debug("Secret does not yet exist. Create user session secret!");
-            secret = SecurityUtils.generatePrivateSymmetricKey();
-            LOG.debug("User session secret created!");
-        }
-        return secret;
+    public SMPUserDetails getUserDetails() {
+        return userDetails;
     }
 
     @Override
@@ -47,11 +44,11 @@ public class SMPAuthenticationToken extends UsernamePasswordAuthenticationToken
         if (!super.equals(o)) return false;
         SMPAuthenticationToken that = (SMPAuthenticationToken) o;
         // also check super equals (roles..) which is implemented in AbstractAuthenticationToken
-        return Objects.equals(user, that.user) && super.equals(that);
+        return Objects.equals(getDetails(), that.getDetails()) && super.equals(that);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(super.hashCode(), user);
+        return Objects.hash(super.hashCode(), getDetails());
     }
 }
\ No newline at end of file
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPUserDetails.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPUserDetails.java
new file mode 100644
index 000000000..6c3629df7
--- /dev/null
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPUserDetails.java
@@ -0,0 +1,84 @@
+package eu.europa.ec.edelivery.smp.auth;
+
+import eu.europa.ec.edelivery.smp.data.model.DBUser;
+import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority;
+import eu.europa.ec.edelivery.smp.utils.SecurityUtils;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Object contains Session details for logged user. For the UI it also generated the session secret for encrypting the
+ * session sensitive data.
+ *
+ * @author Joze Rihtarsic
+ * @since 4.2
+ */
+public class SMPUserDetails implements UserDetails {
+    final DBUser user;
+    final SecurityUtils.Secret sessionSecret;
+    boolean casAuthenticated = false;
+    List<SMPAuthority> smpAuthorities = new ArrayList<>();
+
+    public SMPUserDetails(DBUser user, SecurityUtils.Secret sessionSecret, List<SMPAuthority> smpAuthorities) {
+        this.user = user;
+        if (smpAuthorities != null) {
+            this.smpAuthorities.addAll(smpAuthorities);
+        }
+        this.sessionSecret = sessionSecret;
+    }
+
+    public DBUser getUser() {
+        return user;
+    }
+
+    public SecurityUtils.Secret getSessionSecret() {
+        return sessionSecret;
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        return smpAuthorities;
+    }
+
+    public boolean isCasAuthenticated() {
+        return casAuthenticated;
+    }
+
+    public void setCasAuthenticated(boolean casAuthenticated) {
+        this.casAuthenticated = casAuthenticated;
+    }
+
+    @Override
+    public String getPassword() {
+        return null;
+    }
+
+    @Override
+    public String getUsername() {
+        return this.user.getUsername();
+    }
+
+    @Override
+    public boolean isAccountNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isAccountNonLocked() {
+        return true;
+    }
+
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return this.user.isActive();
+    }
+}
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/auth/UILoginAuthenticationToken.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/auth/UILoginAuthenticationToken.java
new file mode 100644
index 000000000..c724dd9b5
--- /dev/null
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/auth/UILoginAuthenticationToken.java
@@ -0,0 +1,18 @@
+package eu.europa.ec.edelivery.smp.auth;
+
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+
+/**
+ * UI login authentication token. The token is generated by SMPAuthenticationService and is supported by the SMPAuthenticationProviderForUI.
+ * It is "distinguished" from UsernamePasswordAuthenticationToken, generated by basic authentication,
+ * which is used for stateless web services invocation using the Personal Access Token credentials.
+ *
+ * @author Joze Rihtarsic
+ * @since 4.2
+ */
+public class UILoginAuthenticationToken   extends UsernamePasswordAuthenticationToken {
+
+    public UILoginAuthenticationToken(Object principal, Object credentials) {
+        super(principal, credentials);
+    }
+}
\ No newline at end of file
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/PropertyInitialization.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/PropertyInitialization.java
index fa7dd2ce8..0d00d807f 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/PropertyInitialization.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/PropertyInitialization.java
@@ -13,13 +13,13 @@
 
 package eu.europa.ec.edelivery.smp.config;
 
+import eu.europa.ec.edelivery.security.utils.X509CertificateUtils;
 import eu.europa.ec.edelivery.smp.data.model.DBConfiguration;
 import eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum;
 import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 import eu.europa.ec.edelivery.smp.utils.SecurityUtils;
-import eu.europa.ec.edelivery.smp.utils.X509CertificateUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.jdbc.datasource.DriverManagerDataSource;
 import org.springframework.jndi.JndiObjectFactoryBean;
@@ -33,7 +33,6 @@ import javax.sql.DataSource;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.nio.file.Files;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
@@ -54,6 +53,11 @@ import static eu.europa.ec.edelivery.smp.exceptions.ErrorCode.INTERNAL_ERROR;
 public class PropertyInitialization {
 
     SMPLogger LOG = SMPLoggerFactory.getLogger(PropertyInitialization.class);
+    // if SMP is initialized without keystore - a demo keystore with test certificate is created
+    private static final String TEST_CERT_ISSUER_DN = "CN=rootCNTest,OU=B4,O=DIGIT,L=Brussels,ST=BE,C=BE";
+    private static final String TEST_CERT_SUBJECT_DN = "CN=SMP_TEST-PRE-SET-EXAMPLE, OU=eDelivery, O=DIGITAL, C=BE";
+    private static final String TEST_CERT_ISSUER_ALIAS = "issuer";
+    private static final String TEST_CERT_CERT_ALIAS = "sample_key";
 
     protected Properties getDatabaseProperties(Properties fileProperties) {
         String dialect = fileProperties.getProperty(FileProperty.PROPERTY_DB_DIALECT);
@@ -211,7 +215,10 @@ public class PropertyInitialization {
             newKeystore.load(null, newKeyPassword.toCharArray());
             // check if keystore is empty then generate cert for user
             if (newKeystore.size() == 0) {
-                X509CertificateUtils.createAndAddTextCertificate("CN=SMP_TEST-PRE-SET-EXAMPLE, OU=eDelivery, O=DIGITAL, C=BE", newKeystore, newKeyPassword);
+                X509CertificateUtils.createAndStoreCertificateWithChain(
+                        new String []{TEST_CERT_ISSUER_DN, TEST_CERT_SUBJECT_DN},
+                        new String []{TEST_CERT_ISSUER_ALIAS, TEST_CERT_CERT_ALIAS},
+                        newKeystore, newKeyPassword);
             }
             newKeystore.store(out, newKeyPassword.toCharArray());
         } catch (IOException e) {
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/X509CertificateToCertificateROConverter.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/X509CertificateToCertificateROConverter.java
index 42173bba2..aa58f5329 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/X509CertificateToCertificateROConverter.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/X509CertificateToCertificateROConverter.java
@@ -1,12 +1,12 @@
 package eu.europa.ec.edelivery.smp.conversion;
 
 import eu.europa.ec.edelivery.security.PreAuthenticatedCertificatePrincipal;
+import eu.europa.ec.edelivery.security.utils.X509CertificateUtils;
 import eu.europa.ec.edelivery.smp.data.ui.CertificateRO;
 import eu.europa.ec.edelivery.smp.exceptions.ErrorCode;
 import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
-import eu.europa.ec.edelivery.smp.utils.X509CertificateUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.core.convert.converter.Converter;
 import org.springframework.stereotype.Component;
@@ -23,6 +23,7 @@ import java.util.Base64;
 
 /**
  * @author Joze Rihtarsic
+ * @since 4.1
  */
 @Component
 public class X509CertificateToCertificateROConverter implements Converter<X509Certificate, CertificateRO> {
@@ -54,7 +55,7 @@ public class X509CertificateToCertificateROConverter implements Converter<X509Ce
             cro.setEncodedValue(Base64.getMimeEncoder().encodeToString(cert.getEncoded()));
         } catch (CertificateEncodingException cex) {
             throw new SMPRuntimeException(ErrorCode.CERTIFICATE_ERROR, cex,
-                    "Error occured while decoding certificate " + subject, cex.getMessage(), cex);
+                    "Error occurred while decoding certificate " + subject, cex.getMessage(), cex);
 
         }
         // generate clientCertHeader header
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/UserRO.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/UserRO.java
index 47740d866..f5be11549 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/UserRO.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/UserRO.java
@@ -5,7 +5,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
 import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority;
 import eu.europa.ec.edelivery.smp.data.ui.enums.EntityROStatus;
 import eu.europa.ec.edelivery.smp.utils.SMPConstants;
-import org.springframework.security.core.userdetails.UserDetails;
 
 import java.time.OffsetDateTime;
 import java.util.Collection;
@@ -15,12 +14,11 @@ import java.util.Collection;
  * @author Joze Rihtarsic
  * @since 4.1
  */
-public class UserRO extends BaseRO implements UserDetails {
+public class UserRO extends BaseRO {
 
     static final long serialVersionUID = 2821447495333163882L;
 
     String username;
-
     String password;
     @JsonFormat(pattern = SMPConstants.JSON_DATETIME_ISO)
     OffsetDateTime passwordExpireOn;
@@ -133,7 +131,6 @@ public class UserRO extends BaseRO implements UserDetails {
         this.certificate = certificate;
     }
 
-    @Override
     public Collection<SMPAuthority> getAuthorities() {
         return authorities;
     }
@@ -173,28 +170,4 @@ public class UserRO extends BaseRO implements UserDetails {
     public void setCasAuthenticated(boolean casAuthenticated) {
         this.casAuthenticated = casAuthenticated;
     }
-
-    @Override
-    @JsonIgnore
-    public boolean isAccountNonExpired() {
-        return true;
-    }
-
-    @Override
-    @JsonIgnore
-    public boolean isAccountNonLocked() {
-        return true;
-    }
-
-    @Override
-    @JsonIgnore
-    public boolean isCredentialsNonExpired() {
-        return true;
-    }
-
-    @Override
-    @JsonIgnore
-    public boolean isEnabled() {
-        return active;
-    }
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/auth/SMPAuthority.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/auth/SMPAuthority.java
index 962621e9d..f74ea7de6 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/auth/SMPAuthority.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/auth/SMPAuthority.java
@@ -3,9 +3,14 @@ package eu.europa.ec.edelivery.smp.data.ui.auth;
 import com.fasterxml.jackson.annotation.JsonValue;
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import eu.europa.ec.edelivery.smp.data.ui.databind.SMPAuthorityDeserializer;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.security.core.GrantedAuthority;
 
 
+/**
+ * @author Joze Rihtarsic
+ * @since 4.1
+ */
 @JsonDeserialize(using = SMPAuthorityDeserializer.class)
 public class SMPAuthority implements GrantedAuthority {
 
@@ -16,7 +21,6 @@ public class SMPAuthority implements GrantedAuthority {
     public static final String S_AUTHORITY_TOKEN_SYSTEM_ADMIN = "ROLE_SYSTEM_ADMIN";
     public static final String S_AUTHORITY_TOKEN_SMP_ADMIN = "ROLE_SMP_ADMIN";
     public static final String S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN = "ROLE_SERVICE_GROUP_ADMIN";
-    public static final String S_AUTHORITY_TOKEN_ROLE_ANONYMOUS = "ROLE_ANONYMOUS";
 
     // static constants for verification...
     public static final SMPAuthority S_AUTHORITY_SYSTEM_ADMIN = new SMPAuthority(SMPRole.SYSTEM_ADMIN.getCode());
@@ -30,7 +34,7 @@ public class SMPAuthority implements GrantedAuthority {
 
     String role;
 
-    public SMPAuthority(String role) {
+    private SMPAuthority(String role) {
         this.role = role;
     }
 
@@ -39,4 +43,35 @@ public class SMPAuthority implements GrantedAuthority {
     public String getAuthority() {
         return "ROLE_" + role;
     }
+
+    public String getRole() {
+        return role;
+    }
+
+    public static SMPAuthority getAuthorityByRoleName(String name) {
+        if (StringUtils.isBlank(name)) {
+            return S_AUTHORITY_ANONYMOUS;
+        }
+        SMPRole role = SMPRole.valueOf(name);
+        return getAuthorityByRole(role);
+    }
+
+    public static SMPAuthority getAuthorityByRole(SMPRole role) {
+        switch (role) {
+            case SMP_ADMIN:
+                return S_AUTHORITY_SMP_ADMIN;
+            case SYSTEM_ADMIN:
+                return S_AUTHORITY_SYSTEM_ADMIN;
+            case SERVICE_GROUP_ADMIN:
+                return S_AUTHORITY_SERVICE_GROUP;
+            case WS_SMP_ADMIN:
+                return S_AUTHORITY_WS_SMP_ADMIN;
+            case WS_SERVICE_GROUP_ADMIN:
+                return S_AUTHORITY_WS_SERVICE_GROUP;
+            case WS_SYSTEM_ADMIN:
+                return S_AUTHORITY_WS_SYSTEM_ADMIN;
+            default:
+                return S_AUTHORITY_ANONYMOUS;
+        }
+    }
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/databind/SMPAuthorityDeserializer.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/databind/SMPAuthorityDeserializer.java
index 9b38e55eb..aa45aa037 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/databind/SMPAuthorityDeserializer.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/databind/SMPAuthorityDeserializer.java
@@ -24,6 +24,6 @@ public class SMPAuthorityDeserializer extends StdDeserializer<SMPAuthority> {
     public SMPAuthority deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
         JsonNode node = jsonParser.getCodec().readTree(jsonParser);
         String text = node.asText();
-        return new SMPAuthority(text.substring("ROLE_".length()));
+        return SMPAuthority.getAuthorityByRoleName(text.substring("ROLE_".length()));
     }
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java
index 8ae09d7b4..4176a2b64 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java
@@ -72,12 +72,15 @@ public enum SMPPropertyEnum {
             "The error message shown to the user in case the password does not follow the regex put in the domibus.passwordPolicy.pattern property", false, false,false, STRING),
     PASSWORD_POLICY_VALID_DAYS("smp.passwordPolicy.validDays","90",
             "Number of days password is valid", false, false,false, INTEGER),
-    PASSWORD_POLICY_UIWARNING_DAYS_BEFORE_EXPIRE("smp.passwordPolicy.warning.beforeExpiration","15",
+    PASSWORD_POLICY_WARNING_DAYS_BEFORE_EXPIRE("smp.passwordPolicy.warning.beforeExpiration","15",
             "How many days before expiration should the UI warn users at login", false, false,false, INTEGER),
 
     PASSWORD_POLICY_FORCE_CHANGE_EXPIRED("smp.passwordPolicy.expired.forceChange","true",
             "Force change password at UI login if expired", false, false,false, BOOLEAN),
 
+    USER_LOGIN_FAIL_DELAY("smp.user.login.fail.delay","1000",
+            "Delay in ms on invalid username or password", false, false,false, INTEGER),
+
     USER_MAX_FAILED_ATTEMPTS("smp.user.login.maximum.attempt","5",
             "Number of console login attempt before the user is deactivated", false, false,false, INTEGER),
     USER_SUSPENSION_TIME("smp.user.login.suspension.time","3600",
@@ -89,6 +92,8 @@ public enum SMPPropertyEnum {
             "Number of accessToken login attempt before the accessToken is deactivated", false, false,false, INTEGER),
     ACCESS_TOKEN_SUSPENSION_TIME("smp.accessToken.login.suspension.time","3600",
             "Time in seconds for a suspended accessToken to be reactivated. (if 0 the user will not be reactivated)", false, false,false, INTEGER),
+    ACCESS_TOKEN_FAIL_DELAY("smp.accessToken.login.fail.delay","1000",
+            "Delay in ms on invalid token id or token", false, false,false, INTEGER),
 
     // authentication
     UI_AUTHENTICATION_TYPES("smp.ui.authentication.types", "PASSWORD", "Set list of '|' separated authentication types: PASSWORD|SSO.", false, false, false, LIST_STRING),
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/CRLVerifierService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/CRLVerifierService.java
index 65d8997e7..56ee3693a 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/CRLVerifierService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/CRLVerifierService.java
@@ -20,12 +20,12 @@ package eu.europa.ec.edelivery.smp.services;
  */
 
 
+import eu.europa.ec.edelivery.security.utils.X509CertificateUtils;
 import eu.europa.ec.edelivery.smp.exceptions.ErrorCode;
 import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 import eu.europa.ec.edelivery.smp.utils.HttpUtils;
-import eu.europa.ec.edelivery.smp.utils.X509CertificateUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.cxf.helpers.IOUtils;
@@ -70,7 +70,7 @@ public class CRLVerifierService {
     ConfigurationService configurationService;
 
 
-    public void verifyCertificateCRLs(X509Certificate cert) throws CertificateRevokedException {
+    public void verifyCertificateCRLs(X509Certificate cert) throws CertificateRevokedException, CertificateParsingException {
 
         List<String> crlDistPoints = X509CertificateUtils.getCrlDistributionPoints(cert);
         if (crlDistPoints.isEmpty()) {
@@ -269,8 +269,6 @@ public class CRLVerifierService {
             throw new CertificateRevokedException(entry.getRevocationDate(),
                     entry.getRevocationReason() == null ? NULL_CRL_REASON : entry.getRevocationReason(),
                     entry.getCertificateIssuer() == null ? NULL_ISSUER : entry.getCertificateIssuer(), map);
-
         }
     }
-
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ConfigurationService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ConfigurationService.java
index 11619ba97..3d26225b4 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ConfigurationService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ConfigurationService.java
@@ -65,7 +65,7 @@ public class ConfigurationService {
     }
 
     public Integer getPasswordPolicyUIWarningDaysBeforeExpire() {
-        return (Integer) configurationDAO.getCachedPropertyValue(PASSWORD_POLICY_UIWARNING_DAYS_BEFORE_EXPIRE);
+        return (Integer) configurationDAO.getCachedPropertyValue(PASSWORD_POLICY_WARNING_DAYS_BEFORE_EXPIRE);
     }
 
     public Boolean getPasswordPolicyForceChangeIfExpired() {
@@ -84,6 +84,11 @@ public class ConfigurationService {
         return (Integer) configurationDAO.getCachedPropertyValue(USER_SUSPENSION_TIME);
     }
 
+    public Integer getLoginFailDelayInMilliSeconds() {
+        Integer delay =(Integer) configurationDAO.getCachedPropertyValue(USER_LOGIN_FAIL_DELAY);
+        return delay==null? 1000:delay;
+    }
+
     public Integer getAccessTokenLoginMaxAttempts() {
         return (Integer) configurationDAO.getCachedPropertyValue(ACCESS_TOKEN_MAX_FAILED_ATTEMPTS);
     }
@@ -92,6 +97,11 @@ public class ConfigurationService {
         return (Integer) configurationDAO.getCachedPropertyValue(ACCESS_TOKEN_SUSPENSION_TIME);
     }
 
+    public Integer getAccessTokenLoginFailDelayInMilliSeconds() {
+        Integer delay =(Integer) configurationDAO.getCachedPropertyValue(ACCESS_TOKEN_FAIL_DELAY);
+        return delay==null? 1000:delay;
+    }
+
     public Integer getHttpHeaderHstsMaxAge() {
         return (Integer) configurationDAO.getCachedPropertyValue(HTTP_HSTS_MAX_AGE);
     }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIKeystoreService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIKeystoreService.java
index c7213acbc..74d16470f 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIKeystoreService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIKeystoreService.java
@@ -7,9 +7,7 @@ import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 import eu.europa.ec.edelivery.smp.services.ConfigurationService;
 import eu.europa.ec.edelivery.smp.utils.SecurityUtils;
-import eu.europa.ec.edelivery.smp.utils.X509CertificateUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.convert.ConversionService;
 import org.springframework.stereotype.Service;
@@ -17,7 +15,6 @@ import org.springframework.stereotype.Service;
 import javax.annotation.PostConstruct;
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.TrustManagerFactory;
 import java.io.*;
 import java.security.*;
 import java.security.cert.Certificate;
@@ -28,6 +25,10 @@ import java.util.*;
 import static java.util.Collections.list;
 import static org.apache.commons.lang3.StringUtils.isBlank;
 
+/**
+ * @author Joze Rihtarsic
+ * @since 4.1
+ */
 @Service
 public class UIKeystoreService {
 
@@ -53,7 +54,6 @@ public class UIKeystoreService {
     public void init() {
         keystoreKeys = new HashMap();
         keystoreCertificates = new HashMap();
-        X509CertificateUtils.setupJCEProvider();
         refreshData();
     }
 
@@ -66,7 +66,7 @@ public class UIKeystoreService {
         String keystoreSecToken = configurationService.getKeystoreCredentialToken();
 
         // load keystore
-        File keystoreFile =  configurationService.getKeystoreFile();
+        File keystoreFile = configurationService.getKeystoreFile();
         if (keystoreFile == null) {
             LOG.error("KeystoreFile: is null! Check the keystore and the configuration!");
             return;
@@ -101,7 +101,7 @@ public class UIKeystoreService {
             return;
         }
         LOG.debug("Set keystore certificates:");
-        hmCertificates.forEach((alias, cert)-> LOG.debug(" - {}, {}", alias, cert.getSubjectDN().toString() ));
+        hmCertificates.forEach((alias, cert) -> LOG.debug(" - {}, {}", alias, cert.getSubjectDN().toString()));
         // if got all data from keystore - update data
         keyManagers = keyManagersTemp;
 
@@ -120,7 +120,7 @@ public class UIKeystoreService {
     boolean isKeyStoreChanged() {
         File file = configurationService.getKeystoreFile();
 
-        return file!=null && (!Objects.equals(lastUpdateKeystoreFile, file) || file.lastModified() != lastUpdateKeystoreFileTime);
+        return file != null && (!Objects.equals(lastUpdateKeystoreFile, file) || file.lastModified() != lastUpdateKeystoreFileTime);
     }
 
 
@@ -134,7 +134,7 @@ public class UIKeystoreService {
 
     private KeyStore loadKeystore(File keyStoreFile, String keystoreSecToken) {
         // Load the KeyStore.
-        if (keyStoreFile!=null && !keyStoreFile.exists()) {
+        if (keyStoreFile != null && !keyStoreFile.exists()) {
             LOG.error("Keystore file '{}' does not exists!", keyStoreFile.getAbsolutePath());
             return null;
         }
@@ -193,7 +193,7 @@ public class UIKeystoreService {
         }
 
         if (keystoreKeys.isEmpty()) {
-            throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, "Could not retrieve key: " + keyAlias +" from empty keystore!" + configurationService.getKeystoreFile() );
+            throw new SMPRuntimeException(ErrorCode.CONFIGURATION_ERROR, "Could not retrieve key: " + keyAlias + " from empty keystore!" + configurationService.getKeystoreFile());
         }
 
 
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java
index 14b50758c..875fa4db9 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java
@@ -1,5 +1,6 @@
 package eu.europa.ec.edelivery.smp.services.ui;
 
+import eu.europa.ec.edelivery.security.utils.X509CertificateUtils;
 import eu.europa.ec.edelivery.smp.data.ui.CertificateRO;
 import eu.europa.ec.edelivery.smp.exceptions.CertificateNotTrustedException;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
@@ -7,7 +8,6 @@ import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 import eu.europa.ec.edelivery.smp.logging.SMPMessageCode;
 import eu.europa.ec.edelivery.smp.services.CRLVerifierService;
 import eu.europa.ec.edelivery.smp.services.ConfigurationService;
-import eu.europa.ec.edelivery.smp.utils.X509CertificateUtils;
 import eu.europa.ec.edelivery.text.DistinguishedNamesCodingUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
@@ -41,6 +41,10 @@ import java.util.stream.Collectors;
 import static java.util.Collections.list;
 import static java.util.Locale.US;
 
+/**
+ * @author Joze Rihtarsic
+ * @since 4.1
+ */
 @Service
 public class UITruststoreService {
 
@@ -168,15 +172,26 @@ public class UITruststoreService {
     /**
      * Validate certificate!
      *
-     * @param buff - bytearray of the certificate (pem of or der)
+     * @param buff     - bytearray of the certificate (pem of or der)
      * @param validate
      * @return
      * @throws CertificateException
      * @throws IOException
      */
     public CertificateRO getCertificateData(byte[] buff, boolean validate) {
-        X509Certificate cert = X509CertificateUtils.getX509Certificate(buff);
-        CertificateRO cro = convertToRo(cert);
+        X509Certificate cert = null;
+        CertificateRO cro = null;
+        try {
+            cert = X509CertificateUtils.getX509Certificate(buff);
+        } catch (CertificateException e) {
+            LOG.warn("Can not parse the certificate with error:[{}]!", ExceptionUtils.getRootCauseMessage(e));
+            cro = new CertificateRO();
+            cro.setInvalid(true);
+            cro.setInvalidReason("Can not read the certificate!");
+            return cro;
+        }
+
+        cro = convertToRo(cert);
         if (validate) {
             // first expect the worst
             cro.setInvalid(true);
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java
index a59b6a271..88e757865 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java
@@ -1,5 +1,6 @@
 package eu.europa.ec.edelivery.smp.services.ui;
 
+import eu.europa.ec.edelivery.security.utils.X509CertificateUtils;
 import eu.europa.ec.edelivery.smp.data.dao.BaseDao;
 import eu.europa.ec.edelivery.smp.data.dao.UserDao;
 import eu.europa.ec.edelivery.smp.data.model.DBCertificate;
@@ -15,7 +16,6 @@ import eu.europa.ec.edelivery.smp.services.ConfigurationService;
 import eu.europa.ec.edelivery.smp.utils.BCryptPasswordHash;
 import eu.europa.ec.edelivery.smp.utils.SecurityUtils;
 import eu.europa.ec.edelivery.smp.utils.SessionSecurityUtils;
-import eu.europa.ec.edelivery.smp.utils.X509CertificateUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -39,6 +39,10 @@ import java.util.Optional;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
+/**
+ * @author Joze Rihtarsic
+ * @since 4.1
+ */
 @Service
 public class UIUserService extends UIServiceBase<DBUser, UserRO> {
 
@@ -174,9 +178,10 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
             CertificateRO certRo = user.getCertificate();
             LOG.info(certRo.getEncodedValue());
             if (user.getCertificate().getEncodedValue() != null) {
-                X509Certificate x509Certificate = X509CertificateUtils.getX509Certificate(Base64.getMimeDecoder().decode(certRo.getEncodedValue()));
+
                 String certificateAlias;
                 try {
+                    X509Certificate x509Certificate = X509CertificateUtils.getX509Certificate(Base64.getMimeDecoder().decode(certRo.getEncodedValue()));
                     certificateAlias = truststoreService.addCertificate(certRo.getAlias(), x509Certificate);
                 } catch (NoSuchAlgorithmException | KeyStoreException | IOException | CertificateException e) {
                     LOG.error("Error occurred while adding certificate to truststore.", e);
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/SessionSecurityUtils.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/SessionSecurityUtils.java
index 6628a098e..ae803480f 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/SessionSecurityUtils.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/SessionSecurityUtils.java
@@ -1,15 +1,41 @@
 package eu.europa.ec.edelivery.smp.utils;
 
 import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationToken;
+import eu.europa.ec.edelivery.smp.auth.SMPUserDetails;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
+import org.springframework.security.cas.authentication.CasAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
 
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
 
+/**
+ * Class provides common session security tools to enhance UI security.
+ * Session is enabled only for UI. To increase security SMP encrypt sensitive data. The
+ * class provides tools for encrypting, decrypting data for the session.
+ *
+ * @author Joze Rihtarsic
+ * @since 4.2
+ */
 public class SessionSecurityUtils {
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(SessionSecurityUtils.class);
 
+    /**
+     * '
+     * Currently authentication tokens supported to create na UI session.
+     */
+    public static final List<Class> sessionAuthenticationClasses = Arrays.asList(SMPAuthenticationToken.class,
+            CasAuthenticationToken.class);
+
+    /**
+     * SMP uses entity ids type long. Because the keys are sequence keys, SMP encrypts ids for the User.
+     *
+     * @param id
+     * @return
+     */
     public static String encryptedEntityId(Long id) {
         if (id == null) {
             return null;
@@ -29,7 +55,7 @@ public class SessionSecurityUtils {
         return new Long(value);
     }
 
-    public static SecurityUtils.Secret getAuthenticationSecret() {
+    public static Authentication getSessionAuthentication() {
         if (SecurityContextHolder.getContext() == null) {
             LOG.warn("No Security context!");
             return null;
@@ -39,13 +65,53 @@ public class SessionSecurityUtils {
             LOG.warn("No active Authentication!");
             return null;
         }
-        if (!(authentication instanceof SMPAuthenticationToken)) {
-            LOG.warn("Authentication is not class type: SMPAuthenticationToken!");
+
+        if (getSessionAuthenticationClasses().contains(authentication.getClass())) {
+            return authentication;
+        }
+
+        LOG.warn("Authentication class [{}] is not session enabled class types: [{}]!", authentication.getClass(),
+                getSessionAuthenticationClasses().stream().map(Class::getName).collect(Collectors.toList()));
+        return null;
+    }
+
+    public static SMPUserDetails getSessionUserDetails() {
+
+        Authentication authentication = getSessionAuthentication();
+        if (authentication == null) {
+            LOG.warn("No active SMP session Authentication!");
+            return null;
+        }
+
+        if (authentication instanceof SMPAuthenticationToken) {
+            LOG.debug("Return user details from SMPAuthenticationToken");
+            return ((SMPAuthenticationToken) authentication).getUserDetails();
+        }
+
+        if (authentication instanceof CasAuthenticationToken) {
+            LOG.debug("Return session secret from CasAuthenticationToken");
+            return (SMPUserDetails) ((CasAuthenticationToken) authentication).getUserDetails();
+        }
+
+        LOG.warn("Authentication class [{}] is not session enabled class types: [{}]!", authentication.getClass(),
+                getSessionAuthenticationClasses().stream().map(Class::getName).collect(Collectors.toList()));
+        return null;
+    }
+
+    public static SecurityUtils.Secret getAuthenticationSecret() {
+        SMPUserDetails smpUserDetails = getSessionUserDetails();
+        if (smpUserDetails == null) {
+            LOG.warn("No SMPUserDetails object!");
             return null;
         }
-        return ((SMPAuthenticationToken) authentication).getSecret();
+        return smpUserDetails.getSessionSecret();
     }
 
+    /**
+     * Method returns authentication name  for logging
+     *
+     * @return authentication name
+     */
     public static String getAuthenticationName() {
         if (SecurityContextHolder.getContext() == null) {
             LOG.debug("No Security context!");
@@ -57,6 +123,9 @@ public class SessionSecurityUtils {
             return null;
         }
         return authentication.getName();
+    }
 
+    public static List<Class> getSessionAuthenticationClasses() {
+        return sessionAuthenticationClasses;
     }
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/X509CertificateUtils.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/X509CertificateUtils.java
deleted file mode 100644
index bbcedc963..000000000
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/utils/X509CertificateUtils.java
+++ /dev/null
@@ -1,175 +0,0 @@
-package eu.europa.ec.edelivery.smp.utils;
-
-
-import eu.europa.ec.edelivery.security.PreAuthenticatedCertificatePrincipal;
-import eu.europa.ec.edelivery.smp.exceptions.ErrorCode;
-import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
-import org.bouncycastle.asn1.ASN1InputStream;
-import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.DERIA5String;
-import org.bouncycastle.asn1.DEROctetString;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x509.*;
-import org.bouncycastle.cert.X509v3CertificateBuilder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.operator.ContentSigner;
-import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
-
-import javax.security.auth.x500.X500Principal;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.security.*;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.Calendar;
-import java.util.List;
-
-public class X509CertificateUtils {
-
-    private static final String TEST_CERT_ISSUER_DN = "CN=rootCNTest,OU=B4,O=DIGIT,L=Brussels,ST=BE,C=BE";
-
-    public static void setupJCEProvider() {
-        Provider[] providerList = Security.getProviders();
-        if (providerList == null || providerList.length <= 0 || !(providerList[0] instanceof BouncyCastleProvider)) {
-            Security.insertProviderAt(new org.bouncycastle.jce.provider.BouncyCastleProvider(), 1);
-        }
-    }
-
-    public static void createAndAddTextCertificate(String subject,  KeyStore keystore, String secToken) throws Exception {
-        setupJCEProvider();
-        Calendar from = Calendar.getInstance();
-        from.add(Calendar.DAY_OF_MONTH, -1);
-        Calendar to = Calendar.getInstance();
-        to.add(Calendar.YEAR, 5);
-
-        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
-        keyGen.initialize(2048);
-        KeyPair key = keyGen.generateKeyPair();
-        X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(new X500Name(TEST_CERT_ISSUER_DN),BigInteger.ONE, from.getTime(), to.getTime(), new X500Name(subject), SubjectPublicKeyInfo.getInstance(key.getPublic().getEncoded()));
-
-        ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider("BC").build(key.getPrivate());
-        X509Certificate cert =  new JcaX509CertificateConverter().setProvider("BC").getCertificate(certBuilder.build(sigGen));
-        keystore.setKeyEntry("sample_key", key.getPrivate(), secToken.toCharArray(), new X509Certificate[]{cert});
-    }
-    /**
-     * Extracts all CRL distribution point URLs from the
-     * "CRL Distribution Point" extension in a X.509 certificate. If CRL
-     * distribution point extension is unavailable, returns an empty list.
-     */
-    public static List<String> getCrlDistributionPoints(X509Certificate cert) {
-        byte[] crldpExt = cert.getExtensionValue(Extension.cRLDistributionPoints.getId());
-        if (crldpExt == null) {
-            return new ArrayList<>();
-        }
-        ASN1InputStream oAsnInStream = new ASN1InputStream(
-                new ByteArrayInputStream(crldpExt));
-        ASN1Primitive derObjCrlDP;
-        try {
-            derObjCrlDP = oAsnInStream.readObject();
-        } catch (IOException e) {
-            throw new SMPRuntimeException(ErrorCode.CERTIFICATE_ERROR, "Error while extracting CRL distribution point URLs", e);
-        }
-        DEROctetString dosCrlDP = (DEROctetString) derObjCrlDP;
-        byte[] crldpExtOctets = dosCrlDP.getOctets();
-        ASN1InputStream oAsnInStream2 = new ASN1InputStream(
-                new ByteArrayInputStream(crldpExtOctets));
-        ASN1Primitive derObj2;
-        try {
-            derObj2 = oAsnInStream2.readObject();
-        } catch (IOException e) {
-            throw new SMPRuntimeException(ErrorCode.CERTIFICATE_ERROR, "Error while extracting CRL distribution point URLs", e);
-        }
-        CRLDistPoint distPoint = CRLDistPoint.getInstance(derObj2);
-        List<String> crlUrls = new ArrayList<>();
-        for (DistributionPoint dp : distPoint.getDistributionPoints()) {
-            DistributionPointName dpn = dp.getDistributionPoint();
-            // Look for URIs in fullName
-            if (dpn != null
-                    && dpn.getType() == DistributionPointName.FULL_NAME) {
-                GeneralName[] genNames = GeneralNames.getInstance(
-                        dpn.getName()).getNames();
-                // Look for an URI
-                for (GeneralName genName : genNames) {
-                    if (genName.getTagNo() == GeneralName.uniformResourceIdentifier) {
-                        String url = DERIA5String.getInstance(
-                                genName.getName()).getString();
-
-
-                        crlUrls.add(url);
-                    }
-                }
-            }
-        }
-        return crlUrls;
-    }
-
-    public static String getCrlDistributionUrl(X509Certificate cert) {
-        List<String> list = getCrlDistributionPoints(cert);
-        return list.isEmpty()?null:extractHttpCrlDistributionPoint(list);
-    }
-
-    /**
-     * Method retrieves https. If https does not exist it return http distribution list.
-     * (LDAP is not allowed (FW OPEN) in targeted network)
-     *
-     * @param urlList
-     * @return
-     */
-    public static String extractHttpCrlDistributionPoint(List<String> urlList) {
-        String httpsUrl = null;
-        String httpUrl = null;
-        for (String url : urlList) {
-            String newUrl = url.trim();
-            if (newUrl.toLowerCase().startsWith("https://")) {
-                httpsUrl = newUrl;
-            } else if (newUrl.toLowerCase().startsWith("http://")) {
-                httpUrl = newUrl;
-
-            }
-        }
-        return httpsUrl == null ? httpUrl : httpsUrl;
-    }
-
-
-
-    public static PreAuthenticatedCertificatePrincipal extractPrincipalFromCertificate(X509Certificate cert) {
-
-        String subject = cert.getSubjectX500Principal().getName(X500Principal.RFC2253);
-        String issuer = cert.getIssuerX500Principal().getName(X500Principal.RFC2253);
-        BigInteger serial = cert.getSerialNumber();
-
-        return new PreAuthenticatedCertificatePrincipal(subject, issuer, serial, cert.getNotBefore(), cert.getNotAfter());
-    }
-
-    public static X509Certificate getX509Certificate(byte[] certBytes) {
-        try {
-            InputStream is = new ByteArrayInputStream(certBytes);
-            return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(is);
-        } catch (CertificateException exc) {
-            throw new SMPRuntimeException(ErrorCode.CERTIFICATE_ERROR, String.format("The certificate is not valid - [%s]", exc.getMessage()), exc);
-        }
-    }
-
-    public static X509Certificate getX509Certificate(String publicKey) {
-        // if certificate has begin certificate - then is PEM encoded
-        if (publicKey.contains("BEGIN CERTIFICATE")) {
-            return getX509Certificate(publicKey.getBytes());
-        } else {
-            byte[] buff;
-            // try do decode
-            try {
-                buff = Base64.getDecoder().decode(publicKey.getBytes());
-            } catch (java.lang.IllegalArgumentException ex) {
-                buff = publicKey.getBytes();
-            }
-            return getX509Certificate(buff);
-        }
-    }
-
-}
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/SessionSecurityUtilsTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/SessionSecurityUtilsTest.java
new file mode 100644
index 000000000..13748c167
--- /dev/null
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/SessionSecurityUtilsTest.java
@@ -0,0 +1,124 @@
+package eu.europa.ec.edelivery.smp.utils;
+
+import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationToken;
+import eu.europa.ec.edelivery.smp.auth.SMPUserDetails;
+import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority;
+import org.jasig.cas.client.validation.Assertion;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.cas.authentication.CasAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+/**
+ * @author Joze Rihtarsic
+ * @since 4.2
+ */
+public class SessionSecurityUtilsTest {
+
+    @After
+    public void afterUnitTest() {
+        // clear authentication
+        SecurityContextHolder.getContext().setAuthentication(null);
+    }
+
+    @Test
+    public void encryptedEntityId() {
+        SMPAuthenticationToken token = setTestSMPAuthenticationToken();
+        Long value = Long.valueOf(12332L);
+        String result = SessionSecurityUtils.encryptedEntityId(value);
+
+        assertNotNull(result);
+        String decResult = SecurityUtils.decryptUrlSafe(token.getSecret(), result);
+        assertEquals(value, Long.valueOf(decResult));
+    }
+
+    @Test
+    public void decryptEntityId() {
+        SMPAuthenticationToken token = setTestSMPAuthenticationToken();
+        Long value = Long.valueOf(12332L);
+        String encValue = SecurityUtils.encryptURLSafe(token.getSecret(), value.toString());
+
+        Long result = SessionSecurityUtils.decryptEntityId(encValue);
+
+        assertNotNull(result);
+        assertEquals(value, result);
+    }
+
+    @Test
+    public void getAuthenticationSecretFromSMPAuthenticationToken() {
+        // given
+        SMPAuthenticationToken token = setTestSMPAuthenticationToken();
+
+        SecurityUtils.Secret result = SessionSecurityUtils.getAuthenticationSecret();
+        assertNotNull(result);
+        assertEquals(token.getSecret(), result);
+    }
+
+    @Test
+    public void getAuthenticationSecretFromCasAuthenticationToken() {
+        // given
+        CasAuthenticationToken token = setTestCasAuthenticationToken();
+
+
+        SecurityUtils.Secret result = SessionSecurityUtils.getAuthenticationSecret();
+        assertNotNull(result);
+        assertEquals(((SMPUserDetails) token.getUserDetails()).getSessionSecret(), result);
+    }
+
+    @Test
+    public void getAuthenticationSecretNotSupported() {
+        // given
+        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(null, null);
+        SecurityContextHolder.getContext().setAuthentication(token);
+
+        SecurityUtils.Secret result = SessionSecurityUtils.getAuthenticationSecret();
+
+        assertNull(result);
+    }
+
+    @Test
+    public void getAuthenticationName() {
+        Authentication authentication = Mockito.mock(Authentication.class);
+        SecurityContextHolder.getContext().setAuthentication(authentication);
+        String testName = "testName";
+        Mockito.doReturn(testName).when(authentication).getName();
+
+        String result = SessionSecurityUtils.getAuthenticationName();
+
+        Assert.assertNotNull(result);
+        Assert.assertEquals(testName, result);
+    }
+
+    @Test
+    public void getSessionAuthenticationClasses() {
+        List<Class> list = SessionSecurityUtils.getSessionAuthenticationClasses();
+        Assert.assertEquals(2, list.size());
+        Assert.assertTrue(list.contains(SMPAuthenticationToken.class));
+        Assert.assertTrue(list.contains(CasAuthenticationToken.class));
+    }
+
+    public SMPAuthenticationToken setTestSMPAuthenticationToken() {
+        SecurityUtils.Secret secret = SecurityUtils.generatePrivateSymmetricKey();
+        SMPAuthenticationToken token = new SMPAuthenticationToken(null, null, new SMPUserDetails(null, secret, null));
+        SecurityContextHolder.getContext().setAuthentication(token);
+        return token;
+    }
+
+    public CasAuthenticationToken setTestCasAuthenticationToken() {
+        SecurityUtils.Secret secret = SecurityUtils.generatePrivateSymmetricKey();
+        List<SMPAuthority> smpAuthorities = Collections.singletonList(SMPAuthority.S_AUTHORITY_SMP_ADMIN);
+        CasAuthenticationToken token = new CasAuthenticationToken("test", "test", "test", smpAuthorities,
+                new SMPUserDetails(null, secret, smpAuthorities), Mockito.mock(Assertion.class));
+        SecurityContextHolder.getContext().setAuthentication(token);
+        return token;
+    }
+}
\ No newline at end of file
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/X509CertificateUtilsTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/X509CertificateUtilsTest.java
index 5166855b9..cc310f525 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/X509CertificateUtilsTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/utils/X509CertificateUtilsTest.java
@@ -16,10 +16,10 @@
 package eu.europa.ec.edelivery.smp.utils;
 
 
+import eu.europa.ec.edelivery.security.utils.X509CertificateUtils;
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.time.DateUtils;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -36,7 +36,10 @@ import java.util.List;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
-
+/**
+ * @author Joze Rihtarsic
+ * @since 4.1
+ */
 @RunWith(JUnitParamsRunner.class)
 public class X509CertificateUtilsTest {
 
diff --git a/smp-webapp/pom.xml b/smp-webapp/pom.xml
index 4658db474..50879cc6a 100644
--- a/smp-webapp/pom.xml
+++ b/smp-webapp/pom.xml
@@ -103,10 +103,6 @@
             <artifactId>hamcrest-junit</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>org.springframework.security</groupId>
-            <artifactId>spring-security-cas</artifactId>
-        </dependency>
     </dependencies>
 
     <build>
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProvider.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProvider.java
index 6dc991bac..fc4fa5f2d 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProvider.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProvider.java
@@ -5,6 +5,7 @@ import eu.europa.ec.edelivery.security.cert.CertificateValidator;
 import eu.europa.ec.edelivery.smp.data.dao.UserDao;
 import eu.europa.ec.edelivery.smp.data.model.DBCertificate;
 import eu.europa.ec.edelivery.smp.data.model.DBUser;
+import eu.europa.ec.edelivery.smp.data.ui.UserRO;
 import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority;
 import eu.europa.ec.edelivery.smp.data.ui.enums.AlertSuspensionMomentEnum;
 import eu.europa.ec.edelivery.smp.data.ui.enums.CredentialTypeEnum;
@@ -19,7 +20,9 @@ import eu.europa.ec.edelivery.smp.services.ui.UITruststoreService;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.convert.ConversionService;
 import org.springframework.security.authentication.*;
+import org.springframework.security.cas.web.CasAuthenticationFilter;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.crypto.bcrypt.BCrypt;
@@ -60,12 +63,8 @@ public class SMPAuthenticationProvider implements AuthenticationProvider {
      */
     private static final ThreadLocal<DateFormat> dateFormatLocal = ThreadLocal.withInitial(() -> new SimpleDateFormat("MMM d hh:mm:ss yyyy zzz", US));
 
-    // generate dummyPassword hash just to mimic password validation to disable attacker to discover
-    // usernames because of different response times if password or username is wrong
-    private final String dummyPasswordHash;
-    private final String dummyPassword;
-
     final UserDao mUserDao;
+    final ConversionService conversionService;
     final CRLVerifierService crlVerifierService;
     final UITruststoreService truststoreService;
     final ConfigurationService configurationService;
@@ -73,13 +72,13 @@ public class SMPAuthenticationProvider implements AuthenticationProvider {
 
     @Autowired
     public SMPAuthenticationProvider(UserDao mUserDao,
+                                     ConversionService conversionService,
                                      CRLVerifierService crlVerifierService,
                                      UITruststoreService truststoreService,
                                      ConfigurationService configurationService,
                                      AlertService alertService) {
-        this.dummyPassword = UUID.randomUUID().toString();
-        this.dummyPasswordHash = BCrypt.hashpw(dummyPassword, BCrypt.gensalt());
         this.mUserDao = mUserDao;
+        this.conversionService = conversionService;
         this.crlVerifierService = crlVerifierService;
         this.truststoreService = truststoreService;
         this.configurationService = configurationService;
@@ -101,7 +100,8 @@ public class SMPAuthenticationProvider implements AuthenticationProvider {
             }
         } else if (authenticationToken instanceof UsernamePasswordAuthenticationToken) {
             LOG.info("try to authentication Token: [{}] with user:[{}]" , authenticationToken.getClass(), authenticationToken.getPrincipal());
-            if ("_cas_stateful_".equalsIgnoreCase((String)authenticationToken.getPrincipal())){
+            if (CasAuthenticationFilter.CAS_STATEFUL_IDENTIFIER.equalsIgnoreCase((String)authenticationToken.getPrincipal())
+             || CasAuthenticationFilter.CAS_STATELESS_IDENTIFIER.equalsIgnoreCase((String)authenticationToken.getPrincipal())){
                 LOG.debug("Ignore CAS authentication and leave it to cas authentication module");
                 return null;
             }
@@ -127,7 +127,6 @@ public class SMPAuthenticationProvider implements AuthenticationProvider {
      */
     public Authentication authenticateByCertificateToken(PreAuthenticatedCertificatePrincipal principal) {
         LOG.info("authenticateByCertificateToken:" + principal.getName());
-
         KeyStore truststore = truststoreService.getTrustStore();
 
         DBUser user;
@@ -209,13 +208,27 @@ public class SMPAuthenticationProvider implements AuthenticationProvider {
         // get role
         String role = "WS_" + user.getRole();
         LOG.securityInfo(SMPMessageCode.SEC_USER_AUTHENTICATED, userToken, role);
-        SMPCertificateAuthentication authentication = new SMPCertificateAuthentication(principal, Collections.singletonList(new SMPAuthority(role)), user);
+        SMPCertificateAuthentication authentication = new SMPCertificateAuthentication(principal, Collections.singletonList(
+                SMPAuthority.getAuthorityByRoleName(role)), user);
 
         authentication.setAuthenticated(true);
         return authentication;
     }
 
 
+    public void delayResponse(long startTime) {
+        int delayInMS = configurationService.getAccessTokenLoginFailDelayInMilliSeconds() -  (int) (Calendar.getInstance().getTimeInMillis() - startTime);
+        if (delayInMS > 0) {
+            try {
+                LOG.debug("Delay response for [{}] ms to mask password/username login failures!", delayInMS);
+                Thread.sleep(delayInMS);
+            } catch (InterruptedException ie) {
+                LOG.debug("Thread interrupted during sleep.", ie);
+                Thread.currentThread().interrupt();
+            }
+        }
+    }
+
     /**
      * Method tests if user account Suspended
      *
@@ -264,18 +277,17 @@ public class SMPAuthenticationProvider implements AuthenticationProvider {
 
         String authenticationTokenId = auth.getName();
         String authenticationTokenValue = auth.getCredentials().toString();
+        long startTime = Calendar.getInstance().getTimeInMillis();
 
         DBUser user;
         try {
             Optional<DBUser> oUsr = mUserDao.findUserByAuthenticationToken(authenticationTokenId);
             if (!oUsr.isPresent() || !oUsr.get().isActive()) {
                 LOG.securityWarn(SMPMessageCode.SEC_USER_NOT_EXISTS, authenticationTokenId);
-                //run validation on dummy password to achieve similar response time
-                // as it would be if the password is invalid
-                BCrypt.checkpw(dummyPassword, dummyPasswordHash);
 
                 //https://www.owasp.org/index.php/Authentication_Cheat_Sheet
                 // Do not reveal the status of an existing account. Not to use UsernameNotFoundException
+                delayResponse(startTime);
                 throw new BadCredentialsException(LOGIN_FAILED_MESSAGE);
             }
             user = oUsr.get();
@@ -292,7 +304,7 @@ public class SMPAuthenticationProvider implements AuthenticationProvider {
 
         try {
             if (!BCrypt.checkpw(authenticationTokenValue, user.getAccessToken())) {
-                loginAttemptForAccessTokenFailed(user);
+                loginAttemptForAccessTokenFailed(user, startTime);
             }
             user.setSequentialTokenLoginFailureCount(0);
             user.setLastTokenFailedLoginAttempt(null);
@@ -302,14 +314,21 @@ public class SMPAuthenticationProvider implements AuthenticationProvider {
             LOG.securityWarn(SMPMessageCode.SEC_INVALID_PASSWORD, ex, authenticationTokenId);
             throw new BadCredentialsException(LOGIN_FAILED_MESSAGE);
         }
-        String role = "WS_" + user.getRole();
-        SMPAuthenticationToken smpAuthenticationToken = new SMPAuthenticationToken(authenticationTokenId, authenticationTokenValue, Collections.singletonList(new SMPAuthority(role)), user);
+        // the webservice authentication with corresponding web-service authority;
+        SMPAuthority authority = SMPAuthority.getAuthorityByRoleName("WS_" + user.getRole());
+        // the webservice authentication does not support session set the session secret is null!
+        SMPUserDetails userDetails = new SMPUserDetails(user, null,  Collections.singletonList(authority));
+
+        SMPAuthenticationToken smpAuthenticationToken = new SMPAuthenticationToken(authenticationTokenId,
+                authenticationTokenValue,
+                userDetails);
+
+        LOG.securityInfo(SMPMessageCode.SEC_USER_AUTHENTICATED, authenticationTokenId, authority.getRole());
 
-        LOG.securityInfo(SMPMessageCode.SEC_USER_AUTHENTICATED, authenticationTokenId, role);
         return smpAuthenticationToken;
     }
 
-    public void loginAttemptForAccessTokenFailed(DBUser user) {
+    public void loginAttemptForAccessTokenFailed(DBUser user, long startTime) {
 
         user.setSequentialTokenLoginFailureCount(user.getSequentialTokenLoginFailureCount() != null ? user.getSequentialTokenLoginFailureCount() + 1 : 1);
         user.setLastTokenFailedLoginAttempt(OffsetDateTime.now());
@@ -326,6 +345,7 @@ public class SMPAuthenticationProvider implements AuthenticationProvider {
         } else {
             alertService.alertCredentialVerificationFailed(user, CredentialTypeEnum.ACCESS_TOKEN);
         }
+        delayResponse(startTime);
         throw new BadCredentialsException(LOGIN_FAILED_MESSAGE);
     }
 
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProviderForUI.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProviderForUI.java
index 4c5509fb4..8409a4fce 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProviderForUI.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProviderForUI.java
@@ -13,12 +13,13 @@ import eu.europa.ec.edelivery.smp.services.AlertService;
 import eu.europa.ec.edelivery.smp.services.CRLVerifierService;
 import eu.europa.ec.edelivery.smp.services.ConfigurationService;
 import eu.europa.ec.edelivery.smp.services.ui.UITruststoreService;
+import eu.europa.ec.edelivery.smp.utils.SecurityUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.convert.ConversionService;
 import org.springframework.security.authentication.AuthenticationProvider;
 import org.springframework.security.authentication.AuthenticationServiceException;
 import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.crypto.bcrypt.BCrypt;
@@ -26,6 +27,7 @@ import org.springframework.stereotype.Component;
 
 import java.time.OffsetDateTime;
 import java.time.temporal.ChronoUnit;
+import java.util.Calendar;
 import java.util.Collections;
 import java.util.Optional;
 
@@ -41,6 +43,7 @@ public class SMPAuthenticationProviderForUI implements AuthenticationProvider {
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(SMPAuthenticationProviderForUI.class);
 
     final UserDao mUserDao;
+    final ConversionService conversionService;
     final CRLVerifierService crlVerifierService;
     final UITruststoreService truststoreService;
     final ConfigurationService configurationService;
@@ -49,11 +52,13 @@ public class SMPAuthenticationProviderForUI implements AuthenticationProvider {
 
     @Autowired
     public SMPAuthenticationProviderForUI(UserDao mUserDao,
+                                          ConversionService conversionService,
                                           CRLVerifierService crlVerifierService,
                                           AlertService alertService,
                                           UITruststoreService truststoreService,
                                           ConfigurationService configurationService) {
         this.mUserDao = mUserDao;
+        this.conversionService = conversionService;
         this.crlVerifierService = crlVerifierService;
         this.alertService = alertService;
         this.truststoreService = truststoreService;
@@ -67,15 +72,17 @@ public class SMPAuthenticationProviderForUI implements AuthenticationProvider {
         Authentication authentication = null;
         // PreAuthentication token for the rest service certificate authentication
         LOG.debug("Authenticate authentication token type: [{}]", authenticationToken.getClass());
-        if (authenticationToken instanceof UsernamePasswordAuthenticationToken) {
-            authentication = authenticateByUsernamePassword((UsernamePasswordAuthenticationToken) authenticationToken);
+        if (authenticationToken instanceof UILoginAuthenticationToken) {
+            authentication = authenticateByUsernamePassword((UILoginAuthenticationToken) authenticationToken);
         }
         return authentication;
     }
 
-    public Authentication authenticateByUsernamePassword(UsernamePasswordAuthenticationToken auth)
+    public Authentication authenticateByUsernamePassword(UILoginAuthenticationToken auth)
             throws AuthenticationException {
 
+        long startTime = Calendar.getInstance().getTimeInMillis();
+
         String username = auth.getName();
         String userCredentialToken = auth.getCredentials().toString();
 
@@ -84,7 +91,9 @@ public class SMPAuthenticationProviderForUI implements AuthenticationProvider {
             Optional<DBUser> oUsr = mUserDao.findUserByUsername(username);
             if (!oUsr.isPresent()) {
                 LOG.debug("User with username does not exists [{}], continue with next authentication provider");
-                return null;
+                LOG.securityWarn(SMPMessageCode.SEC_INVALID_PASSWORD, "Username does not exits", username);
+                delayResponse(startTime);
+                throw new BadCredentialsException("Login failed; Invalid userID or password");
             }
             user = oUsr.get();
         } catch (AuthenticationException ex) {
@@ -99,11 +108,18 @@ public class SMPAuthenticationProviderForUI implements AuthenticationProvider {
 
         validateIfUserAccountIsSuspended(user);
 
+        SMPAuthority authority = SMPAuthority.getAuthorityByRoleName(user.getRole());
+        // the webservice authentication does not support session set the session secret is null!
+        SMPUserDetails userDetails = new SMPUserDetails(user,
+                SecurityUtils.generatePrivateSymmetricKey(),
+                Collections.singletonList(authority));
+
         String role = user.getRole();
-        SMPAuthenticationToken smpAuthenticationToken = new SMPAuthenticationToken(username, userCredentialToken, Collections.singletonList(new SMPAuthority(role)), user);
+        SMPAuthenticationToken smpAuthenticationToken = new SMPAuthenticationToken(username, userCredentialToken,
+                userDetails);
         try {
             if (!BCrypt.checkpw(userCredentialToken, user.getPassword())) {
-                loginAttemptForUserFailed(user);
+                loginAttemptForUserFailed(user, startTime);
             }
             user.setSequentialLoginFailureCount(0);
             user.setLastFailedLoginAttempt(null);
@@ -117,7 +133,20 @@ public class SMPAuthenticationProviderForUI implements AuthenticationProvider {
         return smpAuthenticationToken;
     }
 
-    public void loginAttemptForUserFailed(DBUser user) {
+    public void delayResponse(long startTime) {
+        int delayInMS = configurationService.getLoginFailDelayInMilliSeconds() - (int) (Calendar.getInstance().getTimeInMillis() - startTime);
+        if (delayInMS > 0) {
+            try {
+                LOG.debug("Delay response for [{}] ms to mask password/username login failures!", delayInMS);
+                Thread.sleep(delayInMS);
+            } catch (InterruptedException ie) {
+                LOG.debug("Thread interrupted during sleep.", ie);
+                Thread.currentThread().interrupt();
+            }
+        }
+    }
+
+    public void loginAttemptForUserFailed(DBUser user, long startTime) {
         user.setSequentialLoginFailureCount(user.getSequentialLoginFailureCount() != null ? user.getSequentialLoginFailureCount() + 1 : 1);
         user.setLastFailedLoginAttempt(OffsetDateTime.now());
         mUserDao.update(user);
@@ -128,6 +157,7 @@ public class SMPAuthenticationProviderForUI implements AuthenticationProvider {
         } else {
             alertService.alertCredentialVerificationFailed(user, CredentialTypeEnum.USERNAME_PASSWORD);
         }
+        delayResponse(startTime);
         throw new BadCredentialsException("Login failed; Invalid userID or password");
     }
 
@@ -176,7 +206,7 @@ public class SMPAuthenticationProviderForUI implements AuthenticationProvider {
     @Override
     public boolean supports(Class<?> auth) {
         LOG.info("Support authentication: " + auth);
-        boolean supportAuthentication = auth.equals(UsernamePasswordAuthenticationToken.class);
+        boolean supportAuthentication = auth.equals(UILoginAuthenticationToken.class);
         if (!supportAuthentication) {
             LOG.warn("SMP does not support authentication type: " + auth);
         }
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationService.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationService.java
index 992f9d13b..62faadc05 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationService.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationService.java
@@ -3,10 +3,8 @@ package eu.europa.ec.edelivery.smp.auth;
 import eu.europa.ec.edelivery.smp.config.SMPSecurityConstants;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.core.context.SecurityContextHolder;
@@ -21,20 +19,28 @@ import javax.servlet.http.HttpServletResponse;
 import static eu.europa.ec.edelivery.smp.utils.SMPCookieWriter.CSRF_COOKIE_NAME;
 import static eu.europa.ec.edelivery.smp.utils.SMPCookieWriter.SESSION_COOKIE_NAME;
 
+/**
+ * The UI authentication services for login ,logout, retrieving current session user etc.. The services are intended for
+ * stateful UI service calls.
+ *
+ * @author Joze Rihtarsic
+ * @since 4.1
+ */
 @Service
 public class SMPAuthenticationService {
-
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(SMPAuthenticationService.class);
 
-    @Autowired
-    @Qualifier(SMPSecurityConstants.SMP_UI_AUTHENTICATION_MANAGER_BEAN)
-    private AuthenticationManager authenticationManager;
+    private final AuthenticationManager authenticationManager;
+
+    public SMPAuthenticationService(@Qualifier(SMPSecurityConstants.SMP_UI_AUTHENTICATION_MANAGER_BEAN) AuthenticationManager authenticationManager) {
+        this.authenticationManager = authenticationManager;
+    }
 
     @Transactional(noRollbackFor = AuthenticationException.class)
     public Authentication authenticate(String username, String password) {
         LOG.debug("Authenticate: [{}]", username);
-        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
-        SMPAuthenticationToken authentication = (SMPAuthenticationToken) authenticationManager.authenticate(token);
+        UILoginAuthenticationToken token = new UILoginAuthenticationToken(username, password);
+        Authentication authentication = authenticationManager.authenticate(token);
         SecurityContextHolder.getContext().setAuthentication(authentication);
         return authentication;
     }
@@ -45,7 +51,6 @@ public class SMPAuthenticationService {
             LOG.debug("Cannot perform logout: no user is authenticated");
             return;
         }
-
         LOG.info("Logging out user [{}]", auth.getName());
         new CookieClearingLogoutHandler(SESSION_COOKIE_NAME, CSRF_COOKIE_NAME).logout(request, response, null);
         LOG.info("Cleared cookies");
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationService.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationService.java
index 3ac7d6209..3620970e1 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationService.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationService.java
@@ -1,26 +1,31 @@
 package eu.europa.ec.edelivery.smp.auth;
 
+import eu.europa.ec.edelivery.smp.data.dao.UserDao;
+import eu.europa.ec.edelivery.smp.data.model.DBUser;
 import eu.europa.ec.edelivery.smp.data.ui.UserRO;
 import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority;
 import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
+import eu.europa.ec.edelivery.smp.services.ConfigurationService;
 import eu.europa.ec.edelivery.smp.services.ServiceGroupService;
 import eu.europa.ec.edelivery.smp.utils.SessionSecurityUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.springframework.core.convert.ConversionService;
 import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.cas.authentication.CasAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.web.authentication.session.SessionAuthenticationException;
 import org.springframework.stereotype.Service;
 
+import java.time.OffsetDateTime;
 import java.util.stream.Collectors;
 
 import static eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority.*;
 
 /**
  * @author Sebastian-Ion TINCU
+ * @since 4.1
  */
 @Service("smpAuthorizationService")
 public class SMPAuthorizationService {
@@ -28,27 +33,36 @@ public class SMPAuthorizationService {
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(SMPAuthorizationService.class);
 
     final private ServiceGroupService serviceGroupService;
-
-    public SMPAuthorizationService(ServiceGroupService serviceGroupService) {
+    final private ConversionService conversionService;
+    final private ConfigurationService configurationService;
+    final private UserDao userDao;
+
+    public SMPAuthorizationService(ServiceGroupService serviceGroupService,
+                                   ConversionService conversionService,
+                                   ConfigurationService configurationService,
+                                   UserDao userDao) {
         this.serviceGroupService = serviceGroupService;
+        this.conversionService = conversionService;
+        this.configurationService=configurationService;
+        this.userDao = userDao;
     }
 
     public boolean isSystemAdministrator() {
-        SMPAuthenticationToken authentication = getAndValidateSessionAuthentication();
-        boolean hasSystemRole = hasSessionUserRole(S_AUTHORITY_TOKEN_SYSTEM_ADMIN, authentication);
-        LOG.debug("Logged user [{}] is system administrator role [{}]", authentication.getUser().getUsername(), hasSystemRole);
+        SMPUserDetails userDetails = getAndValidateUserDetails();
+        boolean hasSystemRole = hasSessionUserRole(S_AUTHORITY_TOKEN_SYSTEM_ADMIN, userDetails);
+        LOG.debug("Logged user [{}] is system administrator role [{}]", userDetails.getUsername(), hasSystemRole);
         return hasSystemRole;
     }
 
     public boolean isSMPAdministrator() {
-        SMPAuthenticationToken authentication = getAndValidateSessionAuthentication();
-        boolean hasSystemRole = hasSessionUserRole(S_AUTHORITY_TOKEN_SMP_ADMIN, authentication);
-        LOG.debug("Logged user [{}] is SMP administrator role [{}]", authentication.getUser().getUsername(), hasSystemRole);
-        return hasSystemRole;
+        SMPUserDetails userDetails = getAndValidateUserDetails();
+        boolean hasRole = hasSessionUserRole(S_AUTHORITY_TOKEN_SMP_ADMIN, userDetails);
+        LOG.debug("Logged user [{}] is SMP administrator role [{}]", userDetails.getUsername(), hasRole);
+        return hasRole;
     }
 
     public boolean isCurrentlyLoggedIn(String userId) {
-        SMPAuthenticationToken authentication = getAndValidateSessionAuthentication();
+        SMPUserDetails userDetails = getAndValidateUserDetails();
         Long entityId;
         try {
             entityId = SessionSecurityUtils.decryptEntityId(userId);
@@ -56,26 +70,32 @@ public class SMPAuthorizationService {
             LOG.error("Error occurred while decrypting user-id:[" + userId + "]", ex);
             throw new BadCredentialsException("Login failed; Invalid userID or password");
         }
-        Long loggedUserId = authentication.getUser().getId();
-        return entityId.equals(loggedUserId);
+        return entityId.equals(userDetails.getUser().getId());
 
     }
 
     public boolean isAuthorizedForManagingTheServiceMetadataGroup(Long serviceMetadataId) {
-        SMPAuthenticationToken authentication = getAndValidateSessionAuthentication();
-        if (hasSessionUserRole(S_AUTHORITY_TOKEN_SMP_ADMIN, authentication)) {
+        SMPUserDetails userDetails = getAndValidateUserDetails();
+        if (hasSessionUserRole(S_AUTHORITY_TOKEN_SMP_ADMIN, userDetails)) {
             LOG.debug("SMP admin is authorized to manage service metadata: [{}]" + serviceMetadataId);
             return true;
 
         }
-        if (!hasSessionUserRole(S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN, authentication)) {
+        if (!hasSessionUserRole(S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN, userDetails)) {
             LOG.debug("User is Service group admin nor SMP admin. User is not allowed to manage service metadata: [{}]" + serviceMetadataId);
             return false;
         }
-        Long userId = authentication.getUser().getId();
+        Long userId = userDetails.getUser().getId();
         return serviceGroupService.isServiceGroupOwnerForMetadataID(userId, serviceMetadataId);
     }
 
+
+    private boolean hasSessionUserRole(String role, SMPUserDetails userDetails) {
+        return userDetails.getAuthorities().stream().anyMatch(grantedAuthority ->
+                StringUtils.equals(role, grantedAuthority.getAuthority())
+        );
+    }
+
     /**
      * Returns a user resource with password credentials removed and authorities populated for use in the front-end.
      *
@@ -86,41 +106,52 @@ public class SMPAuthorizationService {
         userRO.setPassword("");
 
         Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-        if (authentication!=null ){
+        if (authentication != null) {
             userRO.setAuthorities(authentication.getAuthorities().stream().map(val -> (SMPAuthority) val).collect(Collectors.toList()));
         }
         return userRO;
     }
 
-    private Authentication getSessionAuthentication() {
-        if (SecurityContextHolder.getContext() == null) {
-            LOG.warn("No users is logged-in! Session security context is null!");
-            return null;
-        }
-        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-        if (authentication == null || !authentication.isAuthenticated()) {
-            LOG.warn("No users is logged-in! Authentication is null or not authenticated!");
-            return null;
+    public SMPUserDetails getAndValidateUserDetails() {
+        SMPUserDetails userDetails = SessionSecurityUtils.getSessionUserDetails();
+        if (userDetails == null) {
+            throw new SessionAuthenticationException(ERR_INVALID_OR_NULL);
         }
-        if (!(authentication instanceof SMPAuthenticationToken
-                || authentication instanceof CasAuthenticationToken)) {
-            LOG.warn("User is logged and authenticated with not supported Authentication [{}]!", authentication.getClass());
+        return userDetails;
+    }
+
+    public UserRO getLoggedUserData() {
+        SMPUserDetails userDetails = getAndValidateUserDetails();
+        // refresh data from database!
+        DBUser dbUser =userDao.find(userDetails.getUser().getId());
+        if (dbUser == null || !dbUser.isActive()) {
+            LOG.warn("User: [{}] with id [{}] does not exists anymore or is not active.",
+                    userDetails.getUser().getId(),
+                    userDetails.getUser().getUsername());
             return null;
         }
-        return authentication;
+        return getUserData(userDetails.getUser());
     }
 
-    private Authentication getAndValidateSessionAuthentication() {
-        Authentication authentication = getSessionAuthentication();
-        if (authentication == null) {
-            throw new SessionAuthenticationException(ERR_INVALID_OR_NULL);
-        }
-        return authentication;
+    public UserRO getUserData(DBUser user) {
+        UserRO userRO = conversionService.convert(user, UserRO.class);
+        return getUpdatedUserData(userRO);
     }
 
-    private boolean hasSessionUserRole(String role, SMPAuthenticationToken authentication) {
-        return authentication.getAuthorities().stream().anyMatch(grantedAuthority ->
-                StringUtils.equals(role, grantedAuthority.getAuthority())
-        );
+    /**
+     * Method updates data with "show expire dialog" flag, forces the password change flag and
+     * sanitize ui data/
+     *
+     * @param userRO
+     * @return updated user data according to SMP configuration
+     */
+    protected UserRO getUpdatedUserData(UserRO userRO) {
+        userRO.setShowPasswordExpirationWarning(userRO.getPasswordExpireOn() != null &&
+                OffsetDateTime.now()
+                        .minusDays(configurationService.getPasswordPolicyUIWarningDaysBeforeExpire())
+                        .isBefore(userRO.getPasswordExpireOn()));
+
+        userRO.setForceChangePassword(userRO.isPasswordExpired() && configurationService.getPasswordPolicyForceChangeIfExpired());
+        return sanitize(userRO);
     }
 }
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/cas/SMPCasUserService.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/cas/SMPCasUserService.java
index eab8b8425..a853e34f5 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/cas/SMPCasUserService.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/cas/SMPCasUserService.java
@@ -1,10 +1,12 @@
 package eu.europa.ec.edelivery.smp.auth.cas;
 
+import eu.europa.ec.edelivery.smp.auth.SMPUserDetails;
 import eu.europa.ec.edelivery.smp.data.model.DBUser;
-import eu.europa.ec.edelivery.smp.data.ui.UserRO;
+
 import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority;
 import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
 import eu.europa.ec.edelivery.smp.services.ui.UIUserService;
+import eu.europa.ec.edelivery.smp.utils.SecurityUtils;
 import org.jasig.cas.client.authentication.AttributePrincipal;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -47,23 +49,25 @@ public class SMPCasUserService implements AuthenticationUserDetailsService<CasAs
 	public UserDetails loadUserDetails(CasAssertionAuthenticationToken token) throws UsernameNotFoundException {
 		
 		AttributePrincipal principal = token.getAssertion().getPrincipal();
+		// the cas id must match with username
 		String username = principal.getName();
-		LOG.info("Principal name:  "+username);
-		LOG.info("Principal:  "+principal);
+		LOG.debug("Got CAS user with principal name: [{}]", username);
 		Map<String, Object> attributes = principal.getAttributes();
 		for(Map.Entry<String, Object> attribute : attributes.entrySet()) {
-			LOG.info("Principal attribute "+attribute.getKey()+"="+attribute.getValue());
+			LOG.debug("Principal attribute [{}]=[{}] ", attribute.getKey(), attribute.getValue());
 		}
+
 		DBUser dbuser;
 		try {
 			dbuser = uiUserService.findUserByUsername(username);
 		} catch (SMPRuntimeException ex) {
 			throw new UsernameNotFoundException("User with the username ["+username+"] is not registered in SMP", ex);
 		}
-		UserRO userRo = uiUserService.convertToRo(dbuser);
-		userRo.setCasAuthenticated(true);
-		userRo.setPassword(null);
-		userRo.setAuthorities(Collections.singletonList(new SMPAuthority(userRo.getRole())));
-		return userRo;
+		SMPAuthority authority = SMPAuthority.getAuthorityByRoleName(dbuser.getRole());
+		// generate secret for the session
+		SMPUserDetails smpUserDetails = new SMPUserDetails(dbuser, SecurityUtils.generatePrivateSymmetricKey(),Collections.singletonList(authority));
+		smpUserDetails.setCasAuthenticated(true);
+		LOG.info("Return authenticated user details for username: [{}]", username);
+		return smpUserDetails;
 	}
 }
\ No newline at end of file
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResource.java
index 11a02caad..6aaebf73a 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResource.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResource.java
@@ -4,6 +4,7 @@ package eu.europa.ec.edelivery.smp.ui;
 import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationService;
 import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationToken;
 import eu.europa.ec.edelivery.smp.auth.SMPAuthorizationService;
+import eu.europa.ec.edelivery.smp.auth.SMPUserDetails;
 import eu.europa.ec.edelivery.smp.data.model.DBUser;
 import eu.europa.ec.edelivery.smp.data.ui.LoginRO;
 import eu.europa.ec.edelivery.smp.data.ui.UserRO;
@@ -17,6 +18,7 @@ import org.springframework.core.convert.ConversionService;
 import org.springframework.security.access.annotation.Secured;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.web.csrf.CsrfToken;
 import org.springframework.security.web.csrf.CsrfTokenRepository;
 import org.springframework.transaction.annotation.Transactional;
@@ -39,6 +41,7 @@ import static eu.europa.ec.edelivery.smp.utils.SMPCookieWriter.SESSION_COOKIE_NA
 public class AuthenticationResource {
 
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(AuthenticationResource.class);
+    public static final String RELATIVE_BASE_ENTRY="../../../#/";
 
     private UIUserService uiUserService;
 
@@ -46,8 +49,6 @@ public class AuthenticationResource {
 
     protected SMPAuthorizationService authorizationService;
 
-    private ConversionService conversionService;
-
     private ConfigurationService configurationService;
 
     private CsrfTokenRepository csrfTokenRepository;
@@ -57,14 +58,12 @@ public class AuthenticationResource {
     @Autowired
     public AuthenticationResource(SMPAuthenticationService authenticationService
             , SMPAuthorizationService authorizationService
-            , ConversionService conversionService
             , ConfigurationService configurationService
             , SMPCookieWriter smpCookieWriter
             , CsrfTokenRepository csrfTokenRepository
             , UIUserService uiUserService) {
         this.authenticationService = authenticationService;
         this.authorizationService = authorizationService;
-        this.conversionService = conversionService;
         this.configurationService = configurationService;
         this.smpCookieWriter = smpCookieWriter;
         this.csrfTokenRepository = csrfTokenRepository;
@@ -80,9 +79,11 @@ public class AuthenticationResource {
         CsrfToken csfrToken = csrfTokenRepository.generateToken(request);
         csrfTokenRepository.saveToken(csfrToken, request, response);
 
-        SMPAuthenticationToken authentication = (SMPAuthenticationToken) authenticationService.authenticate(loginRO.getUsername(), loginRO.getPassword());
-        DBUser user = authentication.getUser();
-        return getUserData(user);
+        SMPAuthenticationToken authentication = (SMPAuthenticationToken) authenticationService.authenticate(loginRO.getUsername(),
+                loginRO.getPassword());
+        SMPUserDetails user = authentication.getUserDetails();
+
+        return authorizationService.getUserData(user.getUser());
     }
 
     @DeleteMapping(value = "authentication")
@@ -103,50 +104,15 @@ public class AuthenticationResource {
     public RedirectView authenticateCAS() {
         LOG.debug("Authenticating cas");
         // if user was able to access resource - redirect back to main page
-        return new RedirectView("../../../#/");
+        return new RedirectView(RELATIVE_BASE_ENTRY);
     }
 
     @GetMapping(value = "user")
     @Secured({S_AUTHORITY_TOKEN_SYSTEM_ADMIN, S_AUTHORITY_TOKEN_SMP_ADMIN, S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN})
-    public UserRO getUser(HttpServletRequest request, HttpServletResponse response) {
-
-        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
-        if (principal instanceof UserRO) {
-            return getUpdatedUserData((UserRO) principal);
-        }
-
-        String username = (String) principal;
-        LOG.debug("get user: [{}]", username);
-        DBUser user = uiUserService.findUserByUsername(username);
-
-        if (user == null || !user.isActive()) {
-            LOG.warn("User: [{}] does not exists anymore or is not active.", username);
-            return null;
-        }
-        return getUserData(user);
-    }
-
-    protected UserRO getUserData(DBUser user) {
-        UserRO userRO = conversionService.convert(user, UserRO.class);
-        return getUpdatedUserData(userRO);
+    public UserRO getUser() {
+        return authorizationService.getLoggedUserData();
     }
 
-    /**
-     * Method updates data with "show expire dialog" flag, forces the password change flag and
-     * sanitize ui data/
-     *
-     * @param userRO
-     * @return updated user data according to SMP configuration
-     */
-    protected UserRO getUpdatedUserData(UserRO userRO) {
-        userRO.setShowPasswordExpirationWarning(userRO.getPasswordExpireOn() != null &&
-                OffsetDateTime.now()
-                        .minusDays(configurationService.getPasswordPolicyUIWarningDaysBeforeExpire())
-                        .isBefore(userRO.getPasswordExpireOn()));
-
-        userRO.setForceChangePassword(userRO.isPasswordExpired() && configurationService.getPasswordPolicyForceChangeIfExpired());
-        return authorizationService.sanitize(userRO);
-    }
 
     /**
      * set cookie parameters https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
@@ -160,7 +126,8 @@ public class AuthenticationResource {
 //        String sessionId = request.changeSessionId();
         smpCookieWriter.writeCookieToResponse(SESSION_COOKIE_NAME,
                 sessionId,
-                configurationService.getSessionCookieSecure(), configurationService.getSessionCookieMaxAge(),
+                configurationService.getSessionCookieSecure(),
+                configurationService.getSessionCookieMaxAge(),
                 configurationService.getSessionCookiePath(),
                 configurationService.getSessionCookieSameSite(),
                 request, response
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/ServiceGroupResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/ServiceGroupResource.java
index 23e59f234..f0b73d770 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/ServiceGroupResource.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/ServiceGroupResource.java
@@ -1,24 +1,22 @@
 package eu.europa.ec.edelivery.smp.ui.external;
 
 
-import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationToken;
+import eu.europa.ec.edelivery.smp.auth.SMPAuthorizationService;
+import eu.europa.ec.edelivery.smp.auth.SMPUserDetails;
 import eu.europa.ec.edelivery.smp.data.dao.DomainDao;
-import eu.europa.ec.edelivery.smp.data.model.DBUser;
+import eu.europa.ec.edelivery.smp.data.dao.UserDao;
 import eu.europa.ec.edelivery.smp.data.ui.ServiceGroupRO;
 import eu.europa.ec.edelivery.smp.data.ui.ServiceGroupValidationRO;
 import eu.europa.ec.edelivery.smp.data.ui.ServiceResult;
 import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority;
-import eu.europa.ec.edelivery.smp.data.ui.auth.SMPRole;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 import eu.europa.ec.edelivery.smp.services.ui.UIServiceGroupService;
 import eu.europa.ec.edelivery.smp.services.ui.filters.ServiceGroupFilter;
 import eu.europa.ec.edelivery.smp.ui.ResourceConstants;
+import eu.europa.ec.edelivery.smp.utils.SessionSecurityUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.annotation.Secured;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.util.MimeTypeUtils;
 import org.springframework.web.bind.annotation.*;
 
@@ -33,22 +31,27 @@ import static eu.europa.ec.edelivery.smp.ui.ResourceConstants.*;
  * @author Joze Rihtarsic
  * @since 4.1
  */
-
 @RestController
 @RequestMapping(value = ResourceConstants.CONTEXT_PATH_PUBLIC_SERVICE_GROUP)
 public class ServiceGroupResource {
 
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(ServiceGroupResource.class);
 
-    @Autowired
-    private UIServiceGroupService uiServiceGroupService;
-    @Autowired
-    private DomainDao domainDao;
+    final private UIServiceGroupService uiServiceGroupService;
+    final private DomainDao domainDao;
+    final private UserDao userDao;
+    final private SMPAuthorizationService authorizationService;
+
+    public ServiceGroupResource(UIServiceGroupService uiServiceGroupService, DomainDao domainDao, UserDao userDao, SMPAuthorizationService authorizationService) {
+        this.uiServiceGroupService = uiServiceGroupService;
+        this.domainDao = domainDao;
+        this.userDao = userDao;
+        this.authorizationService = authorizationService;
+    }
 
     @GetMapping(produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
     @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN})
     public ServiceResult<ServiceGroupRO> getServiceGroupList(
-            HttpServletRequest request,
             @RequestParam(value = PARAM_PAGINATION_PAGE, defaultValue = "0") int page,
             @RequestParam(value = PARAM_PAGINATION_PAGE_SIZE, defaultValue = "10") int pageSize,
             @RequestParam(value = PARAM_PAGINATION_ORDER_BY, required = false) String orderBy,
@@ -70,19 +73,17 @@ public class ServiceGroupResource {
         sgf.setDomain(domainDao.validateDomainCode(domainCodeDecoded));
 
         // check if logged user is ServiceGroup admin if yes return only his servicegroups
-        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-
         // show all service groups only for SMP Admin
         // SMP admin can edit all service groups. For others return only services groups they own.
-        if (!request.isUserInRole(SMPRole.SMP_ADMIN.getCode())) {
-            SMPAuthenticationToken authToken = (SMPAuthenticationToken) authentication;
-            DBUser user = authToken.getUser();
-            sgf.setOwner(user);
+        if (!authorizationService.isSMPAdministrator()) {
+            authorizationService.getAndValidateUserDetails();
+            SMPUserDetails user = SessionSecurityUtils.getSessionUserDetails();
+            sgf.setOwner(userDao.find(user.getUser().getId()));
         }
         return uiServiceGroupService.getTableList(page, pageSize, orderBy, orderType, sgf);
     }
 
-    @GetMapping( path = "{serviceGroupId}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+    @GetMapping(path = "{serviceGroupId}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
     @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN, SMPAuthority.S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN})
     public ServiceGroupRO getServiceGroupById(@PathVariable Long serviceGroupId) {
         LOG.info("Get service group [{}]", serviceGroupId);
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/TruststoreResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/TruststoreResource.java
index 99c6290e5..dcea2481e 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/TruststoreResource.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/TruststoreResource.java
@@ -1,29 +1,16 @@
 package eu.europa.ec.edelivery.smp.ui.external;
 
 import eu.europa.ec.edelivery.smp.data.ui.CertificateRO;
-import eu.europa.ec.edelivery.smp.data.ui.KeystoreImportResult;
-import eu.europa.ec.edelivery.smp.data.ui.ServiceResult;
-import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority;
-import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 import eu.europa.ec.edelivery.smp.services.PayloadValidatorService;
 import eu.europa.ec.edelivery.smp.services.ui.UITruststoreService;
 import eu.europa.ec.edelivery.smp.ui.ResourceConstants;
-import eu.europa.ec.edelivery.smp.utils.X509CertificateUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.annotation.Secured;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.util.MimeTypeUtils;
 import org.springframework.web.bind.annotation.*;
 
 import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.List;
 
 /**
  * @author Joze Rihtarsic
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/TruststoreAdminResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/TruststoreAdminResource.java
index 59d138eb1..8c325dd3d 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/TruststoreAdminResource.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/TruststoreAdminResource.java
@@ -1,5 +1,6 @@
 package eu.europa.ec.edelivery.smp.ui.internal;
 
+import eu.europa.ec.edelivery.security.utils.X509CertificateUtils;
 import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority;
 import eu.europa.ec.edelivery.smp.data.ui.CertificateRO;
 import eu.europa.ec.edelivery.smp.data.ui.KeystoreImportResult;
@@ -10,7 +11,6 @@ import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 import eu.europa.ec.edelivery.smp.services.PayloadValidatorService;
 import eu.europa.ec.edelivery.smp.services.ui.UITruststoreService;
 import eu.europa.ec.edelivery.smp.ui.ResourceConstants;
-import eu.europa.ec.edelivery.smp.utils.X509CertificateUtils;
 import org.springframework.security.access.annotation.Secured;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.util.MimeTypeUtils;
@@ -73,7 +73,7 @@ public class TruststoreAdminResource {
         CertificateRO certificateRO=null;
         try {
             x509Certificate = X509CertificateUtils.getX509Certificate(fileBytes);
-        } catch (SMPRuntimeException e) {
+        } catch (SMPRuntimeException | CertificateException e) {
             LOG.error("Error occurred while parsing certificate.", e);
             return certificateRO;
         }
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/UserAdminResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/UserAdminResource.java
index 259c012a1..ed946f78d 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/UserAdminResource.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/UserAdminResource.java
@@ -2,6 +2,7 @@ package eu.europa.ec.edelivery.smp.ui.internal;
 
 import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationToken;
 import eu.europa.ec.edelivery.smp.auth.SMPAuthorizationService;
+import eu.europa.ec.edelivery.smp.auth.SMPUserDetails;
 import eu.europa.ec.edelivery.smp.data.model.DBUser;
 import eu.europa.ec.edelivery.smp.data.ui.DeleteEntityValidation;
 import eu.europa.ec.edelivery.smp.data.ui.ServiceResult;
@@ -73,10 +74,10 @@ public class UserAdminResource {
     @PostMapping(value = "validate-delete", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
     @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN})
     public DeleteEntityValidation validateDeleteUsers(@RequestBody List<String> queryEncIds) {
-        DBUser user = getCurrentUser();
+        SMPUserDetails userDetails = getLoggedUserData();
         List<Long> query = queryEncIds.stream().map(SessionSecurityUtils::decryptEntityId).collect(Collectors.toList());
         DeleteEntityValidation dres = new DeleteEntityValidation();
-        if (query.contains(user.getId())) {
+        if (query.contains(userDetails.getUser().getId())) {
             dres.setValidOperation(false);
             dres.setStringMessage("Could not delete logged user!");
             return dres;
@@ -85,9 +86,7 @@ public class UserAdminResource {
         return uiUserService.validateDeleteRequest(dres);
     }
 
-    private DBUser getCurrentUser() {
-        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-        SMPAuthenticationToken authToken = (SMPAuthenticationToken) authentication;
-        return authToken.getUser();
+    private SMPUserDetails getLoggedUserData() {
+        return authorizationService.getAndValidateUserDetails();
     }
 }
diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProviderTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProviderTest.java
index 5ab349dfd..6761cdcda 100644
--- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProviderTest.java
+++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProviderTest.java
@@ -9,6 +9,7 @@ import eu.europa.ec.edelivery.smp.services.ui.UITruststoreService;
 import org.hamcrest.Matchers;
 import org.junit.Test;
 import org.mockito.Mockito;
+import org.springframework.core.convert.ConversionService;
 import org.springframework.security.authentication.AuthenticationServiceException;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -21,15 +22,21 @@ import static org.junit.Assert.assertThat;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doReturn;
 
+/**
+ * @author Joze Rihtarsic
+ * @since 4.2
+ */
 public class SMPAuthenticationProviderTest {
 
     UserDao mockUserDao = Mockito.mock(UserDao.class);
+    ConversionService mockConversionService = Mockito.mock(ConversionService.class);
     CRLVerifierService mockCrlVerifierService = Mockito.mock(CRLVerifierService.class);
     UITruststoreService mockTruststoreService = Mockito.mock(UITruststoreService.class);
     ConfigurationService mockConfigurationService = Mockito.mock(ConfigurationService.class);
     AlertService mocAlertService = Mockito.mock(AlertService.class);
 
     SMPAuthenticationProvider testInstance = new SMPAuthenticationProvider(mockUserDao,
+            mockConversionService,
             mockCrlVerifierService,
             mockTruststoreService,
             mockConfigurationService,
@@ -44,9 +51,11 @@ public class SMPAuthenticationProviderTest {
         user.setAccessTokenIdentifier("User");
         user.setAccessToken(BCrypt.hashpw("InvalidPassword", BCrypt.gensalt()));
         user.setRole("MY_ROLE");
+        doReturn(500).when(mockConfigurationService).getAccessTokenLoginFailDelayInMilliSeconds();
+
 
         doReturn(Optional.of(user)).when(mockUserDao).findUserByIdentifier(any());
-        int count = 100;
+        int count = 10;
         long averageExists = 0;
         long averageNotExist = 0;
         for (int i = 0; i < count; i++) {
@@ -70,7 +79,7 @@ public class SMPAuthenticationProviderTest {
 
         // the average should be the same!
         assertThat("average difference between failed login must be less than 10ms", Math.abs(averageExists - averageNotExist),
-                Matchers.lessThan(1000L));
+                Matchers.lessThan(20L));
 
     }
 }
\ No newline at end of file
diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationServiceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationServiceTest.java
index 29a5eef11..ff29e08e4 100644
--- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationServiceTest.java
+++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationServiceTest.java
@@ -1,44 +1,62 @@
 package eu.europa.ec.edelivery.smp.auth;
 
+import eu.europa.ec.edelivery.smp.data.dao.UserDao;
 import eu.europa.ec.edelivery.smp.data.model.DBUser;
+import eu.europa.ec.edelivery.smp.data.ui.UserRO;
 import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority;
+import eu.europa.ec.edelivery.smp.services.ConfigurationService;
 import eu.europa.ec.edelivery.smp.services.ServiceGroupService;
 import eu.europa.ec.edelivery.smp.utils.SessionSecurityUtils;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.mockito.Mock;
 import org.mockito.Mockito;
+import org.springframework.core.convert.ConversionService;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
 
+import java.time.OffsetDateTime;
 import java.util.Collections;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 
+
 public class SMPAuthorizationServiceTest {
 
-    DBUser user = null;
+    UserRO user = null;
     SecurityContext mockSecurityContextSystemAdmin = null;
     SecurityContext mockSecurityContextSMPAdmin = null;
     SecurityContext mockSecurityContextSGAdmin = null;
     ServiceGroupService serviceGroupService = Mockito.mock(ServiceGroupService.class);
+    ConversionService conversionService = Mockito.mock(ConversionService.class);
+    ConfigurationService configurationService = Mockito.mock(ConfigurationService.class);
+    UserDao userDao = Mockito.mock(UserDao.class);
 
-    SMPAuthorizationService testInstance = new SMPAuthorizationService(serviceGroupService);
+    SMPAuthorizationService testInstance = new SMPAuthorizationService(serviceGroupService, conversionService,
+            configurationService, userDao);
 
 
     @Before
     public void setup() {
 
-        user = new DBUser();
-        user.setId((long) 10);
-
+        user = new UserRO();
+        SMPUserDetails sysUserDetails = new SMPUserDetails(new DBUser() {{
+            setId(10L);
+            setUsername("sys_admin");
+        }}, null, Collections.singletonList(SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN));
+        SMPUserDetails smpUserDetails = new SMPUserDetails(new DBUser() {{
+            setUsername("smp_admin");
+        }}, null, Collections.singletonList(SMPAuthority.S_AUTHORITY_SMP_ADMIN));
+        SMPUserDetails sgUserDetails = new SMPUserDetails(new DBUser() {{
+            setUsername("smp_admin");
+        }}, null, Collections.singletonList(SMPAuthority.S_AUTHORITY_SERVICE_GROUP));
 
         mockSecurityContextSystemAdmin = new SecurityContext() {
-            SMPAuthenticationToken smpa = new SMPAuthenticationToken("sys_admin", "test123", Collections.singletonList(SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN), user);
+            SMPAuthenticationToken smpa = new SMPAuthenticationToken("sg_admin", "test123", sysUserDetails);
 
             @Override
             public Authentication getAuthentication() {
@@ -50,7 +68,7 @@ public class SMPAuthorizationServiceTest {
             }
         };
         mockSecurityContextSMPAdmin = new SecurityContext() {
-            SMPAuthenticationToken smpa = new SMPAuthenticationToken("smp_admin", "test123", Collections.singletonList(SMPAuthority.S_AUTHORITY_SMP_ADMIN), user);
+            SMPAuthenticationToken smpa = new SMPAuthenticationToken("smp_admin", "test123", smpUserDetails);
 
             @Override
             public Authentication getAuthentication() {
@@ -62,7 +80,7 @@ public class SMPAuthorizationServiceTest {
             }
         };
         mockSecurityContextSGAdmin = new SecurityContext() {
-            SMPAuthenticationToken smpa = new SMPAuthenticationToken("sg_admin", "test123", Collections.singletonList(SMPAuthority.S_AUTHORITY_SERVICE_GROUP), user);
+            SMPAuthenticationToken smpa = new SMPAuthenticationToken("sg_admin", "test123", sgUserDetails);
 
             @Override
             public Authentication getAuthentication() {
@@ -128,4 +146,60 @@ public class SMPAuthorizationServiceTest {
         assertFalse(bVal);
     }
 
+    @Test
+    public void testGetUpdatedUserData() {
+        UserRO user = new UserRO();
+        user.setPasswordExpireOn(OffsetDateTime.now().minusDays(1));
+        Mockito.doReturn(10).when(configurationService).getPasswordPolicyUIWarningDaysBeforeExpire();
+        Mockito.doReturn(false).when(configurationService).getPasswordPolicyForceChangeIfExpired();
+
+        user = testInstance.getUpdatedUserData(user);
+
+        Assert.assertTrue(user.isShowPasswordExpirationWarning());
+        Assert.assertFalse(user.isForceChangeExpiredPassword());
+        Assert.assertFalse(user.isPasswordExpired());
+    }
+
+    @Test
+    public void testGetUpdatedUserDataDoNotShowWarning() {
+        UserRO user = new UserRO();
+        user.setPasswordExpireOn(OffsetDateTime.now().minusDays(11));
+        Mockito.doReturn(10).when(configurationService).getPasswordPolicyUIWarningDaysBeforeExpire();
+        Mockito.doReturn(false).when(configurationService).getPasswordPolicyForceChangeIfExpired();
+
+        user = testInstance.getUpdatedUserData(user);
+
+        Assert.assertFalse(user.isShowPasswordExpirationWarning());
+        Assert.assertFalse(user.isForceChangeExpiredPassword());
+        Assert.assertFalse(user.isPasswordExpired());
+    }
+
+    @Test
+    public void testGetUpdatedUserDataForceChange() {
+        UserRO user = new UserRO();
+        user.setPasswordExpireOn(OffsetDateTime.now().plusDays(1));
+        user.setPasswordExpired(true);
+        Mockito.doReturn(10).when(configurationService).getPasswordPolicyUIWarningDaysBeforeExpire();
+        Mockito.doReturn(true).when(configurationService).getPasswordPolicyForceChangeIfExpired();
+
+        user = testInstance.getUpdatedUserData(user);
+
+        Assert.assertTrue(user.isForceChangeExpiredPassword());
+        Assert.assertTrue(user.isPasswordExpired());
+    }
+
+    @Test
+    public void testGetUpdatedUserDataForceChangeFalse() {
+        UserRO user = new UserRO();
+        user.setPasswordExpireOn(OffsetDateTime.now().plusDays(1));
+        user.setPasswordExpired(true);
+        Mockito.doReturn(10).when(configurationService).getPasswordPolicyUIWarningDaysBeforeExpire();
+        Mockito.doReturn(false).when(configurationService).getPasswordPolicyForceChangeIfExpired();
+
+        user = testInstance.getUpdatedUserData(user);
+
+        Assert.assertFalse(user.isForceChangeExpiredPassword());
+        Assert.assertTrue(user.isPasswordExpired());
+    }
+
 }
\ No newline at end of file
diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResourceTest.java
index 122f1cd94..25a298825 100644
--- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResourceTest.java
+++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResourceTest.java
@@ -1,7 +1,9 @@
 package eu.europa.ec.edelivery.smp.ui;
 
 import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationService;
+import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationToken;
 import eu.europa.ec.edelivery.smp.auth.SMPAuthorizationService;
+import eu.europa.ec.edelivery.smp.auth.SMPUserDetails;
 import eu.europa.ec.edelivery.smp.data.ui.UserRO;
 import eu.europa.ec.edelivery.smp.services.ConfigurationService;
 import eu.europa.ec.edelivery.smp.services.ui.UIUserService;
@@ -9,85 +11,84 @@ import eu.europa.ec.edelivery.smp.utils.SMPCookieWriter;
 import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
-import org.springframework.core.convert.ConversionService;
+import org.springframework.security.web.csrf.CsrfToken;
 import org.springframework.security.web.csrf.CsrfTokenRepository;
+import org.springframework.web.servlet.view.RedirectView;
 
-import java.time.OffsetDateTime;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import static eu.europa.ec.edelivery.smp.utils.SMPCookieWriter.SESSION_COOKIE_NAME;
 
 public class AuthenticationResourceTest {
 
     SMPAuthenticationService authenticationService = Mockito.mock(SMPAuthenticationService.class);
     SMPAuthorizationService authorizationService = Mockito.mock(SMPAuthorizationService.class);
-    ConversionService conversionService = Mockito.mock(ConversionService.class);
     ConfigurationService configurationService = Mockito.mock(ConfigurationService.class);
     SMPCookieWriter smpCookieWriter = Mockito.mock(SMPCookieWriter.class);
     CsrfTokenRepository csrfTokenRepository = Mockito.mock(CsrfTokenRepository.class);
     UIUserService uiUserService = Mockito.mock(UIUserService.class);
 
-    AuthenticationResource testInstance= new AuthenticationResource(authenticationService,
+    AuthenticationResource testInstance = new AuthenticationResource(authenticationService,
             authorizationService,
-            conversionService,
             configurationService,
             smpCookieWriter,
             csrfTokenRepository,
             uiUserService);
+
     @Test
-    public void testGetUpdatedUserData() {
-        UserRO user  = new UserRO();
-        user.setPasswordExpireOn(OffsetDateTime.now().minusDays(1));
-        Mockito.doReturn(10).when(configurationService).getPasswordPolicyUIWarningDaysBeforeExpire();
-        Mockito.doReturn(false).when(configurationService).getPasswordPolicyForceChangeIfExpired();
-        Mockito.doReturn(user).when(authorizationService).sanitize(Mockito.any());
-
-        user = testInstance.getUpdatedUserData(user);
-
-        Assert.assertTrue(user.isShowPasswordExpirationWarning());
-        Assert.assertFalse(user.isForceChangeExpiredPassword());
-        Assert.assertFalse(user.isPasswordExpired());
+    public void logout() {
+        HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+        HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+        Mockito.doNothing().when(authenticationService).logout(Mockito.any(), Mockito.any());
+        testInstance.logout(request, response);
+
+        Mockito.verify(authenticationService, Mockito.times(1)).logout(request, response);
     }
 
     @Test
-    public void testGetUpdatedUserDataDoNotShowWarning() {
-        UserRO user  = new UserRO();
-        user.setPasswordExpireOn(OffsetDateTime.now().minusDays(11));
-        Mockito.doReturn(10).when(configurationService).getPasswordPolicyUIWarningDaysBeforeExpire();
-        Mockito.doReturn(false).when(configurationService).getPasswordPolicyForceChangeIfExpired();
-        Mockito.doReturn(user).when(authorizationService).sanitize(Mockito.any());
-
-        user = testInstance.getUpdatedUserData(user);
-
-        Assert.assertFalse(user.isShowPasswordExpirationWarning());
-        Assert.assertFalse(user.isForceChangeExpiredPassword());
-        Assert.assertFalse(user.isPasswordExpired());
+    public void authenticateCAS() {
+
+        RedirectView result = testInstance.authenticateCAS();
+        Assert.assertNotNull(result);
+        Assert.assertEquals("../../../#/", result.getUrl());
     }
 
     @Test
-    public void testGetUpdatedUserDataForceChange() {
-        UserRO user  = new UserRO();
-        user.setPasswordExpireOn(OffsetDateTime.now().plusDays(1));
-        user.setPasswordExpired(true);
-        Mockito.doReturn(10).when(configurationService).getPasswordPolicyUIWarningDaysBeforeExpire();
-        Mockito.doReturn(true).when(configurationService).getPasswordPolicyForceChangeIfExpired();
-        Mockito.doReturn(user).when(authorizationService).sanitize(Mockito.any());
-
-        user = testInstance.getUpdatedUserData(user);
-
-        Assert.assertTrue(user.isForceChangeExpiredPassword());
-        Assert.assertTrue(user.isPasswordExpired());
+    public void getUser() {
+        UserRO user = new UserRO();
+        Mockito.doReturn(user).when(authorizationService).getLoggedUserData();
+        UserRO result = testInstance.getUser();
+        Assert.assertEquals(user, result);
     }
 
     @Test
-    public void testGetUpdatedUserDataForceChangeFalse() {
-        UserRO user  = new UserRO();
-        user.setPasswordExpireOn(OffsetDateTime.now().plusDays(1));
-        user.setPasswordExpired(true);
-        Mockito.doReturn(10).when(configurationService).getPasswordPolicyUIWarningDaysBeforeExpire();
-        Mockito.doReturn(false).when(configurationService).getPasswordPolicyForceChangeIfExpired();
-        Mockito.doReturn(user).when(authorizationService).sanitize(Mockito.any());
-
-        user = testInstance.getUpdatedUserData(user);
-
-        Assert.assertFalse(user.isForceChangeExpiredPassword());
-        Assert.assertTrue(user.isPasswordExpired());
+    public void recreatedSessionCookie() {
+        String cookieName = SESSION_COOKIE_NAME;
+        String cookieValue = "CookieValue";
+        boolean sessionCookieSecure = true;
+        String sessionCookiePath = "getSessionCookiePath";
+        String sessionCookieSameSite = "getSessionCookieSameSite";
+        Integer sessionCookieMaxAge = 12;
+
+        HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+        HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+        HttpSession session = Mockito.mock(HttpSession.class);
+        Mockito.doReturn(session).when(request).getSession(Mockito.anyBoolean());
+        Mockito.doReturn(cookieValue).when(session).getId();
+        Mockito.doReturn(sessionCookieSecure).when(configurationService).getSessionCookieSecure();
+        Mockito.doReturn(sessionCookieMaxAge).when(configurationService).getSessionCookieMaxAge();
+        Mockito.doReturn(sessionCookiePath).when(configurationService).getSessionCookiePath();
+        Mockito.doReturn(sessionCookieSameSite).when(configurationService).getSessionCookieSameSite();
+
+
+        Mockito.doNothing().when(smpCookieWriter).writeCookieToResponse(cookieName,
+                cookieValue, sessionCookieSecure, sessionCookieMaxAge, sessionCookiePath, sessionCookieSameSite, request, response);
+
+        testInstance.recreatedSessionCookie(request, response);
+
+        Mockito.verify(smpCookieWriter, Mockito.times(1)).writeCookieToResponse(cookieName,
+                cookieValue, sessionCookieSecure, sessionCookieMaxAge, sessionCookiePath, sessionCookieSameSite, request, response);
     }
 }
diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/UserResourceIntegrationTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/UserResourceIntegrationTest.java
index ea4bfc715..e12901913 100644
--- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/UserResourceIntegrationTest.java
+++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/UserResourceIntegrationTest.java
@@ -62,7 +62,6 @@ public class UserResourceIntegrationTest {
 
     @Test
     public void getUserList() throws Exception {
-
         MockHttpSession session = loginWithSystemAdmin(mvc);
         MvcResult result = mvc.perform(get(CONTEXT_PATH_INTERNAL_USER)
                 .session(session)
diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/TruststoreAdminResourceIntegrationTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/TruststoreAdminResourceIntegrationTest.java
index fb62cc4be..f6041f33e 100644
--- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/TruststoreAdminResourceIntegrationTest.java
+++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/TruststoreAdminResourceIntegrationTest.java
@@ -58,9 +58,9 @@ public class TruststoreAdminResourceIntegrationTest {
 
     @Before
     public void setup() throws IOException {
-        X509CertificateTestUtils.reloadKeystores();
         mvc = initializeMockMvc(webAppContext);
         uiTruststoreService.refreshData();
+        X509CertificateTestUtils.reloadKeystores();
     }
 
 
@@ -78,8 +78,8 @@ public class TruststoreAdminResourceIntegrationTest {
                 .session(session)
                 .with(csrf())
                 .content(buff))
-                .andExpect(status().is5xxServerError())
-                .andExpect(content().string(CoreMatchers.containsString(" The certificate is not valid")));
+                .andExpect(status().isOk())
+                .andExpect(content().string(CoreMatchers.containsString("Can not read the certificate!")));
     }
 
     @Test
-- 
GitLab