diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBCertificate.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBCertificate.java
index e552eb609411eb9e3fdcd190641829bb4b9ca373..541553a963d81a1a36ec0ededeb57e5668e71f2b 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBCertificate.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBCertificate.java
@@ -45,29 +45,26 @@ public class DBCertificate extends BaseEntity {
     @Column(name = "VALID_TO")
     @ColumnDescription(comment = "Certificate valid to date.")
     private LocalDateTime validTo;
-
     @Column(name = "SUBJECT", length = CommonColumnsLengths.MAX_MEDIUM_TEXT_LENGTH)
-    @ColumnDescription(comment = "Certificate subject (canonical form)" )
-    private String  subject;
+    @ColumnDescription(comment = "Certificate subject (canonical form)")
+    private String subject;
     @Column(name = "ISSUER", length = CommonColumnsLengths.MAX_MEDIUM_TEXT_LENGTH)
-    @ColumnDescription(comment = "Certificate issuer (canonical form)" )
-    private String  issuer;
+    @ColumnDescription(comment = "Certificate issuer (canonical form)")
+    private String issuer;
     @Column(name = "SERIALNUMBER", length = CommonColumnsLengths.MAX_TEXT_LENGTH_128)
-    @ColumnDescription(comment = "Certificate serial number" )
-    private String  serialNumber;
+    @ColumnDescription(comment = "Certificate serial number")
+    private String serialNumber;
 
-    @Column(name = "pem_encoding")
-    @ColumnDescription(comment = "PEM encoding for the certificate")
+    @Column(name = "PEM_ENCODED_CERT")
+    @ColumnDescription(comment = "PEM encoded  certificate")
     @Lob
     private String pemEncoding;
 
-    @Column(name = "crl_url", length = CommonColumnsLengths.MAX_FREE_TEXT_LENGTH)
+    @Column(name = "CRL_URL", length = CommonColumnsLengths.MAX_FREE_TEXT_LENGTH)
     @ColumnDescription(comment = "URL to the certificate revocation list (CRL)")
     private String crlUrl;
 
-
-
-    @Column(name = "CREATED_ON" , nullable = false)
+    @Column(name = "CREATED_ON", nullable = false)
     LocalDateTime createdOn;
     @Column(name = "LAST_UPDATED_ON", nullable = false)
     LocalDateTime lastUpdatedOn;
@@ -179,7 +176,7 @@ public class DBCertificate extends BaseEntity {
 
     @PrePersist
     public void prePersist() {
-        if(createdOn == null) {
+        if (createdOn == null) {
             createdOn = LocalDateTime.now();
         }
         lastUpdatedOn = LocalDateTime.now();
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 a627668565791ba577eaca47e1ea86ae4e826670..a056aa974256cf4de209f8711ba1e9d4baff07e5 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
@@ -1,36 +1,156 @@
 package eu.europa.ec.edelivery.smp.auth;
 
+import eu.europa.ec.edelivery.security.PreAuthenticatedCertificatePrincipal;
 import eu.europa.ec.edelivery.smp.data.dao.UserDao;
 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.logging.SMPMessageCode;
 import org.springframework.beans.factory.annotation.Autowired;
-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.authentication.*;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.crypto.bcrypt.BCrypt;
+import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
 
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
 import java.util.Collections;
+import java.util.Date;
 import java.util.Optional;
 
+import static java.util.Locale.US;
+
 public class SMPAuthenticationProvider implements AuthenticationProvider {
 
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(AuthenticationProvider.class);
 
+
+    /**
+     * thread safe validator
+     */
+    private static final ThreadLocal<DateFormat> dateFormatLocal = ThreadLocal.withInitial( () -> {
+        return  new SimpleDateFormat("MMM d hh:mm:ss yyyy zzz", US);
+    } );
+
     @Autowired
     UserDao mUserDao;
 
     @Override
-    public Authentication authenticate(Authentication auth)
+    public Authentication authenticate(Authentication authenticationToken)
+            throws AuthenticationException {
+
+        Authentication authentication = null;
+        // PreAuthentication token for the rest service certificate authentication
+        if (authenticationToken instanceof PreAuthenticatedAuthenticationToken) {
+
+            Object principal = authenticationToken.getPrincipal();
+            if (principal instanceof PreAuthenticatedCertificatePrincipal) {
+                authentication = authenticateByCertificateToken((PreAuthenticatedCertificatePrincipal) principal);
+            } else {
+                LOG.warn("Unknown or null PreAuthenticatedAuthenticationToken principal type: " + principal);
+            }
+        } else  if (authenticationToken instanceof UsernamePasswordAuthenticationToken) {
+            authentication = authenticateByUsernameToken((UsernamePasswordAuthenticationToken)authenticationToken);
+        }
+
+
+       // set anonymous token
+       if (authentication == null) {
+           authentication = new AnonymousAuthenticationToken(authenticationToken.toString(), authenticationToken.getPrincipal(),
+                   Collections.singleton(SMPAuthority.S_AUTHORITY_ANONYMOUS));
+           authentication.setAuthenticated(false);
+       }
+           /*
+
+            if (principal instanceof PreAuthenticatedCertificatePrincipal) {
+                // get principal
+                LOG.info("Authenticate: PreAuthenticatedCertificatePrincipal");
+                authentication = authenticateCertificate((PreAuthenticatedCertificatePrincipal) principal);
+            } else if (principal instanceof PreAuthenticatedTokenPrincipal) {
+                authentication = authenticateSecurityToken((PreAuthenticatedTokenPrincipal) principal);
+
+            } else if (principal instanceof PreAuthenticatedAnonymousPrincipal) {
+                authentication = new UnsecureAuthentication();
+                authentication.setAuthenticated(configurationBusiness.isUnsecureLoginEnabled());
+            }
+            else {
+                // unknown principal type
+                authentication = new UnsecureAuthentication();
+                authentication.setAuthenticated(false);
+            }*/
+
+
+        return authentication;
+    }
+
+
+    /**
+     * Authenticate by certificate token got by BlueCoat or X509Certificate authentication)
+     * @param principal - certificate principal
+     * @return authentication value.
+     */
+    public Authentication authenticateByCertificateToken(PreAuthenticatedCertificatePrincipal principal) {
+        mUserDao.findUserByCertificateId(principal.getName());
+
+        DBUser user;
+        String userToken = principal.getName();
+        try {
+
+            Optional<DBUser> oUsr = mUserDao.findUserByCertificateId(userToken);
+            if (!oUsr.isPresent()) {
+                LOG.securityWarn(SMPMessageCode.SEC_USER_NOT_EXISTS, userToken);
+                //https://www.owasp.org/index.php/Authentication_Cheat_Sheet
+                // Do not reveal the status of an existing account. Not to use UsernameNotFoundException
+                throw new BadCredentialsException("Login failed; Invalid userID or password");
+            }
+
+
+            user = oUsr.get();
+        } catch (AuthenticationException ex) {
+            throw ex;
+
+        } catch (RuntimeException ex) {
+            LOG.error("Database connection error", ex);
+            throw new AuthenticationServiceException("Internal server error occurred while user authentication!");
+
+        }
+        // check if certificate is valid
+        Date currentDate = Calendar.getInstance().getTime();
+        // validate  dates
+        if (principal.getNotBefore().after(currentDate)) {
+            throw new AuthenticationServiceException("Invalid certificate: NotBefore: " + dateFormatLocal.get().format(principal.getNotBefore()));
+        } else if (principal.getNotAfter().before(currentDate)) {
+            throw new AuthenticationServiceException("Invalid certificate:  NotAfter: " + dateFormatLocal.get().format(principal.getNotAfter()));
+        }
+        // check if issuer is on trust list.
+
+        // Check crl list
+        String url = user.getCertificate().getCrlUrl();
+        if (url!= null) {
+
+        }
+
+
+        // get role
+        String role = user.getRole();
+        LOG.securityInfo(SMPMessageCode.SEC_USER_AUTHENTICATED, userToken, role);
+        SMPCertificateAuthentication authentication = new SMPCertificateAuthentication(principal, Collections.singletonList(new SMPAuthority(role)), user);
+
+        authentication.setAuthenticated(true);
+        return authentication;
+    }
+
+
+    public Authentication authenticateByUsernameToken(UsernamePasswordAuthenticationToken auth)
             throws AuthenticationException {
 
         // get user
         // test credentials
         // get and return  user roles.
+
+
         String username = auth.getName();
         String password = auth.getCredentials().toString();
 
@@ -72,6 +192,12 @@ public class SMPAuthenticationProvider implements AuthenticationProvider {
 
     @Override
     public boolean supports(Class<?> auth) {
-        return auth.equals(UsernamePasswordAuthenticationToken.class) || auth.equals(SMPAuthenticationToken.class);
+        LOG.info("Support authentication: " + auth);
+        boolean supportAuthentication = auth.equals(UsernamePasswordAuthenticationToken.class) || auth.equals(PreAuthenticatedAuthenticationToken.class);
+        if (!supportAuthentication) {
+            LOG.warn("SMP does not support authentication type: " + auth);
+        }
+
+        return supportAuthentication;
     }
 }
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthority.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthority.java
index 38ac2682072b3cbb49ce618231480c91bda43dea..b0ca43ee578247676bd50d5ef778fee20e02741f 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthority.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthority.java
@@ -9,12 +9,13 @@ 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());
-    public static final SMPAuthority S_AUTHORITY_SMP_ADMIN =  new SMPAuthority(SMPRole.SMP_ADMIN.getCode());
-    public static final SMPAuthority S_AUTHORITY_SERVICE_GROUP =  new SMPAuthority(SMPRole.SERVICE_GROUP_ADMIN.getCode());
-
+    public static final SMPAuthority S_AUTHORITY_SYSTEM_ADMIN = new SMPAuthority(SMPRole.SYSTEM_ADMIN.getCode());
+    public static final SMPAuthority S_AUTHORITY_SMP_ADMIN = new SMPAuthority(SMPRole.SMP_ADMIN.getCode());
+    public static final SMPAuthority S_AUTHORITY_SERVICE_GROUP = new SMPAuthority(SMPRole.SERVICE_GROUP_ADMIN.getCode());
+    public static final SMPAuthority S_AUTHORITY_ANONYMOUS = new SMPAuthority(SMPRole.ANONYMOUS.getCode());
 
     String role;
 
@@ -24,6 +25,6 @@ public class SMPAuthority implements GrantedAuthority {
 
     @Override
     public String getAuthority() {
-        return "ROLE_"+role;
+        return "ROLE_" + role;
     }
 }
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPCertificateAuthentication.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPCertificateAuthentication.java
new file mode 100644
index 0000000000000000000000000000000000000000..0602230c963351cf576d9905777cdc54f1c5d7b0
--- /dev/null
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPCertificateAuthentication.java
@@ -0,0 +1,86 @@
+/**
+ * (C) Copyright 2018 - European Commission | CEF eDelivery
+ * <p>
+ * Licensed under the EUPL, Version 1.2 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * \BDMSL\bdmsl-parent-pom\LICENSE-EUPL-v1.2.pdf or https://joinup.ec.europa.eu/sites/default/files/custom-page/attachment/eupl_v1.2_en.pdf
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+
+package eu.europa.ec.edelivery.smp.auth;
+
+import eu.europa.ec.edelivery.security.PreAuthenticatedCertificatePrincipal;
+import eu.europa.ec.edelivery.smp.data.model.DBUser;
+import org.apache.commons.lang3.time.DateUtils;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class SMPCertificateAuthentication implements Authentication {
+
+    PreAuthenticatedCertificatePrincipal principal;
+    DBUser dbUser;
+
+    List<GrantedAuthority> listAuthorities = new ArrayList<>();
+    boolean isAuthenticated;
+    private static final int SERIAL_PADDING_SIZE =16;
+
+
+    public SMPCertificateAuthentication(PreAuthenticatedCertificatePrincipal principal, List<GrantedAuthority> listAuthorities, DBUser user) {
+        this.principal = principal;
+        this.listAuthorities.addAll(listAuthorities);
+        this.dbUser = user;
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        return listAuthorities;
+    }
+
+    @Override
+    public Object getCredentials() {
+        return this.principal!=null?this.principal.getCredentials():null;
+    }
+
+    @Override
+    public Object getDetails() {
+        return this.principal;
+    }
+
+    @Override
+    public Object getPrincipal() {
+        return this.principal;
+    }
+
+    @Override
+    public boolean isAuthenticated() {
+        return isAuthenticated;
+    }
+
+    @Override
+    public void setAuthenticated(boolean b) throws IllegalArgumentException {
+        isAuthenticated = b;
+    }
+
+    @Override
+    public String getName() {
+        return principal.getName(SERIAL_PADDING_SIZE);
+    }
+
+    @Override
+    public String toString() {
+        return getName();
+    }
+
+
+}
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPRole.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPRole.java
index 12d1d4e2725e91ee83a6b179c211074da3dadce6..1f296a054a2e2d9312e278f1b1a3b1dbb8df1082 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPRole.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPRole.java
@@ -2,22 +2,18 @@ package eu.europa.ec.edelivery.smp.auth;
 
 public enum SMPRole {
 
+    ANONYMOUS("ANONYMOUS"),
     SMP_ADMIN("SMP_ADMIN"),
     SERVICE_GROUP_ADMIN("SERVICE_GROUP_ADMIN"),
     SYSTEM_ADMIN("SYSTEM_ADMIN");
 
-
-
-
     String code;
-    SMPRole(String code){
+
+    SMPRole(String code) {
         this.code = code;
     }
 
     public String getCode() {
         return code;
     }
-
-
-
 }
diff --git a/smp-webapp/src/main/resources/spring-security.xml b/smp-webapp/src/main/resources/spring-security.xml
index fe56dc85107363be001ebc83dfd210b02fa1e8f4..3c4997decac0bafb6b6ae17a53c05c4fa0f25cc6 100644
--- a/smp-webapp/src/main/resources/spring-security.xml
+++ b/smp-webapp/src/main/resources/spring-security.xml
@@ -38,26 +38,9 @@
 
     <authentication-manager alias="smpAuthenticationManager">
         <authentication-provider ref="smpAuthProvider"/>
-        <authentication-provider ref="preauthAuthProvider"/>
-
     </authentication-manager>
 
-    <!-- user detail service is used only in preAhtProviders for cert authentication that is why search is only on cert table-->
-    <!-- database Cert ID search must be case insensitive  -->
-    <jdbc-user-service id="smpJdbcUserDetailsService"
-                       data-source-ref="dataSource"
-                       users-by-username-query="SELECT c.CERTIFICATE_ID AS USERNAME, 'dummy' AS PASWORD, u.ACTIVE FROM SMP_CERTIFICATE c INNER JOIN SMP_USER u ON (u.id = c.id) WHERE lower(c.CERTIFICATE_ID) = lower(?)"
-                       authorities-by-username-query="SELECT c.CERTIFICATE_ID AS USERNAME, u.ROLE FROM SMP_CERTIFICATE c INNER JOIN SMP_USER u ON (u.id = c.id) WHERE lower(c.CERTIFICATE_ID) = lower(?)"/>
-
-    <b:bean id="preauthAuthProvider"
-            class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
-        <b:property name="preAuthenticatedUserDetailsService">
-            <b:bean id="userDetailsServiceWrapper"
-                    class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
-                <b:property name="userDetailsService" ref="smpJdbcUserDetailsService"/>
-            </b:bean>
-        </b:property>
-    </b:bean>
+    <b:bean id="smpAuthProvider" class="eu.europa.ec.edelivery.smp.auth.SMPAuthenticationProvider" />
 
     <b:bean id="blueCoatReverseProxyAuthFilter"
             class="eu.europa.ec.edelivery.security.BlueCoatAuthenticationFilter">
@@ -70,15 +53,13 @@
         <b:property name="authenticationManager" ref="smpAuthenticationManager"/>
     </b:bean>
 
-    <!-- Slashes in participant or document identifiers are disallowed by default -->
+    <!-- encoded Slashes are disallowed by default but SMP is using
+    them in participant or document identifiers  -->
     <http-firewall ref="httpFirewall"/>
     <b:bean id="httpFirewall" class="org.springframework.security.web.firewall.DefaultHttpFirewall">
         <b:property name="allowUrlEncodedSlash" value="${encodedSlashesAllowedInUrl}"/>
     </b:bean>
 
-    <b:bean id="smpAuthProvider" class="eu.europa.ec.edelivery.smp.auth.SMPAuthenticationProvider">
-    </b:bean>
-
 
 
 </b:beans>