You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2021/11/12 17:02:45 UTC

[syncope] 02/02: [SYNCOPE-1650] Enforcing general id pattern for usernames only when either no account policy is defined or no pattern is defined with DefaultAccountRule config

This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch 2_1_X
in repository https://gitbox.apache.org/repos/asf/syncope.git

commit 2f53a63f2abd5d0479d5242baa831d13186215bd
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Fri Nov 12 18:02:35 2021 +0100

    [SYNCOPE-1650] Enforcing general id pattern for usernames only when either no account policy is defined or no pattern is defined with DefaultAccountRule config
---
 .../syncope/common/lib/SyncopeConstants.java       | 23 ++-------
 .../rest/api/batch/BatchPayloadGenerator.java      | 10 ++--
 .../rest/api/batch/BatchPayloadLineReader.java     | 10 ++--
 .../common/rest/api/service/JAXRSService.java      |  4 ++
 .../org/apache/syncope/core/logic/RoleLogic.java   |  4 +-
 .../core/persistence/api/entity/Entity.java        | 10 ++++
 .../validation/EmailAddressValidator.java          |  4 +-
 .../core/persistence/jpa/dao/JPAUserDAO.java       | 55 +++++++++++-----------
 .../jpa/validation/entity/AbstractValidator.java   |  5 --
 .../jpa/validation/entity/AnyObjectValidator.java  |  3 +-
 .../validation/entity/ApplicationValidator.java    |  3 +-
 .../entity/ExternalResourceValidator.java          |  3 +-
 .../jpa/validation/entity/GroupValidator.java      |  3 +-
 .../validation/entity/ImplementationValidator.java |  3 +-
 .../jpa/validation/entity/PrivilegeValidator.java  |  3 +-
 .../jpa/validation/entity/RoleValidator.java       |  7 +--
 .../jpa/validation/entity/SchemaKeyValidator.java  | 30 +++++-------
 .../core/persistence/jpa/inner/AnySearchTest.java  |  3 +-
 .../core/provisioning/api/IntAttrNameParser.java   | 18 +++----
 .../java/data/NotificationDataBinderImpl.java      |  4 +-
 .../syncope/core/rest/cxf/batch/BatchProcess.java  |  4 +-
 .../core/rest/cxf/service/AbstractAnyService.java  |  5 +-
 .../cxf/service/AbstractExecutableService.java     |  4 +-
 .../core/spring/policy/DefaultAccountRule.java     | 13 +++--
 .../core/spring/security/AuthContextUtils.java     |  4 +-
 .../core/spring/security/AuthDataAccessor.java     | 10 ++--
 26 files changed, 121 insertions(+), 124 deletions(-)

diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java b/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java
index 42b133c..68f5977 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java
@@ -32,16 +32,12 @@ public final class SyncopeConstants {
 
     public static final String ROOT_REALM = "/";
 
-    public static final String REALM_ANYTYPE = "REALM";
-
-    public static final Set<String> FULL_ADMIN_REALMS = Collections.singleton("/");
+    public static final Set<String> FULL_ADMIN_REALMS = Collections.singleton(ROOT_REALM);
 
-    public static final String UNAUTHENTICATED = "unauthenticated";
+    public static final String REALM_ANYTYPE = "REALM";
 
     public static final String ENUM_VALUES_SEPARATOR = ";";
 
-    public static final String NAME_PATTERN = "[\\p{L}\\p{gc=Mn}\\p{gc=Me}\\p{gc=Mc}\\p{Digit}\\p{gc=Pc} \\-@.~]+";
-
     public static final String[] DATE_PATTERNS = {
         "yyyy-MM-dd'T'HH:mm:ssZ",
         "EEE, dd MMM yyyy HH:mm:ss z",
@@ -52,24 +48,13 @@ public final class SyncopeConstants {
 
     public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ssZ";
 
-    public static final String ROOT_LOGGER = "ROOT";
-
-    public static final String GROUP_OWNER_ROLE = "GROUP_OWNER";
-
-    public static final Pattern EMAIL_PATTERN = Pattern.compile(
-            "^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*"
-            + "@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$",
-            Pattern.CASE_INSENSITIVE);
-
     public static final String UUID_REGEX = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
 
     public static final Pattern UUID_PATTERN = Pattern.compile(UUID_REGEX);
 
-    public static final String ENCRYPTED_DECODE_CONVERSION_PATTERN = "ENCRYPTED_DECODE_CONVERSION_PATTERN";
-
-    public static final String DOUBLE_DASH = "--";
+    public static final String ROOT_LOGGER = "ROOT";
 
-    public static final String CRLF = "\r\n";
+    public static final String ENCRYPTED_DECODE_CONVERSION_PATTERN = "ENCRYPTED_DECODE_CONVERSION_PATTERN";
 
     private SyncopeConstants() {
         // private constructor for utility class
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadGenerator.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadGenerator.java
index 18d5f64..85e2b17 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadGenerator.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadGenerator.java
@@ -21,7 +21,7 @@ package org.apache.syncope.common.rest.api.batch;
 import java.util.List;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.rest.api.service.JAXRSService;
 
 public final class BatchPayloadGenerator {
 
@@ -31,10 +31,10 @@ public final class BatchPayloadGenerator {
         StringBuilder payload = new StringBuilder();
 
         items.forEach(item -> {
-            payload.append(boundary).append(SyncopeConstants.CRLF);
+            payload.append(boundary).append(JAXRSService.CRLF);
             payload.append(HttpHeaders.CONTENT_TYPE).append(": ").append("application/http").append('\n');
             payload.append("Content-Transfer-Encoding: binary").append('\n');
-            payload.append(SyncopeConstants.CRLF);
+            payload.append(JAXRSService.CRLF);
 
             if (item instanceof BatchRequestItem) {
                 BatchRequestItem bri = BatchRequestItem.class.cast(item);
@@ -59,7 +59,7 @@ public final class BatchPayloadGenerator {
                         payload.append(key).append(": ").append(value).append('\n');
                     });
                 });
-                payload.append(SyncopeConstants.CRLF);
+                payload.append(JAXRSService.CRLF);
             }
 
             if (item.getContent() != null) {
@@ -67,7 +67,7 @@ public final class BatchPayloadGenerator {
             }
         });
 
-        payload.append(boundary).append(SyncopeConstants.DOUBLE_DASH).append('\n');
+        payload.append(boundary).append(JAXRSService.DOUBLE_DASH).append('\n');
 
         return payload.toString();
     }
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadLineReader.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadLineReader.java
index b4a4d9f..0fca90b 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadLineReader.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/batch/BatchPayloadLineReader.java
@@ -27,8 +27,8 @@ import java.util.ArrayList;
 import java.util.List;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
-import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.JAXRSService;
 
 public class BatchPayloadLineReader implements AutoCloseable {
 
@@ -69,8 +69,8 @@ public class BatchPayloadLineReader implements AutoCloseable {
     }
 
     private boolean isBoundary(final String currentLine) {
-        return (currentBoundary + SyncopeConstants.CRLF).equals(currentLine)
-                || (currentBoundary + SyncopeConstants.DOUBLE_DASH + SyncopeConstants.CRLF).equals(currentLine);
+        return (currentBoundary + JAXRSService.CRLF).equals(currentLine)
+                || (currentBoundary + JAXRSService.DOUBLE_DASH + JAXRSService.CRLF).equals(currentLine);
     }
 
     private int fillBuffer() throws IOException {
@@ -137,9 +137,9 @@ public class BatchPayloadLineReader implements AutoCloseable {
                         ? DEFAULT_CHARSET
                         : Charset.forName(charsetString);
 
-                currentBoundary = SyncopeConstants.DOUBLE_DASH + multipartMixed.getParameters().
+                currentBoundary = JAXRSService.DOUBLE_DASH + multipartMixed.getParameters().
                         get(RESTHeaders.BOUNDARY_PARAMETER);
-            } else if (SyncopeConstants.CRLF.equals(currentLine)) {
+            } else if (JAXRSService.CRLF.equals(currentLine)) {
                 readState.foundLinebreak();
             } else if (isBoundary(currentLine)) {
                 readState.foundBoundary();
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java
index abcc0e2..6ebdfd3 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java
@@ -48,4 +48,8 @@ public interface JAXRSService {
 
     String PARAM_ANYTYPEKEY = "anyTypeKey";
 
+    String DOUBLE_DASH = "--";
+
+    String CRLF = "\r\n";
+
 }
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java
index 2faffaa..b51b789 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java
@@ -24,7 +24,6 @@ import java.util.stream.Collectors;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.RoleTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
@@ -32,6 +31,7 @@ import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
 import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.provisioning.api.data.RoleDataBinder;
+import org.apache.syncope.core.spring.security.AuthDataAccessor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
@@ -83,7 +83,7 @@ public class RoleLogic extends AbstractTransactionalLogic<RoleTO> {
 
     @PreAuthorize("hasRole('" + StandardEntitlement.ROLE_DELETE + "')")
     public RoleTO delete(final String key) {
-        if (SyncopeConstants.GROUP_OWNER_ROLE.equals(key)) {
+        if (AuthDataAccessor.GROUP_OWNER_ROLE.equals(key)) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRole);
             sce.getElements().add("This Role cannot be deleted");
             throw sce;
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Entity.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Entity.java
index 1f59d0b..ac7b75d 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Entity.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Entity.java
@@ -19,8 +19,18 @@
 package org.apache.syncope.core.persistence.api.entity;
 
 import java.io.Serializable;
+import java.util.regex.Pattern;
 
 public interface Entity extends Serializable {
 
+    String ID_REGEX = "[\\p{L}\\p{gc=Mn}\\p{gc=Me}\\p{gc=Mc}\\p{Digit}\\p{gc=Pc} \\-@.~]+";
+
+    Pattern ID_PATTERN = Pattern.compile('^' + Entity.ID_REGEX, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
+
+    Pattern EMAIL_PATTERN = Pattern.compile(
+            "^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*"
+            + "@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$",
+            Pattern.CASE_INSENSITIVE);
+
     String getKey();
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/EmailAddressValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/EmailAddressValidator.java
index 1202373..ebc9e9d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/EmailAddressValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/EmailAddressValidator.java
@@ -19,8 +19,8 @@
 package org.apache.syncope.core.persistence.jpa.attrvalue.validation;
 
 import java.util.regex.Matcher;
-import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException;
+import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 
 public class EmailAddressValidator extends AbstractValidator {
@@ -29,7 +29,7 @@ public class EmailAddressValidator extends AbstractValidator {
 
     @Override
     protected void doValidate(final PlainAttrValue attrValue) {
-        Matcher matcher = SyncopeConstants.EMAIL_PATTERN.matcher(attrValue.<CharSequence>getValue());
+        Matcher matcher = Entity.EMAIL_PATTERN.matcher(attrValue.<CharSequence>getValue());
         if (!matcher.matches()) {
             throw new InvalidPlainAttrValueException("\"" + attrValue.getValue() + "\" is not a valid email address");
         }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index 054461d..3e5892c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -27,7 +27,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
-import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import javax.annotation.Resource;
 import javax.persistence.NoResultException;
@@ -35,7 +34,6 @@ import javax.persistence.PersistenceException;
 import javax.persistence.Query;
 import javax.persistence.TypedQuery;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
@@ -53,6 +51,7 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.AccessToken;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.Delegation;
+import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.Privilege;
 import org.apache.syncope.core.persistence.api.entity.Realm;
@@ -79,9 +78,6 @@ import org.springframework.transaction.annotation.Transactional;
 
 public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
 
-    protected static final Pattern USERNAME_PATTERN =
-            Pattern.compile("^" + SyncopeConstants.NAME_PATTERN, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
-
     protected static final Encryptor ENCRYPTOR = Encryptor.getInstance();
 
     @Autowired
@@ -396,31 +392,34 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
                 throw new AccountPolicyException("Not allowed: " + user.getUsername());
             }
 
-            if (!USERNAME_PATTERN.matcher(user.getUsername()).matches()) {
-                throw new AccountPolicyException("Character(s) not allowed: " + user.getUsername());
-            }
-            user.getLinkedAccounts().stream().
-                    filter(account -> account.getUsername() != null).
-                    forEach(account -> {
-                        if (!USERNAME_PATTERN.matcher(account.getUsername()).matches()) {
-                            throw new AccountPolicyException("Character(s) not allowed: " + account.getUsername());
-                        }
-                    });
-
-            for (AccountPolicy policy : getAccountPolicies(user)) {
-                for (Implementation impl : policy.getRules()) {
-                    ImplementationManager.buildAccountRule(impl).ifPresent(rule -> {
-                        rule.enforce(user);
-
-                        user.getLinkedAccounts().stream().
-                                filter(account -> account.getUsername() != null).
-                                forEach(account -> rule.enforce(account));
-                    });
+            List<AccountPolicy> accountPolicies = getAccountPolicies(user);
+            if (accountPolicies.isEmpty()) {
+                if (!Entity.ID_PATTERN.matcher(user.getUsername()).matches()) {
+                    throw new AccountPolicyException("Character(s) not allowed: " + user.getUsername());
                 }
+                user.getLinkedAccounts().stream().
+                        filter(account -> account.getUsername() != null).
+                        forEach(account -> {
+                            if (!Entity.ID_PATTERN.matcher(account.getUsername()).matches()) {
+                                throw new AccountPolicyException("Character(s) not allowed: " + account.getUsername());
+                            }
+                        });
+            } else {
+                for (AccountPolicy policy : accountPolicies) {
+                    for (Implementation impl : policy.getRules()) {
+                        ImplementationManager.buildAccountRule(impl).ifPresent(rule -> {
+                            rule.enforce(user);
+
+                            user.getLinkedAccounts().stream().
+                                    filter(account -> account.getUsername() != null).
+                                    forEach(account -> rule.enforce(account));
+                        });
+                    }
 
-                suspend |= user.getFailedLogins() != null && policy.getMaxAuthenticationAttempts() > 0
-                        && user.getFailedLogins() > policy.getMaxAuthenticationAttempts() && !user.isSuspended();
-                propagateSuspension |= policy.isPropagateSuspension();
+                    suspend |= user.getFailedLogins() != null && policy.getMaxAuthenticationAttempts() > 0
+                            && user.getFailedLogins() > policy.getMaxAuthenticationAttempts() && !user.isSuspended();
+                    propagateSuspension |= policy.isPropagateSuspension();
+                }
             }
         } catch (PersistenceException | InvalidEntityException e) {
             throw e;
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AbstractValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AbstractValidator.java
index b06d5ea..785284f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AbstractValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AbstractValidator.java
@@ -19,9 +19,7 @@
 package org.apache.syncope.core.persistence.jpa.validation.entity;
 
 import java.lang.annotation.Annotation;
-import java.util.regex.Pattern;
 import javax.validation.ConstraintValidator;
-import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,9 +28,6 @@ public abstract class AbstractValidator<A extends Annotation, T> implements Cons
 
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractValidator.class);
 
-    protected static final Pattern KEY_PATTERN =
-            Pattern.compile("^" + SyncopeConstants.NAME_PATTERN, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
-
     @Override
     public void initialize(final A annotation) {
         // no initialization
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyObjectValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyObjectValidator.java
index 08f5023..319b3f0 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyObjectValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyObjectValidator.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.jpa.validation.entity;
 
 import javax.validation.ConstraintValidatorContext;
 import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 
 public class AnyObjectValidator extends AbstractValidator<AnyObjectCheck, AnyObject> {
@@ -28,7 +29,7 @@ public class AnyObjectValidator extends AbstractValidator<AnyObjectCheck, AnyObj
     public boolean isValid(final AnyObject anyObject, final ConstraintValidatorContext context) {
         context.disableDefaultConstraintViolation();
 
-        boolean isValid = anyObject.getName() != null && KEY_PATTERN.matcher(anyObject.getName()).matches();
+        boolean isValid = anyObject.getName() != null && Entity.ID_PATTERN.matcher(anyObject.getName()).matches();
 
         if (!isValid) {
             context.buildConstraintViolationWithTemplate(
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ApplicationValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ApplicationValidator.java
index 65ee56c..314ce9b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ApplicationValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ApplicationValidator.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.persistence.jpa.validation.entity;
 import javax.validation.ConstraintValidatorContext;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.core.persistence.api.entity.Application;
+import org.apache.syncope.core.persistence.api.entity.Entity;
 
 public class ApplicationValidator extends AbstractValidator<ApplicationCheck, Application> {
 
@@ -28,7 +29,7 @@ public class ApplicationValidator extends AbstractValidator<ApplicationCheck, Ap
     public boolean isValid(final Application application, final ConstraintValidatorContext context) {
         context.disableDefaultConstraintViolation();
 
-        if (application.getKey() == null || !KEY_PATTERN.matcher(application.getKey()).matches()) {
+        if (application.getKey() == null || !Entity.ID_PATTERN.matcher(application.getKey()).matches()) {
             context.buildConstraintViolationWithTemplate(
                     getTemplate(EntityViolationType.InvalidKey, application.getKey())).
                     addPropertyNode("key").addConstraintViolation();
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
index 8254baa..b98160b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
@@ -24,6 +24,7 @@ import java.util.Set;
 import javax.validation.ConstraintValidatorContext;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.Item;
 import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
@@ -75,7 +76,7 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
     public boolean isValid(final ExternalResource resource, final ConstraintValidatorContext context) {
         context.disableDefaultConstraintViolation();
 
-        if (resource.getKey() == null || !KEY_PATTERN.matcher(resource.getKey()).matches()) {
+        if (resource.getKey() == null || !Entity.ID_PATTERN.matcher(resource.getKey()).matches()) {
             context.buildConstraintViolationWithTemplate(
                     getTemplate(EntityViolationType.InvalidKey, resource.getKey())).
                     addPropertyNode("key").addConstraintViolation();
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/GroupValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/GroupValidator.java
index 282f72b..3ff9e8f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/GroupValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/GroupValidator.java
@@ -24,6 +24,7 @@ import javax.validation.ConstraintValidatorContext;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 
@@ -44,7 +45,7 @@ public class GroupValidator extends AbstractValidator<GroupCheck, Group> {
                     addPropertyNode("owner").addConstraintViolation();
         }
 
-        if (isValid && (group.getName() == null || !KEY_PATTERN.matcher(group.getName()).matches())) {
+        if (isValid && (group.getName() == null || !Entity.ID_PATTERN.matcher(group.getName()).matches())) {
             isValid = false;
 
             context.buildConstraintViolationWithTemplate(
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ImplementationValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ImplementationValidator.java
index fd88ea5..3efdf92 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ImplementationValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ImplementationValidator.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.jpa.validation.entity;
 
 import javax.validation.ConstraintValidatorContext;
 import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 
 public class ImplementationValidator extends AbstractValidator<ImplementationCheck, Implementation> {
@@ -28,7 +29,7 @@ public class ImplementationValidator extends AbstractValidator<ImplementationChe
     public boolean isValid(final Implementation resource, final ConstraintValidatorContext context) {
         context.disableDefaultConstraintViolation();
 
-        if (resource.getKey() == null || !KEY_PATTERN.matcher(resource.getKey()).matches()) {
+        if (resource.getKey() == null || !Entity.ID_PATTERN.matcher(resource.getKey()).matches()) {
             context.buildConstraintViolationWithTemplate(
                     getTemplate(EntityViolationType.InvalidKey, resource.getKey())).
                     addPropertyNode("key").addConstraintViolation();
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/PrivilegeValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/PrivilegeValidator.java
index acdbf01..6d4019f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/PrivilegeValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/PrivilegeValidator.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.jpa.validation.entity;
 
 import javax.validation.ConstraintValidatorContext;
 import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.Privilege;
 
 public class PrivilegeValidator extends AbstractValidator<PrivilegeCheck, Privilege> {
@@ -28,7 +29,7 @@ public class PrivilegeValidator extends AbstractValidator<PrivilegeCheck, Privil
     public boolean isValid(final Privilege privilege, final ConstraintValidatorContext context) {
         context.disableDefaultConstraintViolation();
 
-        if (privilege.getKey() == null || !KEY_PATTERN.matcher(privilege.getKey()).matches()) {
+        if (privilege.getKey() == null || !Entity.ID_PATTERN.matcher(privilege.getKey()).matches()) {
             context.buildConstraintViolationWithTemplate(
                     getTemplate(EntityViolationType.InvalidKey, privilege.getKey())).
                     addPropertyNode("key").addConstraintViolation();
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RoleValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RoleValidator.java
index c62d149..19bf173 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RoleValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RoleValidator.java
@@ -19,9 +19,10 @@
 package org.apache.syncope.core.persistence.jpa.validation.entity;
 
 import javax.validation.ConstraintValidatorContext;
-import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.Role;
+import org.apache.syncope.core.spring.security.AuthDataAccessor;
 
 public class RoleValidator extends AbstractValidator<RoleCheck, Role> {
 
@@ -30,8 +31,8 @@ public class RoleValidator extends AbstractValidator<RoleCheck, Role> {
         context.disableDefaultConstraintViolation();
 
         if (role.getKey() == null
-                || (!SyncopeConstants.GROUP_OWNER_ROLE.equals(role.getKey())
-                && !KEY_PATTERN.matcher(role.getKey()).matches())) {
+                || (!AuthDataAccessor.GROUP_OWNER_ROLE.equals(role.getKey())
+                && !Entity.ID_PATTERN.matcher(role.getKey()).matches())) {
 
             context.buildConstraintViolationWithTemplate(
                     getTemplate(EntityViolationType.InvalidKey, role.getKey())).
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchemaKeyValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchemaKeyValidator.java
index e0a1676..5369b31 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchemaKeyValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchemaKeyValidator.java
@@ -20,39 +20,31 @@ package org.apache.syncope.core.persistence.jpa.validation.entity;
 
 import javax.validation.ConstraintValidatorContext;
 import org.apache.syncope.common.lib.types.EntityViolationType;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.apache.syncope.core.persistence.api.entity.Schema;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtils;
 
-public class SchemaKeyValidator extends AbstractValidator<SchemaKeyCheck, Object> {
+public class SchemaKeyValidator extends AbstractValidator<SchemaKeyCheck, Schema> {
 
     @Override
-    public boolean isValid(final Object object, final ConstraintValidatorContext context) {
-        String key = null;
-        if (object instanceof PlainSchema) {
-            key = ((PlainSchema) object).getKey();
-        } else if (object instanceof DerSchema) {
-            key = ((DerSchema) object).getKey();
-        } else if (object instanceof VirSchema) {
-            key = ((VirSchema) object).getKey();
-        }
+    public boolean isValid(final Schema schema, final ConstraintValidatorContext context) {
 
-        boolean isValid = KEY_PATTERN.matcher(key).matches();
-        if (!isValid) {
+        if (schema.getKey() == null || !Entity.ID_PATTERN.matcher(schema.getKey()).matches()) {
             context.disableDefaultConstraintViolation();
             context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidKey, key)).
+                    getTemplate(EntityViolationType.InvalidKey, schema.getKey())).
                     addPropertyNode("key").addConstraintViolation();
-        } else if (JPAAnyUtils.matchesFieldName(key)) {
+
+            return false;
+        } else if (JPAAnyUtils.matchesFieldName(schema.getKey())) {
             context.disableDefaultConstraintViolation();
             context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidKey, "Schema key not allowed: " + key)).
+                    getTemplate(EntityViolationType.InvalidKey, "Schema key not allowed: " + schema.getKey())).
                     addPropertyNode("key").addConstraintViolation();
 
             return false;
         }
 
-        return isValid;
+        return true;
     }
 }
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
index e6692f9..1561154 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
@@ -63,6 +63,7 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthDataAccessor;
 import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
 import org.apache.syncope.core.spring.security.SyncopeGrantedAuthority;
 import org.junit.jupiter.api.Test;
@@ -600,7 +601,7 @@ public class AnySearchTest extends AbstractTest {
     public void asGroupOwner() {
         // prepare authentication
         Map<String, Set<String>> entForRealms = new HashMap<>();
-        roleDAO.find(SyncopeConstants.GROUP_OWNER_ROLE).getEntitlements().forEach(entitlement -> {
+        roleDAO.find(AuthDataAccessor.GROUP_OWNER_ROLE).getEntitlements().forEach(entitlement -> {
             Set<String> realms = Optional.ofNullable(entForRealms.get(entitlement)).orElseGet(() -> {
                 HashSet<String> r = new HashSet<>();
                 entForRealms.put(entitlement, r);
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/IntAttrNameParser.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/IntAttrNameParser.java
index cf5bff5..d640ae9 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/IntAttrNameParser.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/IntAttrNameParser.java
@@ -22,40 +22,40 @@ import java.text.ParseException;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.Schema;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
 @SuppressWarnings({ "squid:S4784", "squid:S3776" })
 public class IntAttrNameParser {
-    
+
     private static final String END_PATTERN = ")\\]\\.(.+)";
 
     private static final Pattern PRIVILEGE_PATTERN = Pattern.compile(
-            "^privileges\\[(" + SyncopeConstants.NAME_PATTERN + ")\\]");
+            "^privileges\\[(" + Entity.ID_REGEX + ")\\]");
 
     private static final Pattern ENCLOSING_GROUP_PATTERN = Pattern.compile(
-            "^groups\\[(" + SyncopeConstants.NAME_PATTERN + END_PATTERN);
+            "^groups\\[(" + Entity.ID_REGEX + END_PATTERN);
 
     private static final Pattern RELATED_USER_PATTERN = Pattern.compile(
-            "^users\\[(" + SyncopeConstants.NAME_PATTERN + END_PATTERN);
+            "^users\\[(" + Entity.ID_REGEX + END_PATTERN);
 
     private static final Pattern RELATED_ANY_OBJECT_PATTERN = Pattern.compile(
-            "^anyObjects\\[(" + SyncopeConstants.NAME_PATTERN + END_PATTERN);
+            "^anyObjects\\[(" + Entity.ID_REGEX + END_PATTERN);
 
     private static final Pattern MEMBERSHIP_PATTERN = Pattern.compile(
-            "^memberships\\[(" + SyncopeConstants.NAME_PATTERN + END_PATTERN);
+            "^memberships\\[(" + Entity.ID_REGEX + END_PATTERN);
 
     private static final Pattern RELATIONSHIP_PATTERN = Pattern.compile(
-            "^relationships\\[(" + SyncopeConstants.NAME_PATTERN + ")\\]"
-            + "\\[(" + SyncopeConstants.NAME_PATTERN + END_PATTERN);
+            "^relationships\\[(" + Entity.ID_REGEX + ")\\]"
+            + "\\[(" + Entity.ID_REGEX + END_PATTERN);
 
     @Autowired
     private PlainSchemaDAO plainSchemaDAO;
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
index 648520a..9863863 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
@@ -22,7 +22,6 @@ import java.text.ParseException;
 import java.util.regex.Matcher;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.core.provisioning.api.data.NotificationDataBinder;
 import org.apache.syncope.common.lib.to.NotificationTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
@@ -34,6 +33,7 @@ import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
 import org.apache.syncope.core.persistence.api.dao.MailTemplateDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyAbout;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.MailTemplate;
 import org.apache.syncope.core.provisioning.api.IntAttrNameParser;
@@ -126,7 +126,7 @@ public class NotificationDataBinderImpl implements NotificationDataBinder {
 
         if (!notification.getStaticRecipients().isEmpty()) {
             notification.getStaticRecipients().forEach(mail -> {
-                Matcher matcher = SyncopeConstants.EMAIL_PATTERN.matcher(mail);
+                Matcher matcher = Entity.EMAIL_PATTERN.matcher(mail);
                 if (!matcher.matches()) {
                     LOG.error("Invalid mail address: {}", mail);
                     sce.getElements().add("staticRecipients: " + mail);
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/batch/BatchProcess.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/batch/BatchProcess.java
index e6426fd..2c13095 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/batch/BatchProcess.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/batch/BatchProcess.java
@@ -25,10 +25,10 @@ import javax.servlet.ServletConfig;
 import javax.servlet.http.HttpServletRequest;
 import org.apache.cxf.transport.http.AbstractHTTPDestination;
 import org.apache.cxf.transport.http.DestinationRegistry;
-import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.rest.api.batch.BatchPayloadGenerator;
 import org.apache.syncope.common.rest.api.batch.BatchRequestItem;
 import org.apache.syncope.common.rest.api.batch.BatchResponseItem;
+import org.apache.syncope.common.rest.api.service.JAXRSService;
 import org.apache.syncope.core.persistence.api.dao.BatchDAO;
 import org.apache.syncope.core.persistence.api.entity.Batch;
 import org.slf4j.Logger;
@@ -131,7 +131,7 @@ public class BatchProcess implements Runnable {
             }
         });
 
-        String results = BatchPayloadGenerator.generate(batchResponseItems, SyncopeConstants.DOUBLE_DASH + boundary);
+        String results = BatchPayloadGenerator.generate(batchResponseItems, JAXRSService.DOUBLE_DASH + boundary);
 
         Batch batch = batchDAO.find(boundary);
         if (batch == null) {
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
index 2d8c3b4..f857cc1 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
@@ -48,6 +48,7 @@ import org.apache.syncope.common.rest.api.batch.BatchPayloadGenerator;
 import org.apache.syncope.common.rest.api.batch.BatchResponseItem;
 import org.apache.syncope.common.rest.api.beans.AnyQuery;
 import org.apache.syncope.common.rest.api.service.AnyService;
+import org.apache.syncope.common.rest.api.service.JAXRSService;
 import org.apache.syncope.core.logic.AbstractAnyLogic;
 import org.apache.syncope.core.persistence.api.dao.AnyDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
@@ -282,7 +283,7 @@ public abstract class AbstractAnyService<TO extends AnyTO, P extends AnyPatch>
 
         String boundary = "deassociate_" + SecureRandomUtils.generateRandomUUID().toString();
         return Response.ok(BatchPayloadGenerator.generate(
-                batchResponseItems, SyncopeConstants.DOUBLE_DASH + boundary)).
+                batchResponseItems, JAXRSService.DOUBLE_DASH + boundary)).
                 type(RESTHeaders.multipartMixedWith(boundary)).
                 build();
     }
@@ -371,7 +372,7 @@ public abstract class AbstractAnyService<TO extends AnyTO, P extends AnyPatch>
 
         String boundary = "associate_" + SecureRandomUtils.generateRandomUUID().toString();
         return Response.ok(BatchPayloadGenerator.generate(
-                batchResponseItems, SyncopeConstants.DOUBLE_DASH + boundary)).
+                batchResponseItems, JAXRSService.DOUBLE_DASH + boundary)).
                 type(RESTHeaders.multipartMixedWith(boundary)).
                 build();
     }
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractExecutableService.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractExecutableService.java
index 48d238c..10936bf 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractExecutableService.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractExecutableService.java
@@ -21,7 +21,6 @@ package org.apache.syncope.core.rest.cxf.service;
 import java.util.List;
 import javax.ws.rs.core.Response;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.to.JobTO;
 import org.apache.syncope.common.lib.to.PagedResult;
@@ -33,6 +32,7 @@ import org.apache.syncope.common.rest.api.beans.ExecDeleteQuery;
 import org.apache.syncope.common.rest.api.beans.ExecQuery;
 import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
 import org.apache.syncope.common.rest.api.service.ExecutableService;
+import org.apache.syncope.common.rest.api.service.JAXRSService;
 import org.apache.syncope.core.logic.AbstractExecutableLogic;
 import org.apache.syncope.core.spring.security.SecureRandomUtils;
 
@@ -71,7 +71,7 @@ public abstract class AbstractExecutableService extends AbstractServiceImpl impl
 
         String boundary = "deleteExecutions_" + SecureRandomUtils.generateRandomUUID().toString();
         return Response.ok(BatchPayloadGenerator.generate(
-                batchResponseItems, SyncopeConstants.DOUBLE_DASH + boundary)).
+                batchResponseItems, JAXRSService.DOUBLE_DASH + boundary)).
                 type(RESTHeaders.multipartMixedWith(boundary)).
                 build();
     }
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/policy/DefaultAccountRule.java b/core/spring/src/main/java/org/apache/syncope/core/spring/policy/DefaultAccountRule.java
index 703b8a9..e430f72 100644
--- a/core/spring/src/main/java/org/apache/syncope/core/spring/policy/DefaultAccountRule.java
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/policy/DefaultAccountRule.java
@@ -29,6 +29,7 @@ import org.apache.syncope.common.lib.policy.AccountRuleConf;
 import org.apache.syncope.common.lib.policy.DefaultAccountRuleConf;
 import org.apache.syncope.core.persistence.api.dao.AccountRule;
 import org.apache.syncope.core.persistence.api.dao.AccountRuleConfClass;
+import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.springframework.transaction.annotation.Transactional;
@@ -37,8 +38,6 @@ import org.springframework.util.CollectionUtils;
 @AccountRuleConfClass(DefaultAccountRuleConf.class)
 public class DefaultAccountRule implements AccountRule {
 
-    private static final Pattern DEFAULT_PATTERN = Pattern.compile("[a-zA-Z0-9-_@. ]+");
-
     private DefaultAccountRuleConf conf;
 
     @Override
@@ -78,22 +77,22 @@ public class DefaultAccountRule implements AccountRule {
         }
 
         // check pattern
-        Pattern pattern = (conf.getPattern() == null) ? DEFAULT_PATTERN : Pattern.compile(conf.getPattern());
+        Pattern pattern = conf.getPattern() == null ? Entity.ID_PATTERN : Pattern.compile(conf.getPattern());
         if (!pattern.matcher(username).matches()) {
             throw new AccountPolicyException("Username does not match pattern");
         }
 
         // check prefix
         conf.getPrefixesNotPermitted().stream().
-                filter(prefix -> username.startsWith(prefix)).
-                forEach(item -> {
+                filter(username::startsWith).findAny().
+                ifPresent(item -> {
                     throw new AccountPolicyException("Prefix not permitted");
                 });
 
         // check suffix
         conf.getSuffixesNotPermitted().stream().
-                filter(suffix -> username.endsWith(suffix)).
-                forEach(item -> {
+                filter(username::endsWith).findAny().
+                ifPresent(item -> {
                     throw new AccountPolicyException("Suffix not permitted");
                 });
     }
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java
index f829105..a1a17fc 100644
--- a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java
@@ -41,6 +41,8 @@ public final class AuthContextUtils {
 
     private static final Logger LOG = LoggerFactory.getLogger(AuthContextUtils.class);
 
+    private static final String UNAUTHENTICATED = "unauthenticated";
+
     public interface Executable<T> {
 
         T exec();
@@ -48,7 +50,7 @@ public final class AuthContextUtils {
 
     public static String getUsername() {
         Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-        return authentication == null ? SyncopeConstants.UNAUTHENTICATED : authentication.getName();
+        return authentication == null ? UNAUTHENTICATED : authentication.getName();
     }
 
     public static void updateUsername(final String newUsername) {
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
index a59555e..72d81f8 100644
--- a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
@@ -91,6 +91,8 @@ import org.springframework.transaction.annotation.Transactional;
  */
 public class AuthDataAccessor {
 
+    public static final String GROUP_OWNER_ROLE = "GROUP_OWNER";
+
     protected static final Logger LOG = LoggerFactory.getLogger(AuthDataAccessor.class);
 
     protected static final Encryptor ENCRYPTOR = Encryptor.getInstance();
@@ -358,7 +360,7 @@ public class AuthDataAccessor {
         // Give entitlements as assigned by roles (with static or dynamic realms, where applicable) - assigned
         // either statically and dynamically
         userDAO.findAllRoles(user).stream().
-                filter(role -> !SyncopeConstants.GROUP_OWNER_ROLE.equals(role.getKey())).
+                filter(role -> !GROUP_OWNER_ROLE.equals(role.getKey())).
                 forEach(role -> role.getEntitlements().forEach(entitlement -> {
             Set<String> realms = Optional.ofNullable(entForRealms.get(entitlement)).orElseGet(() -> {
                 HashSet<String> r = new HashSet<>();
@@ -374,9 +376,9 @@ public class AuthDataAccessor {
 
         // Give group entitlements for owned groups
         groupDAO.findOwnedByUser(user.getKey()).forEach(group -> {
-            Role groupOwnerRole = roleDAO.find(SyncopeConstants.GROUP_OWNER_ROLE);
+            Role groupOwnerRole = roleDAO.find(GROUP_OWNER_ROLE);
             if (groupOwnerRole == null) {
-                LOG.warn("Role {} was not found", SyncopeConstants.GROUP_OWNER_ROLE);
+                LOG.warn("Role {} was not found", GROUP_OWNER_ROLE);
             } else {
                 groupOwnerRole.getEntitlements().forEach(entitlement -> {
                     Set<String> realms = Optional.ofNullable(entForRealms.get(entitlement)).orElseGet(() -> {
@@ -396,7 +398,7 @@ public class AuthDataAccessor {
     protected Set<SyncopeGrantedAuthority> getDelegatedAuthorities(final Delegation delegation) {
         Map<String, Set<String>> entForRealms = new HashMap<>();
 
-        delegation.getRoles().stream().filter(role -> !SyncopeConstants.GROUP_OWNER_ROLE.equals(role.getKey())).
+        delegation.getRoles().stream().filter(role -> !GROUP_OWNER_ROLE.equals(role.getKey())).
                 forEach(role -> role.getEntitlements().forEach(entitlement -> {
             Set<String> realms = Optional.ofNullable(entForRealms.get(entitlement)).orElseGet(() -> {
                 HashSet<String> r = new HashSet<>();