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 2017/10/27 15:21:41 UTC

[2/2] syncope git commit: [SYNCOPE-152] Initial implementation as extension: user / group read and search (without filters, attributes or sort)

[SYNCOPE-152] Initial implementation as extension: user / group read and search (without filters, attributes or sort)


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/aa25af97
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/aa25af97
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/aa25af97

Branch: refs/heads/2_0_X
Commit: aa25af970cacaf6675f78d4dc65d4c02a5b9bd5b
Parents: 59ad56b
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Oct 27 17:02:25 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Oct 27 17:02:25 2017 +0200

----------------------------------------------------------------------
 .../apache/syncope/common/lib/to/UserTO.java    |  10 +
 ext/pom.xml                                     |   1 +
 ext/scimv2/pom.xml                              |  45 ++++
 ext/scimv2/scim-rest-api/pom.xml                |  70 ++++++
 .../syncope/ext/scimv2/api/SCIMConstants.java   |  32 +++
 .../syncope/ext/scimv2/api/data/Display.java    |  46 ++++
 .../syncope/ext/scimv2/api/data/Group.java      |  51 ++++
 .../ext/scimv2/api/data/ListResponse.java       |  74 ++++++
 .../syncope/ext/scimv2/api/data/Member.java     |  49 ++++
 .../syncope/ext/scimv2/api/data/Meta.java       |  80 +++++++
 .../syncope/ext/scimv2/api/data/Reference.java  |  39 +++
 .../syncope/ext/scimv2/api/data/SCIMBean.java   |  29 +++
 .../syncope/ext/scimv2/api/data/SCIMGroup.java  |  55 +++++
 .../ext/scimv2/api/data/SCIMResource.java       |  62 +++++
 .../syncope/ext/scimv2/api/data/SCIMUser.java   |  69 ++++++
 .../ext/scimv2/api/service/GroupService.java    |  64 +++++
 .../ext/scimv2/api/service/RootService.java     |  45 ++++
 .../ext/scimv2/api/service/SCIMService.java     |  41 ++++
 .../ext/scimv2/api/service/UserService.java     |  64 +++++
 .../syncope/ext/scimv2/api/type/Function.java   |  25 ++
 .../ext/scimv2/api/type/ResourceType.java       |  37 +++
 .../syncope/ext/scimv2/api/type/SortOrder.java  |  25 ++
 ext/scimv2/scim-rest-cxf/pom.xml                | 127 ++++++++++
 .../ext/scimv2/cxf/JacksonSCIMJsonProvider.java |  51 ++++
 .../scimv2/cxf/service/AbstractSCIMService.java | 235 +++++++++++++++++++
 .../scimv2/cxf/service/GroupServiceImpl.java    |  71 ++++++
 .../ext/scimv2/cxf/service/RootServiceImpl.java |  41 ++++
 .../ext/scimv2/cxf/service/UserServiceImpl.java |  70 ++++++
 .../META-INF/cxf/org.apache.cxf.Logger          |   1 +
 .../main/resources/META-INF/web-fragment.xml    |  70 ++++++
 .../src/main/resources/restSCIMv2CXFContext.xml |  83 +++++++
 fit/core-reference/pom.xml                      |   6 +
 .../src/main/webapp/WEB-INF/web.xml             |   2 +-
 .../org/apache/syncope/fit/SCIMDetector.java    |  55 +++++
 .../apache/syncope/fit/core/SAML2ITCase.java    |   9 +-
 .../org/apache/syncope/fit/core/SCIMITCase.java |  96 ++++++++
 fit/core-reference/src/test/resources/rebel.xml |   4 +
 37 files changed, 1928 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
