diff --git a/pom.xml b/pom.xml
index eb30f3bb526b417010a740a41a2eace5d323e532..de06f3cc2fba4eba68cd3c248c021c86bb96982a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -84,7 +84,7 @@
         <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
         <sonar.jacoco.codeCoveragePath>${basedir}/target/code-coverage</sonar.jacoco.codeCoveragePath>
         <sonar.jacoco.reportPath>${sonar.jacoco.codeCoveragePath}/jacoco-ut.exec</sonar.jacoco.reportPath>
-        <sonar.jacoco.itReportPath>{sonar.jacoco.codeCoveragePath}/jacoco-it.exec</sonar.jacoco.itReportPath>
+        <sonar.jacoco.itReportPath>${sonar.jacoco.codeCoveragePath}/jacoco-it.exec</sonar.jacoco.itReportPath>
         <sonar.language>java</sonar.language>
 
         <sonar.host.url>http://localhost:9000/sonar/</sonar.host.url>
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 91e38f941636d4b35b1423326830edd1aa555462..ce93e47bcdd44f4dbe794610bf47526698176460 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
@@ -43,6 +43,8 @@ public enum SMPPropertyEnum {
     ENCRYPTION_FILENAME("encryption.key.filename", "encryptionPrivateKey.private", "Key filename to encrypt passwords", false, false, true, SMPPropertyTypeEnum.FILENAME),
     KEYSTORE_PASSWORD_DECRYPTED("smp.keystore.password.decrypted", "", "Only for backup purposes when  password is automatically created. Store password somewhere save and delete this entry!", false, false, false, SMPPropertyTypeEnum.STRING),
     TRUSTSTORE_PASSWORD_DECRYPTED("smp.truststore.password.decrypted", "", "Only for backup purposes when  password is automatically created. Store password somewhere save and delete this entry!", false, false, false, SMPPropertyTypeEnum.STRING),
+    CERTIFICATE_ALLOWED_CERTIFICATEPOLICY_OIDS("smp.certificate.validation.allowedCertificatePolicyOIDs","","List of certificate policy OIDs separated by comma where at least one must be in the CertifictePolicy extension", false, false,false, SMPPropertyTypeEnum.STRING),
+    CERTIFICATE_SUBJECT_REGULAR_EXPRESSION("smp.certificate.validation.subjectRegex",".*","Regular expression to validate subject of the certificate", false, false,false, SMPPropertyTypeEnum.REGEXP),
 
     SMP_PROPERTY_REFRESH_CRON("smp.property.refresh.cronJobExpression", "0 48 */1 * * *", "Property refresh cron expression (def 12 minutes to each hour). Property change is refreshed at restart!", false, false, true, SMPPropertyTypeEnum.STRING),
     // UI COOKIE configuration
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 271d41fc09c5afd019cc097841349ea57383adb3..65d8997e7d755bde0aa333f6d74d0860a76e3674 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
@@ -56,7 +56,7 @@ public class CRLVerifierService {
 
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(CRLVerifierService.class);
 
-    public static final int DEF_PROXY_PORT=80;
+    public static final int DEF_PROXY_PORT = 80;
 
     Map<String, X509CRL> crlCacheMap = new HashMap<>();
     Map<String, Long> crlCacheNextRefreshMap = new HashMap<>();
@@ -74,7 +74,7 @@ public class CRLVerifierService {
 
         List<String> crlDistPoints = X509CertificateUtils.getCrlDistributionPoints(cert);
         if (crlDistPoints.isEmpty()) {
-            LOG.warn("The certificate: '{}' has no CRL Lists.", cert.getSubjectX500Principal() );
+            LOG.warn("The certificate: '{}' has no CRL Lists.", cert.getSubjectX500Principal());
             return;
         }
         String crlUrl = X509CertificateUtils.extractHttpCrlDistributionPoint(crlDistPoints);
@@ -91,7 +91,7 @@ public class CRLVerifierService {
 
 
     public void verifyCertificateCRLs(BigInteger serial, String crlDistributionPointURL) throws CertificateRevokedException {
-        LOG.info("Download CRL {}." ,crlDistributionPointURL);
+        LOG.info("Download CRL {}.", crlDistributionPointURL);
         X509CRL crl = getCRLByURL(crlDistributionPointURL);
         if (crl != null && crl.getRevokedCertificates() != null) {
             validateCertificateCRL(crl, serial);
@@ -110,7 +110,7 @@ public class CRLVerifierService {
         if (x509CRL == null) {
             // if CRL is null try to get one
             boolean mandatoryCrlValidation = configurationService.forceCRLValidation();
-            x509CRL = downloadCRL(crlURL,mandatoryCrlValidation);
+            x509CRL = downloadCRL(crlURL, mandatoryCrlValidation);
             // calculate next update in milliseconds...
             Long nextRefresh = x509CRL != null && x509CRL.getNextUpdate() != null ? x509CRL.getNextUpdate().getTime()
                     : currentDate.getTime() + REFRESH_CRL_INTERVAL;
@@ -147,7 +147,7 @@ public class CRLVerifierService {
 
         X509CRL crl = null;
         SMPRuntimeException exception = null;
-        try ( InputStream crlStream = downloadURL(crlURL)){
+        try (InputStream crlStream = downloadURL(crlURL)) {
             if (crlStream != null) {
                 CertificateFactory cf = CertificateFactory.getInstance("X.509");
                 crl = (X509CRL) cf.generateCRL(crlStream);
@@ -161,11 +161,11 @@ public class CRLVerifierService {
         } catch (CRLException e) {
             exception = new SMPRuntimeException(ErrorCode.CERTIFICATE_ERROR, "CRL can not be read: '" + crlURL
                     , ExceptionUtils.getRootCauseMessage(e), e);
-        } catch(SMPRuntimeException exc) {
+        } catch (SMPRuntimeException exc) {
             exception = exc;
         }
         // if exception occurred
-        if (exception != null ) {
+        if (exception != null) {
             if (mandatoryCRLValidation) {
                 throw exception;
             } else {
@@ -190,7 +190,7 @@ public class CRLVerifierService {
                     String decryptedPassword = configurationService.getProxyCredentialToken();
                     Optional<Integer> proxyPort = configurationService.getHttpProxyPort();
                     inputStream = downloadURLViaProxy(crlURL, configurationService.getHttpProxyHost(),
-                            proxyPort.isPresent()?proxyPort.get():DEF_PROXY_PORT,
+                            proxyPort.isPresent() ? proxyPort.get() : DEF_PROXY_PORT,
                             configurationService.getProxyUsername(), decryptedPassword);
                 } else {
                     inputStream = downloadURLDirect(crlURL);
@@ -220,8 +220,8 @@ public class CRLVerifierService {
             HttpGet httpget = new HttpGet(url);
             httpget.setConfig(config);
             // log username
-            String logUserName = credentialsProvider == null ? "None" :  proxyUser;
-            LOG.debug("Executing request '{}' via proxy '{}' with user: '{}'.",url, proxyHost,
+            String logUserName = credentialsProvider == null ? "None" : proxyUser;
+            LOG.debug("Executing request '{}' via proxy '{}' with user: '{}'.", url, proxyHost,
                     logUserName);
 
             return execute(httpclient, httpget);
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 646b3c4be78b155144864d15b6222b07e2ad2eaa..be234e8088e12dc29690dfc624eafffbf401cee2 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
@@ -148,6 +148,15 @@ public class ConfigurationService {
         return value != null && value;
     }
 
+
+    public Pattern getCertificateSubjectRegularExpression() {
+        return (Pattern) configurationDAO.getCachedPropertyValue(CERTIFICATE_SUBJECT_REGULAR_EXPRESSION);
+    }
+
+    public List<String> getAllowedCertificatePolicies() {
+        return (List<String>) configurationDAO.getCachedPropertyValue(CERTIFICATE_ALLOWED_CERTIFICATEPOLICY_OIDS);
+    }
+
     public String getSMLIntegrationServerCertSubjectRegExp() {
         return configurationDAO.getCachedProperty(SML_TLS_SERVER_CERT_SUBJECT_REGEXP);
     }
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 a5c5e138e0a7f906d13248b25cfaeb1d7b52264c..16d10272a5b925e46bcb396e61ccbb49b50e3241 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
@@ -11,6 +11,10 @@ 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;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.x509.CertificatePolicies;
+import org.bouncycastle.asn1.x509.PolicyInformation;
+import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.convert.ConversionService;
@@ -31,6 +35,8 @@ import java.security.cert.*;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.*;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 import static java.util.Collections.list;
 import static java.util.Locale.US;
@@ -51,18 +57,16 @@ public class UITruststoreService {
     CRLVerifierService crlVerifierService;
 
     @Autowired
-    private ConversionService conversionService;
+    ConversionService conversionService;
 
-    private List<String> normalizedTrustedList = new ArrayList<>();
-    private Map<String, X509Certificate> truststoreCertificates = new HashMap();
-    private List<CertificateRO> certificateROList = new ArrayList<>();
-    KeyStore trustStore = null;
-
-
-    private long lastUpdateTrustoreFileTime = 0;
-    private File lastUpdateTrustStoreFile = null;
+    List<String> normalizedTrustedList = new ArrayList<>();
 
+    Map<String, X509Certificate> truststoreCertificates = new HashMap();
+    List<CertificateRO> certificateROList = new ArrayList<>();
+    long lastUpdateTrustoreFileTime = 0;
+    File lastUpdateTrustStoreFile = null;
     TrustManager[] trustManagers;
+    KeyStore trustStore = null;
 
 
     @PostConstruct
@@ -102,7 +106,6 @@ public class UITruststoreService {
                     " and the configuration!");
             return;
         }
-
         // init key managers for TLS
         TrustManager[] trustManagersTemp;
         try {
@@ -198,6 +201,8 @@ public class UITruststoreService {
 
             throw new CertificateNotTrustedException("Certificate is not trusted!");
         }
+        validateCertificatePolicyMatch(cert);
+        validateCertificateSubjectExpression(cert);
         // check CRL - it is using only HTTP or https
         crlVerifierService.verifyCertificateCRLs(cert);
     }
@@ -408,9 +413,7 @@ public class UITruststoreService {
         } catch (KeyStoreException e) {
             LOG.error("Error occured while reading truststore for validating alias: " + alias, e);
         }
-
         return alias;
-
     }
 
 
@@ -453,4 +456,74 @@ public class UITruststoreService {
         return conversionService.convert(d, CertificateRO.class);
     }
 
+    /**
+     * Extracts all Certificate Policy identifiers the "Certificate policy" extension of X.509.
+     * If the certificate policy extension is unavailable, returns an empty list.
+     *
+     * @param cert a X509 certificate
+     * @return the list of CRL urls of certificate policy identifiers
+     */
+    public List<String> getCertificatePolicyIdentifiers(X509Certificate cert) throws CertificateException {
+
+        byte[] certPolicyExt = cert.getExtensionValue(org.bouncycastle.asn1.x509.Extension.certificatePolicies.getId());
+        if (certPolicyExt == null) {
+            return new ArrayList<>();
+        }
+
+        CertificatePolicies policies;
+        try {
+            policies = CertificatePolicies.getInstance(JcaX509ExtensionUtils.parseExtensionValue(certPolicyExt));
+        } catch (IOException e) {
+            throw new CertificateException("Error occurred while reading certificate policy object!", e);
+        }
+
+        return Arrays.stream(policies.getPolicyInformation())
+                .map(PolicyInformation::getPolicyIdentifier)
+                .map(ASN1ObjectIdentifier::getId)
+                .map(StringUtils::trim)
+                .collect(Collectors.toList());
+    }
+
+    protected void validateCertificatePolicyMatch(X509Certificate certificate) throws CertificateException {
+
+        // allowed list
+        List<String> allowedCertificatePolicyOIDList = configurationService.getAllowedCertificatePolicies();
+        if (allowedCertificatePolicyOIDList == null || allowedCertificatePolicyOIDList.isEmpty()) {
+            LOG.debug("Certificate policy is not configured. Skip Certificate policy validation!");
+            return;
+        }
+        // certificate list
+        List<String> certPolicyList = getCertificatePolicyIdentifiers(certificate);
+        if (certPolicyList.isEmpty()) {
+            String excMessage = String.format("Certificate has empty CertificatePolicy extension. Certificate: %s ", certificate);
+            throw new CertificateException(excMessage);
+        }
+
+        Optional<String> result = certPolicyList.stream().filter(certPolicyOID -> allowedCertificatePolicyOIDList.contains(certPolicyOID)).findFirst();
+        if (result.isPresent()) {
+            LOG.info("Certificate [{}] is trusted with certificate policy [{}]", certificate, result.get());
+            return;
+        }
+        String excMessage = String.format("Certificate policy verification failed. Certificate [%s] does not contain any of the policy: [%s]", certificate, allowedCertificatePolicyOIDList);
+        throw new CertificateException(excMessage);
+    }
+
+    protected void validateCertificateSubjectExpression(X509Certificate signingCertificate) throws CertificateException {
+        LOG.debug("Validate certificate subject");
+
+
+        String subject = signingCertificate.getSubjectDN().getName();
+        Pattern certSubjectExpression = configurationService.getCertificateSubjectRegularExpression();
+        if (certSubjectExpression == null) {
+            LOG.debug("Certificate subject regular expression is empty, verification is disabled.");
+            return;
+        }
+
+        if (!certSubjectExpression.matcher(subject).matches()) {
+            String excMessage = String.format("Certificate subject [%s] does not match the regular expression configured [%s]", subject, certSubjectExpression);
+            LOG.error(excMessage);
+            throw new CertificateException(excMessage);
+        }
+    }
+
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/sml/SmlConnector.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/sml/SmlConnector.java
index a3c241be5fe57895e2ed85e7cc4cae1076854431..c7c2b4f9ab41c2ba36fb4385f4b407a91900b8b1 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/sml/SmlConnector.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/sml/SmlConnector.java
@@ -99,16 +99,16 @@ public class SmlConnector implements ApplicationContextAware {
         }
         String normalizedParticipantString = asString(normalizedParticipantId);
         if (!domain.isSmlRegistered()) {
-            LOG.info("Participant {} is not registered to SML because domain {} is not registered!" ,
+            LOG.info("Participant {} is not registered to SML because domain {} is not registered!",
                     normalizedParticipantString, domain.getDomainCode());
             return false;
         }
 
-        LOG.debug("Registering new Participant: {} to domain: {}." , normalizedParticipantString, domain.getDomainCode());
+        LOG.debug("Registering new Participant: {} to domain: {}.", normalizedParticipantString, domain.getDomainCode());
         try {
             ServiceMetadataPublisherServiceForParticipantType smlRequest = toBusdoxParticipantId(normalizedParticipantId, domain.getSmlSmpId());
             getParticipantWSClient(domain).create(smlRequest);
-            LOG.info("Participant: {} registered to domain: {}." , normalizedParticipantString, domain.getDomainCode());
+            LOG.info("Participant: {} registered to domain: {}.", normalizedParticipantString, domain.getDomainCode());
             return true;
         } catch (BadRequestFault e) {
             return processSMLErrorMessage(e, normalizedParticipantId);
@@ -225,7 +225,7 @@ public class SmlConnector implements ApplicationContextAware {
         }
         String normalizedParticipantString = asString(normalizedParticipantId);
         if (!domain.isSmlRegistered()) {
-            LOG.info("Participant {} is not unregistered from SML because domain {} is not registered!" ,
+            LOG.info("Participant {} is not unregistered from SML because domain {} is not registered!",
                     normalizedParticipantString, domain.getDomainCode());
             return false;
         }
@@ -329,7 +329,7 @@ public class SmlConnector implements ApplicationContextAware {
         // check if there is only one cert in  keystore
         if (!blueCoatAuthentication && StringUtils.isBlank(clientKeyAlias)) {
             List<CertificateRO> list = keystoreService.getKeystoreEntriesList();
-            if (list.size()==1) {
+            if (list.size() == 1) {
                 // set the default alias
                 clientKeyAlias = list.get(0).getAlias();
             } else if (list.isEmpty()) {
@@ -340,7 +340,7 @@ public class SmlConnector implements ApplicationContextAware {
         }
 
         if (!blueCoatAuthentication && !useTLS) {
-           LOG.warn("SML integration is wrongly configured. Uses 2-way-SSL HTTPS but URL is not HTTPS! Url: {}." ,urlSMPManagment.toString());
+            LOG.warn("SML integration is wrongly configured. Uses 2-way-SSL HTTPS but URL is not HTTPS! Url: {}.", urlSMPManagment.toString());
         }
 
         HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
@@ -378,14 +378,13 @@ public class SmlConnector implements ApplicationContextAware {
             requestContext.put(MessageContext.HTTP_REQUEST_HEADERS, customHeaders);
         }
         if (useTLS) {
-
             httpConduit.setTlsClientParameters(tlsParams);
         }
     }
 
 
-    public CertificateConstraintsType createCertConstraint(String regExp){
-        if (StringUtils.isBlank(regExp)){
+    public CertificateConstraintsType createCertConstraint(String regExp) {
+        if (StringUtils.isBlank(regExp)) {
             return null;
         }
 
@@ -433,7 +432,7 @@ public class SmlConnector implements ApplicationContextAware {
             httpConduit.getClient().setProxyServerPort(proxyPort.get());
         }
 
-        if (!StringUtils.isBlank(proxyUser)){
+        if (!StringUtils.isBlank(proxyUser)) {
             ProxyAuthorizationPolicy proxyAuth = new ProxyAuthorizationPolicy();
             proxyAuth.setAuthorizationType("Basic");
             LOG.debug("Set proxy authentication {}", proxyUser);
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/X509CertificateTestUtils.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/X509CertificateTestUtils.java
index 4f03366dff8c26b868a64f88c825d663032b8c07..570354e4e8e17e74b447a22d7c9205ffc57d25bc 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/X509CertificateTestUtils.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/X509CertificateTestUtils.java
@@ -66,7 +66,44 @@ public class X509CertificateTestUtils {
                     BigInteger.valueOf(iSerial++), startDate, expiryDate, new X500Name(sbj),
                     SubjectPublicKeyInfo.getInstance(key.getPublic().getEncoded()));
 
-            ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption")
+            ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WITHRSA")
+                    .setProvider("BC").build(issuerKey ==null?key.getPrivate():issuerKey);
+
+            certs[--index] = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certBuilder.build(sigGen));
+            issuer= sbj;
+            issuerKey = key.getPrivate();
+
+        }
+        return certs;
+    }
+
+    /**
+     *  Method generates certificate chain
+     * @param subjects
+     * @param certificatePoliciesOids
+     * @param startDate
+     * @param expiryDate
+     * @return
+     * @throws Exception
+     */
+    public static X509Certificate[] createCertificateChain(String[] subjects,  List<List<String>> certificatePoliciesOids,  Date startDate, Date expiryDate) throws Exception {
+
+        String issuer = null;
+        PrivateKey issuerKey = null;
+        long iSerial = 10000;
+        X509Certificate[] certs = new X509Certificate[subjects.length];
+
+        int index = subjects.length;
+        for (String sbj: subjects){
+            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
+            keyGen.initialize(1024);
+            KeyPair key = keyGen.generateKeyPair();
+
+            X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(new X500Name(issuer ==null? sbj:issuer),
+                    BigInteger.valueOf(iSerial++), startDate, expiryDate, new X500Name(sbj),
+                    SubjectPublicKeyInfo.getInstance(key.getPublic().getEncoded()));
+
+            ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WITHRSA")
                     .setProvider("BC").build(issuerKey ==null?key.getPrivate():issuerKey);
 
             certs[--index] = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certBuilder.build(sigGen));
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListener.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListener.java
index c41c02ed9326ca107edf908bb102a9b1fce18400..51247078381a3b5701b48454dd011776c9b8ca15 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListener.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListener.java
@@ -39,20 +39,29 @@ public class SMPAuthenticationEventListener implements ApplicationListener<Authe
 
     /**
      * On successful authentication method validates the roles and set max session idle time before it invalidates the session.
+     *
      * @param event
      */
     @Override
-    public void onApplicationEvent (AuthenticationSuccessEvent event) {
-        Collection<? extends GrantedAuthority> authorities = event.getAuthentication().getAuthorities();
-        boolean hasAdminRole = authorities.stream().anyMatch(grantedAuthority -> StringUtils.equalsIgnoreCase(grantedAuthority.getAuthority(), SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN.getAuthority()));
+    public void onApplicationEvent(AuthenticationSuccessEvent event) {
+
         ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
-        if (attr!= null) {
+        if (attr != null) {
+            Collection<? extends GrantedAuthority> authorities = event.getAuthentication().getAuthorities();
             HttpSession session = attr.getRequest().getSession();
-            int idleTimeout = (hasAdminRole ? configurationService.getSessionIdleTimeoutForAdmin() : configurationService.getSessionIdleTimeoutForUser());
-            LOG.debug("Set session idle timeout [{}] for user [{}]", idleTimeout, event.getAuthentication().getName());
+            int idleTimeout = getSessionTimeoutForRoles(authorities);
+            LOG.debug("Set session idle timeout [{}] for user [{}] with roles [{}]", idleTimeout, event.getAuthentication().getName(), authorities);
             session.setMaxInactiveInterval(idleTimeout);
         } else {
-            LOG.warn("Could not get ServletRequestAttributes attributes for authentication [{}]", event.getAuthentication() );
+            LOG.warn("Could not get ServletRequestAttributes attributes for authentication [{}]", event.getAuthentication());
         }
     }
+
+    public int getSessionTimeoutForRoles(Collection<? extends GrantedAuthority> authorities) {
+        boolean hasAdminRole = authorities.stream().anyMatch(grantedAuthority ->
+                StringUtils.equalsIgnoreCase(grantedAuthority.getAuthority(), SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN.getAuthority())
+                        || StringUtils.equalsIgnoreCase(grantedAuthority.getAuthority(), SMPAuthority.S_AUTHORITY_SMP_ADMIN.getAuthority()));
+        LOG.debug("has admin role [{}]", hasAdminRole);
+        return hasAdminRole ? configurationService.getSessionIdleTimeoutForAdmin() : configurationService.getSessionIdleTimeoutForUser();
+    }
 }
\ No newline at end of file
diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListenerTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListenerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..aff3bd013ee9531d7040a22231fecf8a15fee908
--- /dev/null
+++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListenerTest.java
@@ -0,0 +1,79 @@
+package eu.europa.ec.edelivery.smp.auth;
+
+import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority;
+import eu.europa.ec.edelivery.smp.services.ConfigurationService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.springframework.core.convert.ConversionService;
+import org.springframework.security.core.GrantedAuthority;
+
+import javax.persistence.EntityManager;
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.junit.Assert.*;
+
+public class SMPAuthenticationEventListenerTest {
+
+    ConfigurationService configurationService = Mockito.mock(ConfigurationService .class);;
+    // test instance
+    SMPAuthenticationEventListener testInstance = new SMPAuthenticationEventListener(configurationService);
+
+
+    @Test
+    public void getSessionTimeoutForRolesSMPAdmin() {
+        // Given
+        Collection<? extends GrantedAuthority> authorities = Arrays.asList(SMPAuthority.S_AUTHORITY_SMP_ADMIN);
+        // when then
+        assertTimeoutForAuthorities(authorities, true);
+    }
+
+    @Test
+    public void getSessionTimeoutForRolesSystemAdmin() {
+        // Given
+        Collection<? extends GrantedAuthority> authorities = Arrays.asList(SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN);
+        // when then
+        assertTimeoutForAuthorities(authorities, true);
+    }
+
+    @Test
+    public void getSessionTimeoutForRolesUser() {
+        // Given
+        Collection<? extends GrantedAuthority> authorities = Arrays.asList(SMPAuthority.S_AUTHORITY_SERVICE_GROUP);
+        // when then
+        assertTimeoutForAuthorities(authorities, false);
+    }
+
+    @Test
+    public void getSessionTimeoutForRolesUserAndSystem() {
+        // Given
+        Collection<? extends GrantedAuthority> authorities = Arrays.asList(SMPAuthority.S_AUTHORITY_SERVICE_GROUP,SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN);
+        // when then
+        assertTimeoutForAuthorities(authorities, true);
+    }
+
+    @Test
+    public void getSessionTimeoutForRolesUserAndSMP() {
+        // Given
+        Collection<? extends GrantedAuthority> authorities = Arrays.asList(SMPAuthority.S_AUTHORITY_SERVICE_GROUP,SMPAuthority.S_AUTHORITY_SMP_ADMIN);
+        // when then
+        assertTimeoutForAuthorities(authorities, true);
+    }
+
+    public void assertTimeoutForAuthorities(Collection<? extends GrantedAuthority> authorities, boolean isAdmin){
+        // Given
+        int secondsToTimeoutAdmin = 111;
+        int secondsToTimeoutUser = 555;
+        int expected = isAdmin ? secondsToTimeoutAdmin : secondsToTimeoutUser;
+        // idle for admin
+        Mockito.doReturn(secondsToTimeoutAdmin).when(configurationService).getSessionIdleTimeoutForAdmin();
+        Mockito.doReturn(secondsToTimeoutUser).when(configurationService).getSessionIdleTimeoutForUser();
+        // when
+        int result = testInstance.getSessionTimeoutForRoles(authorities);
+        //then
+        assertEquals(expected, result);
+    }
+}
\ No newline at end of file
diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/UserResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/UserResourceTest.java
index c032b7b1812d9e1fd65bb51c5a6baabd4503e004..0b2161a44e7506af30763f54295a9b25455532e2 100644
--- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/UserResourceTest.java
+++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/UserResourceTest.java
@@ -292,7 +292,6 @@ public class UserResourceTest {
         ObjectMapper mapper = new ObjectMapper();
         CertificateRO res = mapper.readValue(result.getResponse().getContentAsString(), CertificateRO.class);
 
-
         assertEquals("CN=common name,O=org,C=BE:0000000001234321", res.getCertificateId());
     }