index 061f06e..5efe6a5 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
@@ -61,6 +61,8 @@ public class UserTO extends AnyTO implements GroupableRelatableTO {
 
     private String securityAnswer;
 
+    private boolean suspended;
+
     private boolean mustChangePassword;
 
     private final List<RelationshipTO> relationships = new ArrayList<>();
@@ -186,6 +188,14 @@ public class UserTO extends AnyTO implements GroupableRelatableTO {
         this.securityAnswer = securityAnswer;
     }
 
+    public boolean isSuspended() {
+        return suspended;
+    }
+
+    public void setSuspended(final boolean suspended) {
+        this.suspended = suspended;
+    }
+
     public boolean isMustChangePassword() {
         return mustChangePassword;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/pom.xml
----------------------------------------------------------------------
diff --git a/ext/pom.xml b/ext/pom.xml
index 031757a..be5e3ce 100644
--- a/ext/pom.xml
+++ b/ext/pom.xml
@@ -92,6 +92,7 @@ under the License.
     <module>camel</module>
     <module>swagger-ui</module>
     <module>saml2sp</module>
+    <module>scimv2</module>
   </modules>
 
 </project>

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/pom.xml
----------------------------------------------------------------------
diff --git a/ext/scimv2/pom.xml b/ext/scimv2/pom.xml
new file mode 100644
index 0000000..ac554e3
--- /dev/null
+++ b/ext/scimv2/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.syncope</groupId>
+    <artifactId>syncope-ext</artifactId>
+    <version>2.0.7-SNAPSHOT</version>
+  </parent>
+
+  <name>Apache Syncope Ext: SCIMv2</name>
+  <description>Apache Syncope Ext: SCIMv2</description>
+  <groupId>org.apache.syncope.ext</groupId>
+  <artifactId>syncope-ext-scimv2</artifactId>
+  <packaging>pom</packaging>
+  
+  <properties>
+    <rootpom.basedir>${basedir}/../..</rootpom.basedir>
+  </properties>
+  
+  <modules>
+    <module>scim-rest-api</module>
+    <module>scim-rest-cxf</module>
+  </modules>
+
+</project>

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/pom.xml
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/pom.xml b/ext/scimv2/scim-rest-api/pom.xml
new file mode 100644
index 0000000..0d0d1ae
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.syncope.ext</groupId>
+    <artifactId>syncope-ext-scimv2</artifactId>
+    <version>2.0.7-SNAPSHOT</version>
+  </parent>
+
+  <name>Apache Syncope Ext: SCIMv2 SCIM REST API</name>
+  <description>Apache Syncope Ext: SCIMv2 SCIM REST API</description>
+  <groupId>org.apache.syncope.ext.scimv2</groupId>
+  <artifactId>syncope-ext-scimv2-scim-rest-api</artifactId>
+  <packaging>jar</packaging>
+  
+  <properties>
+    <rootpom.basedir>${basedir}/../../..</rootpom.basedir>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>javax.validation</groupId>
+      <artifactId>validation-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>javax.ws.rs</groupId>
+      <artifactId>javax.ws.rs-api</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-annotations</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+    </dependency>
+  </dependencies>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/SCIMConstants.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/SCIMConstants.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/SCIMConstants.java
new file mode 100644
index 0000000..979decd
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/SCIMConstants.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api;
+
+import javax.ws.rs.core.MediaType;
+
+public final class SCIMConstants {
+
+    public static final String APPLICATION_SCIM_JSON = "application/scim+json";
+
+    public static final MediaType APPLICATION_SCIM_JSON_TYPE = new MediaType("application", "scim+json");
+
+    private SCIMConstants() {
+        // private constructor for static utility class
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Display.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Display.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Display.java
new file mode 100644
index 0000000..f79796c
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Display.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class Display extends SCIMBean {
+
+    private static final long serialVersionUID = 5337055958765320091L;
+
+    private final String value;
+
+    private final String display;
+
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public Display(@JsonProperty("value") final String value, @JsonProperty("display") final String display) {
+        this.value = value;
+        this.display = display;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public String getDisplay() {
+        return display;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Group.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Group.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Group.java
new file mode 100644
index 0000000..f64b837
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Group.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.syncope.ext.scimv2.api.type.Function;
+
+@JsonPropertyOrder({ "value", "$ref", "display", "type" })
+public class Group extends Reference {
+
+    private static final long serialVersionUID = -7184515273837918246L;
+
+    @JsonIgnore
+    private final Function type;
+
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public Group(
+            @JsonProperty("value") final String value,
+            @JsonProperty("$ref") final String ref,
+            @JsonProperty("display") final String display,
+            @JsonProperty("type") final Function type) {
+
+        super(value, ref, display);
+        this.type = type;
+    }
+
+    @JsonProperty
+    public String getType() {
+        return type == null ? null : type.name();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java
new file mode 100644
index 0000000..6983631
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.apache.syncope.ext.scimv2.api.type.ResourceType;
+
+public class ListResponse<R extends SCIMResource> extends SCIMBean {
+
+    private static final long serialVersionUID = -776611610457583160L;
+
+    private final List<String> schemas = Arrays.asList(ResourceType.ListResponse.getSchema());
+
+    private final int totalResults;
+
+    @JsonProperty("Resources")
+    private final List<R> resources = new ArrayList<>();
+
+    private final int startIndex;
+
+    private final int itemsPerPage;
+
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public ListResponse(
+            @JsonProperty("totalResults") final int totalResults,
+            @JsonProperty("startIndex") final int startIndex,
+            @JsonProperty("itemsPerPage") final int itemsPerPage) {
+
+        this.totalResults = totalResults;
+        this.startIndex = startIndex;
+        this.itemsPerPage = itemsPerPage;
+    }
+
+    public List<String> getSchemas() {
+        return schemas;
+    }
+
+    public int getTotalResults() {
+        return totalResults;
+    }
+
+    public List<R> getResources() {
+        return resources;
+    }
+
+    public int getStartIndex() {
+        return startIndex;
+    }
+
+    public int getItemsPerPage() {
+        return itemsPerPage;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java
new file mode 100644
index 0000000..73c25eb
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.syncope.ext.scimv2.api.type.ResourceType;
+
+@JsonPropertyOrder({ "value", "$ref", "display", "type" })
+public class Member extends Reference {
+
+    private static final long serialVersionUID = 75245960461062907L;
+
+    @JsonIgnore
+    private final ResourceType type;
+
+    public Member(
+            @JsonProperty("value") final String value,
+            @JsonProperty("$ref") final String ref,
+            @JsonProperty("display") final String display,
+            @JsonProperty("type") final ResourceType type) {
+
+        super(value, ref, display);
+        this.type = type;
+    }
+
+    @JsonProperty
+    public String getType() {
+        return type == null ? null : type.name();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java
new file mode 100644
index 0000000..7ecb4af
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.Date;
+import javax.ws.rs.core.EntityTag;
+import org.apache.syncope.ext.scimv2.api.type.ResourceType;
+
+public class Meta implements Serializable {
+
+    private static final long serialVersionUID = 8976451652101091915L;
+
+    private final ResourceType resourceType;
+
+    private final Date created;
+
+    private final Date lastModified;
+
+    @JsonIgnore
+    private final EntityTag version;
+
+    private final String location;
+
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public Meta(
+            @JsonProperty("resourceType") final ResourceType resourceType,
+            @JsonProperty("created") final Date created,
+            @JsonProperty("lastModified") final Date lastModified,
+            @JsonProperty("version") final String version,
+            @JsonProperty("location") final String location) {
+
+        this.resourceType = resourceType;
+        this.created = created;
+        this.lastModified = lastModified;
+        this.version = new EntityTag(version);
+        this.location = location;
+    }
+
+    public ResourceType getResourceType() {
+        return resourceType;
+    }
+
+    public Date getCreated() {
+        return created;
+    }
+
+    public Date getLastModified() {
+        return lastModified;
+    }
+
+    @JsonProperty
+    public String getVersion() {
+        return version == null ? null : version.toString();
+    }
+
+    public String getLocation() {
+        return location;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Reference.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Reference.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Reference.java
new file mode 100644
index 0000000..d65f5e8
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Reference.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+abstract class Reference extends Display {
+
+    private static final long serialVersionUID = -6190164044699376089L;
+
+    @JsonProperty("$ref")
+    private final String ref;
+
+    Reference(final String value, final String display, final String ref) {
+        super(value, display);
+        this.ref = ref;
+    }
+
+    public String getRef() {
+        return ref;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMBean.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMBean.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMBean.java
new file mode 100644
index 0000000..95334cf
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMBean.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java.io.Serializable;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+abstract class SCIMBean implements Serializable {
+
+    private static final long serialVersionUID = 7604407251038024743L;
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMGroup.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMGroup.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMGroup.java
new file mode 100644
index 0000000..0657476
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMGroup.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import java.util.ArrayList;
+import java.util.List;
+
+@JsonPropertyOrder({ "schemas", "id", "externalId", "displayName", "members", "meta" })
+public class SCIMGroup extends SCIMResource {
+
+    private static final long serialVersionUID = -2935466041674390279L;
+
+    private final String displayName;
+
+    private final List<Member> members = new ArrayList<>();
+
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public SCIMGroup(
+            @JsonProperty("id") final String id,
+            @JsonProperty("schemas") final List<String> schemas,
+            @JsonProperty("meta") final Meta meta,
+            @JsonProperty("displayName") final String displayName) {
+
+        super(id, schemas, meta);
+        this.displayName = displayName;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public List<Member> getMembers() {
+        return members;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMResource.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMResource.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMResource.java
new file mode 100644
index 0000000..fae74e1
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMResource.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.data;
+
+import java.util.Collections;
+import java.util.List;
+
+public abstract class SCIMResource extends SCIMBean {
+
+    private static final long serialVersionUID = -8465880682458920021L;
+
+    private final String id;
+
+    private String externalId;
+
+    private final List<String> schemas;
+
+    private final Meta meta;
+
+    public SCIMResource(final String id, final List<String> schemas, final Meta meta) {
+        this.id = id;
+        this.schemas = schemas == null ? Collections.<String>emptyList() : schemas;
+        this.meta = meta;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public List<String> getSchemas() {
+        return schemas;
+    }
+
+    public Meta getMeta() {
+        return meta;
+    }
+
+    public void setExternalId(final String externalId) {
+        this.externalId = externalId;
+    }
+
+    public String getExternalId() {
+        return externalId;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMUser.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMUser.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMUser.java
new file mode 100644
index 0000000..c76c0f0
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMUser.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import java.util.ArrayList;
+import java.util.List;
+
+@JsonPropertyOrder({ "schemas", "id", "externalId", "userName", "active", "groups", "roles", "meta" })
+public class SCIMUser extends SCIMResource {
+
+    private static final long serialVersionUID = -2935466041674390279L;
+
+    private final String userName;
+
+    private final boolean active;
+
+    private final List<Group> groups = new ArrayList<>();
+
+    private final List<Display> roles = new ArrayList<>();
+
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public SCIMUser(
+            @JsonProperty("id") final String id,
+            @JsonProperty("schemas") final List<String> schemas,
+            @JsonProperty("meta") final Meta meta,
+            @JsonProperty("userName") final String userName,
+            @JsonProperty("active") final boolean active) {
+
+        super(id, schemas, meta);
+        this.userName = userName;
+        this.active = active;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public boolean isActive() {
+        return active;
+    }
+
+    public List<Group> getGroups() {
+        return groups;
+    }
+
+    public List<Display> getRoles() {
+        return roles;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java
new file mode 100644
index 0000000..c1bb82f
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.service;
+
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+import org.apache.cxf.jaxrs.ext.PATCH;
+import org.apache.syncope.ext.scimv2.api.SCIMConstants;
+import org.apache.syncope.ext.scimv2.api.data.SCIMGroup;
+
+@Path("Groups")
+public interface GroupService extends SCIMService<SCIMGroup> {
+
+    @POST
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    @Consumes({ SCIMConstants.APPLICATION_SCIM_JSON })
+    Response create();
+
+    @GET
+    @Path("{id}")
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    SCIMGroup read(@NotNull @PathParam("id") String id);
+
+    @PUT
+    @Path("{id}")
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    @Consumes({ SCIMConstants.APPLICATION_SCIM_JSON })
+    Response replace(@NotNull @PathParam("id") String id);
+
+    @DELETE
+    @Path("{id}")
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    Response delete(@NotNull @PathParam("id") String id);
+
+    @PATCH
+    @Path("{id}")
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    @Consumes({ SCIMConstants.APPLICATION_SCIM_JSON })
+    Response update(@NotNull @PathParam("id") String id);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java
new file mode 100644
index 0000000..8de7a0a
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.service;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.ext.scimv2.api.SCIMConstants;
+
+@Path("")
+public interface RootService extends SCIMService {
+
+    @GET
+    @Path("ServiceProviderConfigs")
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    Response serviceProviderConfigs();
+
+    @GET
+    @Path("ResourceTypes")
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    Response resourceTypes();
+
+    @GET
+    @Path("Schemas")
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    Response schemas();
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SCIMService.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SCIMService.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SCIMService.java
new file mode 100644
index 0000000..1b2fd3f
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SCIMService.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.service;
+
+import java.util.List;
+import javax.ws.rs.GET;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.syncope.ext.scimv2.api.SCIMConstants;
+import org.apache.syncope.ext.scimv2.api.data.ListResponse;
+import org.apache.syncope.ext.scimv2.api.data.SCIMResource;
+import org.apache.syncope.ext.scimv2.api.type.SortOrder;
+
+public interface SCIMService<R extends SCIMResource> {
+
+    @GET
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    ListResponse<R> search(
+            @QueryParam("startIndex") Integer startIndex,
+            @QueryParam("count") Integer count,
+            @QueryParam("filter") String filter,
+            @QueryParam("sortBy") String sortBy,
+            @QueryParam("sortOrder") SortOrder sortOrder,
+            @QueryParam("attributes") List<String> attributes);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java
new file mode 100644
index 0000000..73518b5
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.service;
+
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+import org.apache.cxf.jaxrs.ext.PATCH;
+import org.apache.syncope.ext.scimv2.api.SCIMConstants;
+import org.apache.syncope.ext.scimv2.api.data.SCIMUser;
+
+@Path("Users")
+public interface UserService extends SCIMService<SCIMUser> {
+
+    @POST
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    @Consumes({ SCIMConstants.APPLICATION_SCIM_JSON })
+    Response create();
+
+    @GET
+    @Path("{id}")
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    SCIMUser read(@NotNull @PathParam("id") String id);
+
+    @PUT
+    @Path("{id}")
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    @Consumes({ SCIMConstants.APPLICATION_SCIM_JSON })
+    Response replace(@NotNull @PathParam("id") String id);
+
+    @DELETE
+    @Path("{id}")
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    Response delete(@NotNull @PathParam("id") String id);
+
+    @PATCH
+    @Path("{id}")
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    @Consumes({ SCIMConstants.APPLICATION_SCIM_JSON })
+    Response update(@NotNull @PathParam("id") String id);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Function.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Function.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Function.java
new file mode 100644
index 0000000..49d4eef
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Function.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.type;
+
+public enum Function {
+    direct,
+    indirect;
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/ResourceType.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/ResourceType.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/ResourceType.java
new file mode 100644
index 0000000..faf5ccc
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/ResourceType.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.type;
+
+public enum ResourceType {
+
+    User("urn:ietf:params:scim:schemas:core:2.0:User"),
+    Group("urn:ietf:params:scim:schemas:core:2.0:Group"),
+    ListResponse("urn:ietf:params:scim:api:messages:2.0:ListResponse");
+
+    private final String schema;
+
+    ResourceType(final String schema) {
+        this.schema = schema;
+    }
+
+    public String getSchema() {
+        return schema;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/SortOrder.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/SortOrder.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/SortOrder.java
new file mode 100644
index 0000000..6c7bf16
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/SortOrder.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.api.type;
+
+public enum SortOrder {
+    ascending,
+    descending;
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/pom.xml
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/pom.xml b/ext/scimv2/scim-rest-cxf/pom.xml
new file mode 100644
index 0000000..3db0ae6
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/pom.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.syncope.ext</groupId>
+    <artifactId>syncope-ext-scimv2</artifactId>
+    <version>2.0.7-SNAPSHOT</version>
+  </parent>
+
+  <name>Apache Syncope Ext: SCIMv2 SCIM REST CXF</name>
+  <description>Apache Syncope Ext: SCIMv2 SCIM REST CXF</description>
+  <groupId>org.apache.syncope.ext.scimv2</groupId>
+  <artifactId>syncope-ext-scimv2-scim-rest-cxf</artifactId>
+  <packaging>jar</packaging>
+  
+  <properties>
+    <rootpom.basedir>${basedir}/../../..</rootpom.basedir>
+  </properties>
+
+  <dependencies>
+    <dependency> 
+      <groupId>javax.servlet</groupId> 
+      <artifactId>javax.servlet-api</artifactId> 
+      <scope>provided</scope>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-context</artifactId>
+    </dependency>    
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-web</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.security</groupId>
+      <artifactId>spring-security-web</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.security</groupId>
+      <artifactId>spring-security-config</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>com.fasterxml.jackson.datatype</groupId>
+      <artifactId>jackson-datatype-joda</artifactId>
+    </dependency>    
+    <dependency>
+      <groupId>com.fasterxml.jackson.jaxrs</groupId>
+      <artifactId>jackson-jaxrs-json-provider</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.module</groupId>
+      <artifactId>jackson-module-afterburner</artifactId>
+    </dependency>
+      
+    <dependency>
+      <groupId>joda-time</groupId>
+      <artifactId>joda-time</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-rs-service-description</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-rs-client</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.syncope.core</groupId>
+      <artifactId>syncope-core-logic</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.syncope.ext.scimv2</groupId>
+      <artifactId>syncope-ext-scimv2-scim-rest-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>            
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+      </plugin>
+    </plugins>
+    
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>true</filtering>
+      </resource>
+    </resources>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/JacksonSCIMJsonProvider.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/JacksonSCIMJsonProvider.java b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/JacksonSCIMJsonProvider.java
new file mode 100644
index 0000000..28ca173
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/JacksonSCIMJsonProvider.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.cxf;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
+import java.text.SimpleDateFormat;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.ext.Provider;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.ext.scimv2.api.SCIMConstants;
+
+@Provider
+@Consumes(SCIMConstants.APPLICATION_SCIM_JSON)
+@Produces(SCIMConstants.APPLICATION_SCIM_JSON)
+public class JacksonSCIMJsonProvider extends JacksonJsonProvider {
+
+    private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() {
+
+        @Override
+        protected SimpleDateFormat initialValue() {
+            SimpleDateFormat sdf = new SimpleDateFormat();
+            sdf.applyPattern(SyncopeConstants.DEFAULT_DATE_PATTERN);
+            return sdf;
+        }
+    };
+
+    public JacksonSCIMJsonProvider() {
+        super(new ObjectMapper(), BASIC_ANNOTATIONS);
+        _mapperConfig.getConfiguredMapper().disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+        _mapperConfig.getConfiguredMapper().setDateFormat(DATE_FORMAT.get());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractSCIMService.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractSCIMService.java b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractSCIMService.java
new file mode 100644
index 0000000..cee06eb
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractSCIMService.java
@@ -0,0 +1,235 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.cxf.service;
+
+import java.util.Collections;
+import java.util.List;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriInfo;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.core.logic.AbstractAnyLogic;
+import org.apache.syncope.core.logic.GroupLogic;
+import org.apache.syncope.core.logic.UserLogic;
+import org.apache.syncope.core.persistence.api.dao.AnyDAO;
+import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.ext.scimv2.api.data.Display;
+import org.apache.syncope.ext.scimv2.api.data.Group;
+import org.apache.syncope.ext.scimv2.api.data.ListResponse;
+import org.apache.syncope.ext.scimv2.api.data.Member;
+import org.apache.syncope.ext.scimv2.api.data.Meta;
+import org.apache.syncope.ext.scimv2.api.data.SCIMGroup;
+import org.apache.syncope.ext.scimv2.api.data.SCIMResource;
+import org.apache.syncope.ext.scimv2.api.data.SCIMUser;
+import org.apache.syncope.ext.scimv2.api.service.SCIMService;
+import org.apache.syncope.ext.scimv2.api.type.Function;
+import org.apache.syncope.ext.scimv2.api.type.ResourceType;
+import org.apache.syncope.ext.scimv2.api.type.SortOrder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+abstract class AbstractSCIMService<R extends SCIMResource> implements SCIMService<R> {
+
+    protected static final Logger LOG = LoggerFactory.getLogger(AbstractSCIMService.class);
+
+    @Context
+    protected UriInfo uriInfo;
+
+    @Context
+    protected MessageContext messageContext;
+
+    private UserLogic userLogic;
+
+    private GroupLogic groupLogic;
+
+    protected UserLogic userLogic() {
+        synchronized (this) {
+            if (userLogic == null) {
+                userLogic = ApplicationContextProvider.getApplicationContext().getBean(UserLogic.class);
+            }
+        }
+        return userLogic;
+    }
+
+    protected GroupLogic groupLogic() {
+        synchronized (this) {
+            if (groupLogic == null) {
+                groupLogic = ApplicationContextProvider.getApplicationContext().getBean(GroupLogic.class);
+            }
+        }
+        return groupLogic;
+    }
+
+    protected AbstractAnyLogic<?, ?> anyLogic(final ResourceType type) {
+        switch (type) {
+            case User:
+                return userLogic();
+
+            case Group:
+                return groupLogic();
+
+            default:
+                throw new UnsupportedOperationException();
+        }
+    }
+
+    protected SCIMUser toSCIMUser(final UserTO userTO, final String location) {
+        SCIMUser user = new SCIMUser(
+                userTO.getKey(),
+                Collections.singletonList(ResourceType.User.getSchema()),
+                new Meta(
+                        ResourceType.User,
+                        userTO.getCreationDate(),
+                        userTO.getLastChangeDate(),
+                        userTO.getETagValue(),
+                        location),
+                userTO.getUsername(),
+                !userTO.isSuspended());
+
+        for (MembershipTO membership : userTO.getMemberships()) {
+            user.getGroups().add(new Group(
+                    membership.getGroupKey(),
+                    StringUtils.substringBefore(location, "/Users") + "/Groups/" + membership.getGroupKey(),
+                    membership.getGroupName(),
+                    Function.direct));
+        }
+        for (MembershipTO membership : userTO.getDynMemberships()) {
+            user.getGroups().add(new Group(
+                    membership.getGroupKey(),
+                    StringUtils.substringBefore(location, "/Users") + "/Groups/" + membership.getGroupKey(),
+                    membership.getGroupName(),
+                    Function.indirect));
+        }
+
+        for (String role : userTO.getRoles()) {
+            user.getRoles().add(new Display(role, null));
+        }
+
+        return user;
+    }
+
+    protected SCIMGroup toSCIMGroup(final GroupTO groupTO, final String location) {
+        SCIMGroup group = new SCIMGroup(
+                groupTO.getKey(),
+                Collections.singletonList(ResourceType.Group.getSchema()),
+                new Meta(
+                        ResourceType.Group,
+                        groupTO.getCreationDate(),
+                        groupTO.getLastChangeDate(),
+                        groupTO.getETagValue(),
+                        location),
+                groupTO.getName());
+
+        MembershipCond membCond = new MembershipCond();
+        membCond.setGroup(groupTO.getKey());
+        SearchCond searchCond = SearchCond.getLeafCond(membCond);
+
+        int count = userLogic().
+                search(searchCond, 1, 1, Collections.<OrderByClause>emptyList(), SyncopeConstants.ROOT_REALM, false).
+                getLeft();
+
+        for (int page = 1; page <= (count / AnyDAO.DEFAULT_PAGE_SIZE) + 1; page++) {
+            List<UserTO> users = userLogic().search(
+                    searchCond,
+                    page,
+                    AnyDAO.DEFAULT_PAGE_SIZE,
+                    Collections.<OrderByClause>emptyList(),
+                    SyncopeConstants.ROOT_REALM,
+                    false).
+                    getRight();
+            for (UserTO userTO : users) {
+                group.getMembers().add(new Member(
+                        userTO.getKey(),
+                        StringUtils.substringBefore(location, "/Groups") + "/Users/" + userTO.getKey(),
+                        userTO.getUsername(),
+                        ResourceType.User));
+            }
+        }
+
+        return group;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected ListResponse<R> doSearch(
+            final ResourceType type,
+            final Integer startIndex,
+            final Integer count,
+            final String filter,
+            final String sortBy,
+            final SortOrder sortOrder,
+            final List<String> attributes) {
+
+        if (type == null) {
+            throw new UnsupportedOperationException();
+        }
+
+        int page = startIndex == null || startIndex <= 1 ? 1 : (startIndex / AnyDAO.DEFAULT_PAGE_SIZE) + 1;
+
+        Pair<Integer, ? extends List<? extends AnyTO>> result = anyLogic(type).search(
+                null,
+                page,
+                AnyDAO.DEFAULT_PAGE_SIZE,
+                Collections.<OrderByClause>emptyList(),
+                SyncopeConstants.ROOT_REALM,
+                false);
+
+        ListResponse<R> response = new ListResponse<>(
+                result.getLeft(), startIndex == null || startIndex <= 1 ? 1 : startIndex, AnyDAO.DEFAULT_PAGE_SIZE);
+
+        for (AnyTO anyTO : result.getRight()) {
+            SCIMResource resource = null;
+            if (anyTO instanceof UserTO) {
+                resource = toSCIMUser(
+                        (UserTO) anyTO,
+                        uriInfo.getAbsolutePathBuilder().path(anyTO.getKey()).build().toASCIIString());
+            } else if (anyTO instanceof GroupTO) {
+                resource = toSCIMGroup(
+                        (GroupTO) anyTO,
+                        uriInfo.getAbsolutePathBuilder().path(anyTO.getKey()).build().toASCIIString());
+            }
+
+            if (resource != null) {
+                response.getResources().add((R) resource);
+            }
+        }
+
+        return response;
+    }
+
+    @Override
+    public ListResponse<R> search(
+            final Integer startIndex,
+            final Integer count,
+            final String filter,
+            final String sortBy,
+            final SortOrder sortOrder,
+            final List<String> attributes) {
+
+        return doSearch(null, startIndex, count, filter, sortBy, sortOrder, attributes);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/GroupServiceImpl.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/GroupServiceImpl.java b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/GroupServiceImpl.java
new file mode 100644
index 0000000..151762a
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/GroupServiceImpl.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.cxf.service;
+
+import java.util.List;
+import java.util.UUID;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.ext.scimv2.api.data.ListResponse;
+import org.apache.syncope.ext.scimv2.api.data.SCIMGroup;
+import org.apache.syncope.ext.scimv2.api.service.GroupService;
+import org.apache.syncope.ext.scimv2.api.type.ResourceType;
+import org.apache.syncope.ext.scimv2.api.type.SortOrder;
+
+public class GroupServiceImpl extends AbstractSCIMService<SCIMGroup> implements GroupService {
+
+    @Override
+    public Response create() {
+        return Response.
+                created(uriInfo.getAbsolutePathBuilder().path(UUID.randomUUID().toString()).build()).
+                build();
+    }
+
+    @Override
+    public SCIMGroup read(final String id) {
+        return toSCIMGroup(groupLogic().read(id), uriInfo.getAbsolutePathBuilder().build().toASCIIString());
+    }
+
+    @Override
+    public Response replace(final String id) {
+        return Response.ok().build();
+    }
+
+    @Override
+    public Response delete(final String id) {
+        return Response.noContent().build();
+    }
+
+    @Override
+    public Response update(final String id) {
+        return Response.ok().build();
+    }
+
+    @Override
+    public ListResponse<SCIMGroup> search(
+            final Integer startIndex,
+            final Integer count,
+            final String filter,
+            final String sortBy,
+            final SortOrder sortOrder,
+            final List<String> attributes) {
+
+        return doSearch(ResourceType.Group, startIndex, count, filter, sortBy, sortOrder, attributes);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/RootServiceImpl.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/RootServiceImpl.java b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/RootServiceImpl.java
new file mode 100644
index 0000000..0172e7d
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/RootServiceImpl.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.cxf.service;
+
+import javax.ws.rs.core.Response;
+import org.apache.syncope.ext.scimv2.api.service.RootService;
+
+public class RootServiceImpl extends AbstractSCIMService implements RootService {
+
+    @Override
+    public Response serviceProviderConfigs() {
+        return Response.ok().build();
+    }
+
+    @Override
+    public Response resourceTypes() {
+        return Response.ok().build();
+    }
+
+    @Override
+    public Response schemas() {
+        return Response.ok().build();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/UserServiceImpl.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/UserServiceImpl.java b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/UserServiceImpl.java
new file mode 100644
index 0000000..6d51ca3
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/UserServiceImpl.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.ext.scimv2.cxf.service;
+
+import java.util.List;
+import java.util.UUID;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.ext.scimv2.api.data.ListResponse;
+import org.apache.syncope.ext.scimv2.api.data.SCIMUser;
+import org.apache.syncope.ext.scimv2.api.service.UserService;
+import org.apache.syncope.ext.scimv2.api.type.ResourceType;
+import org.apache.syncope.ext.scimv2.api.type.SortOrder;
+
+public class UserServiceImpl extends AbstractSCIMService<SCIMUser> implements UserService {
+
+    @Override
+    public Response create() {
+        return Response.
+                created(uriInfo.getAbsolutePathBuilder().path(UUID.randomUUID().toString()).build()).
+                build();
+    }
+
+    @Override
+    public SCIMUser read(final String id) {
+        return toSCIMUser(userLogic().read(id), uriInfo.getAbsolutePathBuilder().build().toASCIIString());
+    }
+
+    @Override
+    public Response replace(final String id) {
+        return Response.ok().build();
+    }
+
+    @Override
+    public Response delete(final String id) {
+        return Response.noContent().build();
+    }
+
+    @Override
+    public Response update(final String id) {
+        return Response.ok().build();
+    }
+
+    @Override
+    public ListResponse<SCIMUser> search(
+            final Integer startIndex,
+            final Integer count,
+            final String filter,
+            final String sortBy,
+            final SortOrder sortOrder,
+            final List<String> attributes) {
+
+        return doSearch(ResourceType.User, startIndex, count, filter, sortBy, sortOrder, attributes);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/src/main/resources/META-INF/cxf/org.apache.cxf.Logger
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/resources/META-INF/cxf/org.apache.cxf.Logger b/ext/scimv2/scim-rest-cxf/src/main/resources/META-INF/cxf/org.apache.cxf.Logger
new file mode 100644
index 0000000..6e7bd36
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/src/main/resources/META-INF/cxf/org.apache.cxf.Logger
@@ -0,0 +1 @@
+org.apache.cxf.common.logging.Slf4jLogger

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/src/main/resources/META-INF/web-fragment.xml
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/resources/META-INF/web-fragment.xml b/ext/scimv2/scim-rest-cxf/src/main/resources/META-INF/web-fragment.xml
new file mode 100644
index 0000000..5a021ae
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/src/main/resources/META-INF/web-fragment.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+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.
+-->
+<web-fragment xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
+                                  http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"
+              id="${pom.artifactId}" version="3.1">
+  
+  <listener>
+    <listener-class>org.apache.syncope.core.rest.cxf.ThreadLocalCleanupListener</listener-class>
+  </listener>
+  
+  <servlet>
+    <servlet-name>SCIMv2CXFServlet</servlet-name>
+    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
+    <init-param>
+      <param-name>config-location</param-name>
+      <param-value>classpath*:/restSCIMv2CXFContext.xml</param-value>
+    </init-param>
+    <load-on-startup>1</load-on-startup> 
+  </servlet>
+  <servlet-mapping>
+    <servlet-name>SCIMv2CXFServlet</servlet-name>
+    <url-pattern>/scim/*</url-pattern>
+  </servlet-mapping>
+
+  <filter>
+    <filter-name>encodingFilter</filter-name>
+    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
+    <init-param>
+      <param-name>encoding</param-name>
+      <param-value>UTF-8</param-value>
+    </init-param>
+    <init-param>
+      <param-name>forceEncoding</param-name>
+      <param-value>true</param-value>
+    </init-param>
+  </filter>
+  <filter>
+    <filter-name>springSecurityFilterChain</filter-name>
+    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
+  </filter>
+
+  <filter-mapping>
+    <filter-name>encodingFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping>
+  <filter-mapping>
+    <filter-name>springSecurityFilterChain</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping>
+
+</web-fragment>

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/src/main/resources/restSCIMv2CXFContext.xml
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/resources/restSCIMv2CXFContext.xml b/ext/scimv2/scim-rest-cxf/src/main/resources/restSCIMv2CXFContext.xml
new file mode 100644
index 0000000..7293b26
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/src/main/resources/restSCIMv2CXFContext.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                           http://www.springframework.org/schema/beans/spring-beans.xsd
+                           http://cxf.apache.org/jaxrs
+                           http://cxf.apache.org/schemas/jaxrs.xsd
+                           http://www.springframework.org/schema/context
+                           http://www.springframework.org/schema/context/spring-context.xsd">
+
+  <import resource="classpath:META-INF/cxf/cxf.xml"/>
+  <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
+
+  <context:component-scan base-package="org.apache.syncope.ext.scimv2.cxf.service"/>  
+  
+  <bean id="jsonProvider" class="org.apache.syncope.ext.scimv2.cxf.JacksonSCIMJsonProvider"/>
+
+  <bean id="validationProvider" class="org.apache.cxf.validation.BeanValidationProvider"/>
+  <bean id="validationInInterceptor" class="org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor">
+    <property name="provider" ref="validationProvider"/>
+  </bean>
+  <bean id="validationOutInterceptor" class="org.apache.cxf.jaxrs.validation.JAXRSBeanValidationOutInterceptor">
+    <property name="provider" ref="validationProvider"/>
+  </bean>   
+  
+  <bean id="gzipInInterceptor" class="org.apache.cxf.transport.common.gzip.GZIPInInterceptor"/>
+  <bean id="gzipOutInterceptor" class="org.apache.cxf.transport.common.gzip.GZIPOutInterceptor">
+    <property name="threshold" value="0"/>
+    <property name="force" value="true"/>
+  </bean>
+
+  <bean id="wadlGenerator" class="org.apache.cxf.jaxrs.model.wadl.WadlGenerator">
+    <property name="applicationTitle" value="Apache Syncope SCIMv2 ${syncope.version}"/>
+    <property name="namespacePrefix" value="syncope2"/>
+    <property name="incrementNamespacePrefix" value="false"/>    
+    <property name="linkAnyMediaTypeToXmlSchema" value="true"/>
+    <property name="useJaxbContextForQnames" value="true"/>
+    <property name="addResourceAndMethodIds" value="true"/>
+    <property name="ignoreMessageWriters" value="true"/>
+    <property name="usePathParamsToCompareOperations" value="false"/>
+  </bean>
+  
+  <jaxrs:server id="scimv2Container" address="/"
+                basePackages="org.apache.syncope.ext.scimv2.api.service, org.apache.syncope.ext.scimv2.cxf.service" 
+                staticSubresourceResolution="true">
+    <jaxrs:properties>
+      <entry key="convert.wadl.resources.to.dom" value="false"/>
+    </jaxrs:properties> 
+    <jaxrs:inInterceptors>
+      <ref bean="gzipInInterceptor"/>
+      <ref bean="validationInInterceptor"/>
+    </jaxrs:inInterceptors>  
+    <jaxrs:outInterceptors>
+      <ref bean="gzipOutInterceptor"/>
+      <ref bean="validationOutInterceptor"/>
+    </jaxrs:outInterceptors>
+    <jaxrs:providers>
+      <ref bean="jsonProvider"/>
+      <ref bean="wadlGenerator"/>
+    </jaxrs:providers>
+  </jaxrs:server>
+
+</beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/fit/core-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 7ea19b6..87348ff 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -1051,6 +1051,12 @@ under the License.
         </dependency>
         
         <dependency>
+          <groupId>org.apache.syncope.ext.scimv2</groupId>
+          <artifactId>syncope-ext-scimv2-scim-rest-cxf</artifactId>
+          <version>${project.version}</version>
+        </dependency>
+        
+        <dependency>
           <groupId>org.apache.syncope.ext</groupId>
           <artifactId>syncope-ext-swagger-ui</artifactId>
           <version>${project.version}</version>

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/fit/core-reference/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/webapp/WEB-INF/web.xml b/fit/core-reference/src/main/webapp/WEB-INF/web.xml
index 49a82fe..ad39dab 100644
--- a/fit/core-reference/src/main/webapp/WEB-INF/web.xml
+++ b/fit/core-reference/src/main/webapp/WEB-INF/web.xml
@@ -46,4 +46,4 @@ under the License.
     <auth-method>CLIENT-CERT</auth-method>
   </login-config>
 
-</web-app>
\ No newline at end of file
+</web-app>

http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/fit/core-reference/src/test/java/org/apache/syncope/fit/SCIMDetector.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/SCIMDetector.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/SCIMDetector.java
new file mode 100644
index 0000000..d236c7f
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/SCIMDetector.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.syncope.fit;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.xml.bind.DatatypeConverter;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.syncope.ext.scimv2.api.SCIMConstants;
+import org.apache.syncope.fit.core.SCIMITCase;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SCIMDetector {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SCIMDetector.class);
+
+    private static Boolean ENABLED;
+
+    public static boolean isSCIMAvailable() {
+        synchronized (LOG) {
+            if (ENABLED == null) {
+                try {
+                    Response response = WebClient.create(SCIMITCase.SCIM_ADDRESS).path("ServiceProviderConfigs").
+                            accept(SCIMConstants.APPLICATION_SCIM_JSON_TYPE).
+                            header(HttpHeaders.AUTHORIZATION,
+                                    "Basic " + DatatypeConverter.printBase64Binary(
+                                            (AbstractITCase.ADMIN_UNAME + ":" + AbstractITCase.ADMIN_PWD).getBytes())).
+                            get();
+                    ENABLED = response.getStatus() == 200;
+                } catch (Exception e) {
+                    // ignore
+                    ENABLED = false;
+                }
+            }
+        }
+        return ENABLED;
+    }
+}