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 2020/08/26 06:35:46 UTC

[syncope] branch master updated: [SYNCOPE-1585] Streamline OIDCC4UI ext (#212)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 6cc0cc0  [SYNCOPE-1585] Streamline OIDCC4UI ext (#212)
6cc0cc0 is described below

commit 6cc0cc0cc419ae666b3daecf3ab3139b0672baf5
Author: Francesco Chicchiriccò <il...@users.noreply.github.com>
AuthorDate: Wed Aug 26 08:35:36 2020 +0200

    [SYNCOPE-1585] Streamline OIDCC4UI ext (#212)
---
 .travis.yml                                        |   5 -
 archetype/pom.xml                                  |  16 -
 .../resources/archetype-resources/console/pom.xml  |   4 +-
 .../resources/archetype-resources/core/pom.xml     |   8 +-
 .../resources/archetype-resources/enduser/pom.xml  |   4 +-
 client/idrepo/console/pom.xml                      |   6 +-
 .../test/resources/application-debug.properties    |   3 +
 client/idrepo/enduser/pom.xml                      |   6 +-
 .../test/resources/application-debug.properties    |   3 +
 .../persistence/jpa/entity/auth/JPAOIDCRP.java     |   1 +
 docker/console/pom.xml                             |   4 +-
 docker/core/pom.xml                                |   8 +-
 docker/enduser/pom.xml                             |   4 +-
 .../client-common-ui/pom.xml                       |  20 +-
 .../panels/AbstractOIDCSSOLoginFormPanel.java      |  25 +-
 .../ui/commons/panels/OIDCC4UIConstants.java}      |  20 +-
 .../resources/oidcc4ui/BeforeLogoutResource.java   |  59 +++
 .../resources/oidcc4ui/CodeConsumerResource.java   |  88 ++++
 .../commons/resources/oidcc4ui/LoginResource.java  |  63 +++
 .../resources/oidcc4ui/LogoutResource.java}        |  20 +-
 .../panels/AbstractOIDCSSOLoginFormPanel.html      |   0
 .../client-console/pom.xml                         |  19 +-
 .../syncope/client/console/pages/OIDCC4UI.java}    |  10 +-
 .../console/pages/OIDCClientBeforeLogout.java      |   4 +-
 .../client/console/pages/OIDCClientLogin.java      |   8 +-
 .../client/console/pages/OIDCClientLogout.java     |  11 +-
 .../client/console/pages/OIDCClientSelfReg.java    |   0
 .../panels/OIDCProvidersDirectoryPanel.java        |  65 +--
 .../console/panels/OIDCSSOLoginFormPanel.java      |   3 +-
 .../resources/ConsoleCodeConsumerResource.java     |  43 ++
 .../console/resources/ConsoleLogoutResource.java}  |  26 +-
 .../console/rest/OIDCProviderRestClient.java       |  26 +-
 .../console/wizards/OIDCProviderWizardBuilder.java |  21 +-
 .../wizards/mapping/OIDCProviderMappingPanel.java  |   4 +-
 .../syncope/client/console/pages/OIDCC4UI.html}    |   2 +-
 .../client/console/pages/OIDCC4UI_it.properties}   |   0
 .../client/console/pages/OIDCC4UI_ru.properties}   |   0
 .../client/console/pages/OIDCClient.properties     |   0
 .../panels/OIDCProvidersDirectoryPanel.html        |   0
 .../panels/OIDCProvidersDirectoryPanel.properties  |   0
 .../OIDCProvidersDirectoryPanel_it.properties      |   0
 .../OIDCProvidersDirectoryPanel_pt_BR.properties   |   0
 .../OIDCProvidersDirectoryPanel_ru.properties      |   0
 .../console}/panels/OIDCSSOLoginFormPanel.html     |   0
 .../wizards/OIDCProviderWizardBuilder$Mapping.html |   0
 .../wizards/OIDCProviderWizardBuilder$OP.html      |   0
 .../OIDCProviderWizardBuilder$OP.properties        |   0
 .../OIDCProviderWizardBuilder$OPContinue.html      |   0
 ...OIDCProviderWizardBuilder$OPContinue.properties |   0
 ...CProviderWizardBuilder$OPContinue_it.properties |   0
 ...oviderWizardBuilder$OPContinue_pt_BR.properties |   0
 ...CProviderWizardBuilder$OPContinue_ru.properties |   0
 .../OIDCProviderWizardBuilder$OP_it.properties     |   0
 .../OIDCProviderWizardBuilder$OP_pt_BR.properties  |   0
 .../OIDCProviderWizardBuilder$OP_ru.properties     |   0
 .../client-enduser/pom.xml                         |  19 +-
 .../enduser/pages/OIDCClientBeforeLogout.java      |   4 +-
 .../client/enduser/pages/OIDCClientLogin.java      |   8 +-
 .../client/enduser/pages/OIDCClientLogout.java     |   5 -
 .../client/enduser/pages/OIDCClientSelfReg.java    |   7 +-
 .../enduser/panels/OIDCSSOLoginFormPanel.java      |   3 +-
 .../resources/EnduserCodeConsumerResource.java     |  44 ++
 .../enduser/resources/EnduserLogoutResource.java}  |  26 +-
 .../enduser}/panels/OIDCSSOLoginFormPanel.html     |   0
 ext/{oidcclient => oidcc4ui}/common-lib/pom.xml    |  14 +-
 .../syncope/common/lib/oidc}/OIDCConstants.java    |  15 +-
 .../common/lib/oidc/OIDCLoginResponse.java}        |   4 +-
 .../syncope/common/lib/oidc/OIDCRequest.java}      |  18 +-
 .../syncope/common/lib/to/OIDCC4UIProviderTO.java} |  10 +-
 .../common/lib/types/OIDC4UIEntitlement.java}      |   7 +-
 .../lib/types/OIDCClientImplementationType.java    |   2 +-
 .../provisioning-java => oidcc4ui/logic}/pom.xml   |  24 +-
 .../apache/syncope/core/logic/OIDCC4UILogic.java   | 290 ++++++++++++++
 .../syncope/core/logic/OIDCC4UIProviderLogic.java  | 148 +++++++
 .../syncope/core/logic/init/OIDCC4UILoader.java}   |   6 +-
 .../core/logic/model/TokenEndpointResponse.java    |   1 -
 .../core/logic/oidc/NoOpLogoutHandler.java}        |   7 +-
 .../syncope/core/logic/oidc/NoOpSessionStore.java  |  69 ++++
 .../syncope/core/logic/oidc/OIDC4UIContext.java    | 121 ++++++
 .../syncope/core/logic/oidc/OIDCClientCache.java   | 126 ++++++
 .../syncope/core/logic/oidc/OIDCUserManager.java   |  39 +-
 .../persistence-api/pom.xml                        |  14 +-
 .../persistence/api/dao/OIDCC4UIProviderDAO.java}  |  12 +-
 .../api/entity/OIDCC4UIEntityFactory.java}         |   2 +-
 .../persistence/api/entity/OIDCC4UIProvider.java}  |  14 +-
 .../api/entity/OIDCC4UIProviderItem.java}          |   6 +-
 .../api/entity/OIDCC4UIUserTemplate.java}          |   6 +-
 .../persistence-jpa/pom.xml                        |  14 +-
 .../jpa/dao/JPAOIDCC4UIProviderDAO.java}           |  33 +-
 .../jpa/entity/JPAOIDCC4UIEntityFactory.java}      |  22 +-
 .../jpa/entity/JPAOIDCC4UIProvider.java}           |  38 +-
 .../jpa/entity/JPAOIDCC4UIProviderItem.java}       |  18 +-
 .../jpa/entity/JPAOIDCC4UIUserTemplate.java}       |  18 +-
 .../validation/entity/OIDCC4UIProviderCheck.java}  |   6 +-
 .../entity/OIDCC4UIProviderValidator.java}         |   7 +-
 ext/{oidcclient => oidcc4ui}/pom.xml               |   7 +-
 .../provisioning-api/pom.xml                       |  18 +-
 .../provisioning/api/OIDCC4UIProviderActions.java} |  12 +-
 .../api/data/OIDCC4UIProviderDataBinder.java}      |  12 +-
 .../provisioning-java/pom.xml                      |  14 +-
 .../java/data/OIDCC4UIProviderDataBinderImpl.java} |  42 +-
 ext/{oidcclient => oidcc4ui}/rest-api/pom.xml      |  14 +-
 .../rest/api/service/OIDCC4UIProviderService.java} |  19 +-
 .../common/rest/api/service/OIDCC4UIService.java}  |  26 +-
 ext/{oidcclient => oidcc4ui}/rest-cxf/pom.xml      |  22 +-
 .../cxf/service/OIDCC4UIProviderServiceImpl.java}  |  20 +-
 .../rest/cxf/service/OIDCC4UIServiceImpl.java}     |  32 +-
 ext/oidcclient/agent/pom.xml                       | 136 -------
 .../agent/AbstractOIDCClientServlet.java           |  83 ----
 .../syncope/ext/oidcclient/agent/BeforeLogout.java |  71 ----
 .../syncope/ext/oidcclient/agent/CodeConsumer.java | 127 ------
 .../syncope/ext/oidcclient/agent/Constants.java    |  46 ---
 .../apache/syncope/ext/oidcclient/agent/Login.java | 100 -----
 .../syncope/ext/oidcclient/agent/Logout.java       |  64 ---
 .../oidcclient/agent/OIDCClientAgentContext.java   |  76 ----
 .../META-INF/resources/oidcclient/loginError.jsp   |  35 --
 .../META-INF/resources/oidcclient/loginSuccess.jsp |  33 --
 .../META-INF/resources/oidcclient/logoutError.jsp  |  35 --
 .../resources/oidcclient/logoutSuccess.jsp         |  27 --
 .../src/main/resources/META-INF/spring.factories   |  19 -
 .../src/main/resources/META-INF/web-fragment.xml   |  26 --
 .../src/main/resources/oidcclient-agent.properties |  22 -
 .../client/console/pages/OIDCClient_it.properties  |  17 -
 .../syncope/common/lib/to/OIDCLoginRequestTO.java  |  87 ----
 ext/oidcclient/logic/pom.xml                       |  76 ----
 .../apache/syncope/core/logic/OIDCClientLogic.java | 446 ---------------------
 .../syncope/core/logic/OIDCProviderLogic.java      | 170 --------
 .../logic/model/OIDCProviderDiscoveryDocument.java | 128 ------
 ext/pom.xml                                        |   2 +-
 .../panels/AbstractSAMLSSOLoginFormPanel.java      |  21 +-
 .../console/panels/SAML2IdPsDirectoryPanel.java    |  61 +--
 .../console/panels/SAMLSSOLoginFormPanel.java      |   1 -
 .../client/console/rest/SAML2IdPsRestClient.java   |   8 +-
 .../console/wizards/SAML2IdPWizardBuilder.java     |  14 +-
 .../wizards/mapping/SAML2IdPMappingPanel.java      |   4 +-
 .../enduser/panels/SAMLSSOLoginFormPanel.java      |   1 -
 .../{SAML24UIIdPTO.java => SAML2SP4UIIdPTO.java}   |   2 +-
 .../lib/types/SAML2SP4UIImplementationType.java    |   2 +-
 .../syncope/core/logic/SAML2SP4UIIdPLogic.java     |  27 +-
 .../apache/syncope/core/logic/SAML2SP4UILogic.java |   3 +-
 .../syncope/core/logic/saml2/SAML2ClientCache.java |  14 +-
 .../api/data/SAML2SP4UIIdPDataBinder.java          |   8 +-
 .../java/data/SAML2SP4UIIdPDataBinderImpl.java     |  14 +-
 .../rest/api/service/SAML2SP4UIIdPService.java     |   8 +-
 .../rest/cxf/service/SAML2SP4UIIdPServiceImpl.java |   8 +-
 .../rest/cxf/service/SAML2SP4UIServiceImpl.java    |   4 +-
 fit/console-reference/pom.xml                      |   4 +-
 .../src/main/resources/oidcclient-agent.properties |  22 -
 .../src/main/webapp/WEB-INF/web.xml                |  24 --
 fit/core-reference/pom.xml                         |  16 +-
 .../org/apache/syncope/fit/AbstractITCase.java     |  12 +-
 .../org/apache/syncope/fit/OIDCClientDetector.java |   4 +-
 .../apache/syncope/fit/core/OIDCClientITCase.java  | 125 ------
 fit/enduser-reference/pom.xml                      |   4 +-
 .../src/main/resources/oidcclient-agent.properties |  22 -
 .../src/main/webapp/WEB-INF/web.xml                |  23 --
 fit/wa-reference/pom.xml                           |   4 +-
 .../org/apache/syncope/fit/AbstractITCase.java     |   6 +-
 .../apache/syncope/fit/sra/AbstractSRAITCase.java  |   2 +-
 .../org/apache/syncope/fit/sra/OIDCSRAITCase.java  |   1 +
 .../apache/syncope/fit/ui/AbstractUIITCase.java    |  28 +-
 .../org/apache/syncope/fit/ui/OIDC4UIITCase.java   |  97 +++--
 .../apache/syncope/fit/ui/SAML2SP4UIITCase.java    |  25 +-
 pom.xml                                            |  10 -
 .../resources/debug/application-debug.properties   |  32 +-
 .../reference-guide/concepts/extensions.adoc       |   4 +-
 .../workingwithapachesyncope/customization.adoc    |  20 +-
 167 files changed, 1774 insertions(+), 2811 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 2beae45..d928186 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -74,8 +74,6 @@ jobs:
     - stage: test
       name: "Persistence Unit Tests via JDK 11: PostgreSQL (JSONB)"
       script: mvn -f core/persistence-jpa-json/pom.xml -P postgres -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Dianal.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Dsass.skip=true
-      after_failure:
-       - cat core/persistence-jpa-json/target/failsafe-reports/org.apache.syncope.core.persistence.jpa.inner.AnySearchTest*
     - stage: test
       name: "Persistence Unit Tests via JDK 11: MySQL (JSON)"
       script: mvn -f core/persistence-jpa-json/pom.xml -P mysql -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Dianal.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Dsass.skip=true
@@ -119,7 +117,4 @@ jobs:
     - stage: fit
       name: "Integration Tests: SRA and WA"
       script: mvn -f fit/wa-reference/pom.xml verify -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Dianal.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true
-      after_failure:
-       - cat fit/wa-reference/target/log/*
-       - cat fit/core-reference/target/log/*
     #####################################################
diff --git a/archetype/pom.xml b/archetype/pom.xml
index f51e7b1..081d7ac 100644
--- a/archetype/pom.xml
+++ b/archetype/pom.xml
@@ -244,13 +244,6 @@ under the License.
         </includes>
       </resource>
       <resource>
-        <directory>../ext/oidcclient/agent/src/main/resources</directory>
-        <targetPath>${project.build.outputDirectory}/archetype-resources/console/src/main/resources/all</targetPath>
-        <includes>
-          <include>oidcclient-agent.properties</include>
-        </includes>
-      </resource>
-      <resource>
         <directory>../ext/self-keymaster/client/src/main/resources</directory>
         <targetPath>${project.build.outputDirectory}/archetype-resources/console/src/main/resources</targetPath>
         <includes>
@@ -271,7 +264,6 @@ under the License.
         <includes>
           <include>console.properties</include>
           <include>keymaster.properties</include>
-          <include>oidcclient-agent.properties</include>
         </includes>
       </resource>
       <resource>
@@ -297,13 +289,6 @@ under the License.
         </includes>
       </resource>
       <resource>
-        <directory>../ext/oidcclient/agent/src/main/resources</directory>
-        <targetPath>${project.build.outputDirectory}/archetype-resources/enduser/src/main/resources/all</targetPath>
-        <includes>
-          <include>oidcclient-agent.properties</include>
-        </includes>
-      </resource>
-      <resource>
         <directory>../fit/enduser-reference/src/main/resources</directory>
         <targetPath>${project.build.outputDirectory}/archetype-resources/enduser/src/main/resources</targetPath>
         <includes>
@@ -319,7 +304,6 @@ under the License.
           <include>customFormAttributes.json</include>
           <include>customTemplate.json</include>
           <include>keymaster.properties</include>
-          <include>oidcclient-agent.properties</include>
         </includes>
       </resource>
       <resource>
diff --git a/archetype/src/main/resources/archetype-resources/console/pom.xml b/archetype/src/main/resources/archetype-resources/console/pom.xml
index 21eb781..9a5b879 100644
--- a/archetype/src/main/resources/archetype-resources/console/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/console/pom.xml
@@ -96,8 +96,8 @@ under the License.
         </dependency>
         
         <dependency>
-          <groupId>org.apache.syncope.ext.oidcclient</groupId>
-          <artifactId>syncope-ext-oidcclient-client-console</artifactId>
+          <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+          <artifactId>syncope-ext-oidcc4ui-client-console</artifactId>
           <version>${syncope.version}</version>
         </dependency>
         
diff --git a/archetype/src/main/resources/archetype-resources/core/pom.xml b/archetype/src/main/resources/archetype-resources/core/pom.xml
index 4101fa2..b7fe116 100644
--- a/archetype/src/main/resources/archetype-resources/core/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/core/pom.xml
@@ -150,13 +150,13 @@ under the License.
         </dependency>
 
         <dependency>
-          <groupId>org.apache.syncope.ext.oidcclient</groupId>
-          <artifactId>syncope-ext-oidcclient-rest-cxf</artifactId>
+          <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+          <artifactId>syncope-ext-oidcc4ui-rest-cxf</artifactId>
           <version>${syncope.version}</version>
         </dependency>
         <dependency>
-          <groupId>org.apache.syncope.ext.oidcclient</groupId>
-          <artifactId>syncope-ext-oidcclient-persistence-jpa</artifactId>
+          <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+          <artifactId>syncope-ext-oidcc4ui-persistence-jpa</artifactId>
           <version>${syncope.version}</version>
         </dependency>
 
diff --git a/archetype/src/main/resources/archetype-resources/enduser/pom.xml b/archetype/src/main/resources/archetype-resources/enduser/pom.xml
index fc34207..ac8a728 100644
--- a/archetype/src/main/resources/archetype-resources/enduser/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/enduser/pom.xml
@@ -104,8 +104,8 @@ under the License.
         </dependency>
 
         <dependency>
-          <groupId>org.apache.syncope.ext.oidcclient</groupId>
-          <artifactId>syncope-ext-oidcclient-client-enduser</artifactId>
+          <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+          <artifactId>syncope-ext-oidcc4ui-client-enduser</artifactId>
           <version>${syncope.version}</version>
         </dependency>
         
diff --git a/client/idrepo/console/pom.xml b/client/idrepo/console/pom.xml
index 0b757a7..9ae8cfb 100644
--- a/client/idrepo/console/pom.xml
+++ b/client/idrepo/console/pom.xml
@@ -260,7 +260,7 @@ under the License.
             <configuration>
               <jvmArguments>
                 -Dwicket.core.settings.general.configuration-type=development
-                -Xdebug -Xrunjdwp:transport=dt_socket,address=8001,server=y,suspend=n
+                -Xdebug -Xrunjdwp:transport=dt_socket,address=8003,server=y,suspend=n
               </jvmArguments>
               <profiles>
                 <profile>debug</profile>
@@ -327,8 +327,8 @@ under the License.
           <version>${project.version}</version>
         </dependency>
         <dependency>
-          <groupId>org.apache.syncope.ext.oidcclient</groupId>
-          <artifactId>syncope-ext-oidcclient-client-console</artifactId>
+          <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+          <artifactId>syncope-ext-oidcc4ui-client-console</artifactId>
           <version>${project.version}</version>
         </dependency>
       </dependencies>
diff --git a/client/idrepo/console/src/test/resources/application-debug.properties b/client/idrepo/console/src/test/resources/application-debug.properties
index 033fe3b..1ac160d 100644
--- a/client/idrepo/console/src/test/resources/application-debug.properties
+++ b/client/idrepo/console/src/test/resources/application-debug.properties
@@ -17,3 +17,6 @@
 keymaster.address=http://localhost:9080/syncope/rest/keymaster
 keymaster.username=${anonymousUser}
 keymaster.password=${anonymousKey}
+
+server.port=9090
+service.discovery.address=http://localhost:9090/syncope-console/
diff --git a/client/idrepo/enduser/pom.xml b/client/idrepo/enduser/pom.xml
index 4e4ced2..d34a91f 100644
--- a/client/idrepo/enduser/pom.xml
+++ b/client/idrepo/enduser/pom.xml
@@ -240,7 +240,7 @@ under the License.
             <configuration>
               <jvmArguments>
                 -Dwicket.core.settings.general.configuration-type=development
-                -Xdebug -Xrunjdwp:transport=dt_socket,address=8001,server=y,suspend=n
+                -Xdebug -Xrunjdwp:transport=dt_socket,address=8004,server=y,suspend=n
               </jvmArguments>
               <profiles>
                 <profile>debug</profile>
@@ -285,8 +285,8 @@ under the License.
         </dependency>
 
         <dependency>
-          <groupId>org.apache.syncope.ext.oidcclient</groupId>
-          <artifactId>syncope-ext-oidcclient-client-enduser</artifactId>
+          <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+          <artifactId>syncope-ext-oidcc4ui-client-enduser</artifactId>
           <version>${project.version}</version>
         </dependency>
       </dependencies>
diff --git a/client/idrepo/enduser/src/test/resources/application-debug.properties b/client/idrepo/enduser/src/test/resources/application-debug.properties
index 033fe3b..fc1b6e4 100644
--- a/client/idrepo/enduser/src/test/resources/application-debug.properties
+++ b/client/idrepo/enduser/src/test/resources/application-debug.properties
@@ -17,3 +17,6 @@
 keymaster.address=http://localhost:9080/syncope/rest/keymaster
 keymaster.username=${anonymousUser}
 keymaster.password=${anonymousKey}
+
+server.port=9091
+service.discovery.address=http://localhost:9091/syncope-enduser/
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/auth/JPAOIDCRP.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/auth/JPAOIDCRP.java
index 4ff3e0d..dee84f4 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/auth/JPAOIDCRP.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/auth/JPAOIDCRP.java
@@ -42,6 +42,7 @@ public class JPAOIDCRP extends AbstractClientApp implements OIDCRP {
 
     public static final String TABLE = "OIDCRP";
 
+    @Column(unique = true, nullable = false)
     private String clientId;
 
     private String clientSecret;
diff --git a/docker/console/pom.xml b/docker/console/pom.xml
index 1fc8679..40d8da8 100644
--- a/docker/console/pom.xml
+++ b/docker/console/pom.xml
@@ -84,8 +84,8 @@ under the License.
     </dependency>
 
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-client-console</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-client-console</artifactId>
       <version>${project.version}</version>
     </dependency>
 
diff --git a/docker/core/pom.xml b/docker/core/pom.xml
index a319e7b..7de23c5 100644
--- a/docker/core/pom.xml
+++ b/docker/core/pom.xml
@@ -126,13 +126,13 @@ under the License.
     </dependency>
 
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-rest-cxf</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-rest-cxf</artifactId>
       <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-persistence-jpa</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-persistence-jpa</artifactId>
       <version>${project.version}</version>
     </dependency>
 
diff --git a/docker/enduser/pom.xml b/docker/enduser/pom.xml
index 6b31697..ba537c3 100644
--- a/docker/enduser/pom.xml
+++ b/docker/enduser/pom.xml
@@ -73,8 +73,8 @@ under the License.
     </dependency>
 
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-client-enduser</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-client-enduser</artifactId>
       <version>${project.version}</version>
     </dependency>
   </dependencies>
diff --git a/ext/oidcclient/client-common-ui/pom.xml b/ext/oidcc4ui/client-common-ui/pom.xml
similarity index 76%
rename from ext/oidcclient/client-common-ui/pom.xml
rename to ext/oidcc4ui/client-common-ui/pom.xml
index 24fafb1..dfb13d6 100644
--- a/ext/oidcclient/client-common-ui/pom.xml
+++ b/ext/oidcc4ui/client-common-ui/pom.xml
@@ -23,14 +23,14 @@ under the License.
 
   <parent>
     <groupId>org.apache.syncope.ext</groupId>
-    <artifactId>syncope-ext-oidcclient</artifactId>
+    <artifactId>syncope-ext-oidcc4ui</artifactId>
     <version>3.0.0-SNAPSHOT</version>
   </parent>
 
-  <name>Apache Syncope Ext: OIDC Client Common UI Lib</name>
-  <description>Apache Syncope Ext: OIDC Client Common UI Lib</description>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-client-common-ui</artifactId>
+  <name>Apache Syncope Ext: OIDC C4UI Common UI</name>
+  <description>Apache Syncope Ext: OIDC C4UI Common UI</description>
+  <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+  <artifactId>syncope-ext-oidcc4ui-client-common-ui</artifactId>
   <packaging>jar</packaging>
    
   <properties>
@@ -39,8 +39,14 @@ under the License.
 
   <dependencies>
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-rest-api</artifactId>
+      <groupId>javax.servlet</groupId>
+      <artifactId>javax.servlet-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-rest-api</artifactId>
       <version>${project.version}</version>
     </dependency>
 
diff --git a/ext/oidcclient/client-common-ui/src/main/java/org/apache/syncope/client/common/ui/panels/AbstractOIDCSSOLoginFormPanel.java b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/AbstractOIDCSSOLoginFormPanel.java
similarity index 80%
rename from ext/oidcclient/client-common-ui/src/main/java/org/apache/syncope/client/common/ui/panels/AbstractOIDCSSOLoginFormPanel.java
rename to ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/AbstractOIDCSSOLoginFormPanel.java
index b08ffb4..b8b6974 100644
--- a/ext/oidcclient/client-common-ui/src/main/java/org/apache/syncope/client/common/ui/panels/AbstractOIDCSSOLoginFormPanel.java
+++ b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/AbstractOIDCSSOLoginFormPanel.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.client.common.ui.panels;
+package org.apache.syncope.client.ui.commons.panels;
 
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
@@ -24,9 +24,7 @@ import java.util.List;
 import org.apache.syncope.client.ui.commons.BaseSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
-import org.apache.syncope.client.ui.commons.panels.BaseSSOLoginFormPanel;
-import org.apache.syncope.common.lib.to.OIDCProviderTO;
-import org.apache.syncope.common.rest.api.service.OIDCProviderService;
+import org.apache.syncope.common.lib.to.OIDCC4UIProviderTO;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
 import org.apache.wicket.markup.html.form.IChoiceRenderer;
@@ -37,6 +35,7 @@ import org.apache.wicket.request.cycle.RequestCycle;
 import org.apache.wicket.request.http.handler.RedirectRequestHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.apache.syncope.common.rest.api.service.OIDCC4UIProviderService;
 
 public abstract class AbstractOIDCSSOLoginFormPanel extends BaseSSOLoginFormPanel {
 
@@ -47,29 +46,29 @@ public abstract class AbstractOIDCSSOLoginFormPanel extends BaseSSOLoginFormPane
     public AbstractOIDCSSOLoginFormPanel(final String id, final BaseSession session) {
         super(id);
 
-        List<OIDCProviderTO> available = session.getAnonymousService(OIDCProviderService.class).list();
+        List<OIDCC4UIProviderTO> available = session.getAnonymousService(OIDCC4UIProviderService.class).list();
 
-        final Model<OIDCProviderTO> model = new Model<>();
-        AjaxDropDownChoicePanel<OIDCProviderTO> ops =
+        final Model<OIDCC4UIProviderTO> model = new Model<>();
+        AjaxDropDownChoicePanel<OIDCC4UIProviderTO> ops =
                 new AjaxDropDownChoicePanel<>("ops", "OpenID Connect", model, false);
         ops.setChoices(available);
-        ops.setChoiceRenderer(new IChoiceRenderer<OIDCProviderTO>() {
+        ops.setChoiceRenderer(new IChoiceRenderer<OIDCC4UIProviderTO>() {
 
             private static final long serialVersionUID = 1814750973898916102L;
 
             @Override
-            public Object getDisplayValue(final OIDCProviderTO object) {
+            public Object getDisplayValue(final OIDCC4UIProviderTO object) {
                 return object.getName();
             }
 
             @Override
-            public String getIdValue(final OIDCProviderTO object, final int index) {
+            public String getIdValue(final OIDCC4UIProviderTO object, final int index) {
                 return object.getName();
             }
 
             @Override
-            public OIDCProviderTO getObject(final String id,
-                    final IModel<? extends List<? extends OIDCProviderTO>> choices) {
+            public OIDCC4UIProviderTO getObject(final String id,
+                    final IModel<? extends List<? extends OIDCC4UIProviderTO>> choices) {
 
                 return choices.getObject().stream().
                         filter(object -> object.getName().equals(id)).findFirst().orElse(null);
@@ -85,7 +84,7 @@ public abstract class AbstractOIDCSSOLoginFormPanel extends BaseSSOLoginFormPane
                 if (model.getObject() != null) {
                     try {
                         RequestCycle.get().scheduleRequestHandlerAfterCurrent(new RedirectRequestHandler(
-                                UrlUtils.rewriteToContextRelative("oidcclient/login?op="
+                                UrlUtils.rewriteToContextRelative(OIDCC4UIConstants.URL_CONTEXT + "/login?op="
                                         + URLEncoder.encode(model.getObject().getName(), StandardCharsets.UTF_8),
                                         RequestCycle.get())));
                     } catch (Exception e) {
diff --git a/ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/to/OIDCLogoutRequestTO.java b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/OIDCC4UIConstants.java
similarity index 62%
rename from ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/to/OIDCLogoutRequestTO.java
rename to ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/OIDCC4UIConstants.java
index 4fd28f3..aeb8bff 100644
--- a/ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/to/OIDCLogoutRequestTO.java
+++ b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/OIDCC4UIConstants.java
@@ -16,21 +16,21 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.common.lib.to;
+package org.apache.syncope.client.ui.commons.panels;
 
-import java.io.Serializable;
+public final class OIDCC4UIConstants {
 
-public class OIDCLogoutRequestTO implements Serializable {
+    public static final String URL_CONTEXT = "oidcc4ui";
 
-    private static final long serialVersionUID = -4708360216757961537L;
+    public static final String PARAM_OP = "op";
 
-    private String endSessionEndpoint;
+    public static final String OIDCC4UI_JWT = "oidcc4ui.jwt";
 
-    public String getEndSessionEndpoint() {
-        return endSessionEndpoint;
-    }
+    public static final String OIDCC4UI_NEW_USER = "oidcc4ui.newUser";
+
+    public static final String OIDCC4UI_SLO_SUPPORTED = "oidcc4ui.sloSupported";
 
-    public void setEndSessionEndpoint(final String endSessionEndpoint) {
-        this.endSessionEndpoint = endSessionEndpoint;
+    private OIDCC4UIConstants() {
+        // private constructor for static utility class
     }
 }
diff --git a/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/oidcc4ui/BeforeLogoutResource.java b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/oidcc4ui/BeforeLogoutResource.java
new file mode 100644
index 0000000..010d9f4
--- /dev/null
+++ b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/oidcc4ui/BeforeLogoutResource.java
@@ -0,0 +1,59 @@
+/*
+ * 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.client.ui.commons.resources.oidcc4ui;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.ui.commons.BaseSession;
+import org.apache.syncope.client.ui.commons.annotations.Resource;
+import org.apache.syncope.client.ui.commons.panels.OIDCC4UIConstants;
+import org.apache.syncope.common.lib.oidc.OIDCRequest;
+import org.apache.syncope.common.rest.api.service.OIDCC4UIService;
+import org.apache.wicket.Session;
+import org.apache.wicket.request.resource.AbstractResource;
+
+@Resource(
+        key = OIDCC4UIConstants.URL_CONTEXT + ".beforeLogout",
+        path = "/" + OIDCC4UIConstants.URL_CONTEXT + "/before-logout")
+public class BeforeLogoutResource extends AbstractResource {
+
+    private static final long serialVersionUID = 273797583932923564L;
+
+    @Override
+    protected ResourceResponse newResourceResponse(final Attributes attributes) {
+        HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
+        String postLogoutRedirectURI = StringUtils.substringBefore(
+                request.getRequestURL().toString(), "/before-logout") + "/logout";
+
+        OIDCC4UIService service = BaseSession.class.cast(Session.get()).getService(OIDCC4UIService.class);
+        OIDCRequest logoutRequest = service.createLogoutRequest(postLogoutRedirectURI);
+
+        ResourceResponse response = new ResourceResponse();
+        response.setStatusCode(Response.Status.FOUND.getStatusCode());
+        response.getHeaders().addHeader(HttpHeaders.CACHE_CONTROL, "no-cache, no-store");
+        response.getHeaders().addHeader("Pragma", "no-cache");
+        response.getHeaders().addHeader(HttpHeaders.LOCATION, logoutRequest.getLocation());
+
+        Session.get().invalidate();
+
+        return response;
+    }
+}
diff --git a/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/oidcc4ui/CodeConsumerResource.java b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/oidcc4ui/CodeConsumerResource.java
new file mode 100644
index 0000000..b76a2d0
--- /dev/null
+++ b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/oidcc4ui/CodeConsumerResource.java
@@ -0,0 +1,88 @@
+/*
+ * 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.client.ui.commons.resources.oidcc4ui;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import javax.servlet.http.HttpServletRequest;
+import org.apache.syncope.client.ui.commons.BaseSession;
+import org.apache.syncope.client.ui.commons.panels.OIDCC4UIConstants;
+import org.apache.syncope.common.lib.oidc.OIDCConstants;
+import org.apache.syncope.common.lib.oidc.OIDCLoginResponse;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.rest.api.service.OIDCC4UIService;
+import org.apache.wicket.RestartResponseException;
+import org.apache.wicket.Session;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.resource.AbstractResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class CodeConsumerResource extends AbstractResource {
+
+    protected static final Logger LOG = LoggerFactory.getLogger(CodeConsumerResource.class);
+
+    private static final ObjectMapper MAPPER =
+            new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
+
+    private static final long serialVersionUID = -692581789294259519L;
+
+    protected abstract Class<? extends WebPage> getLoginPageClass();
+
+    protected abstract Class<? extends WebPage> getSelfRegPageClass();
+
+    @Override
+    protected ResourceResponse newResourceResponse(final Attributes attributes) {
+        String authorizationCode = attributes.getRequest().getQueryParameters().
+                getParameterValue(OIDCConstants.CODE).toOptionalString();
+
+        HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
+
+        OIDCC4UIService service = BaseSession.class.cast(Session.get()).getAnonymousService(OIDCC4UIService.class);
+        OIDCLoginResponse oidcResponse = service.login(
+                request.getRequestURL().toString(),
+                authorizationCode,
+                Session.get().getAttribute(OIDCConstants.OP).toString());
+
+        if (oidcResponse.isSelfReg()) {
+            UserTO newUser = new UserTO();
+            newUser.setUsername(oidcResponse.getUsername());
+            newUser.getPlainAttrs().addAll(oidcResponse.getAttrs());
+
+            try {
+                throw new RestartResponseException(
+                        getSelfRegPageClass(),
+                        new PageParameters().
+                                set(OIDCC4UIConstants.OIDCC4UI_NEW_USER, MAPPER.writeValueAsString(newUser)));
+            } catch (JsonProcessingException e) {
+                LOG.error("Could not serialize new user {}", newUser, e);
+                throw new WicketRuntimeException(e);
+            }
+        } else {
+            throw new RestartResponseException(
+                    getLoginPageClass(),
+                    new PageParameters().
+                            set(OIDCC4UIConstants.OIDCC4UI_JWT, oidcResponse.getAccessToken()).
+                            set(OIDCC4UIConstants.OIDCC4UI_SLO_SUPPORTED, oidcResponse.isLogoutSupported()));
+        }
+    }
+}
diff --git a/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/oidcc4ui/LoginResource.java b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/oidcc4ui/LoginResource.java
new file mode 100644
index 0000000..3ebe48c
--- /dev/null
+++ b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/oidcc4ui/LoginResource.java
@@ -0,0 +1,63 @@
+/*
+ * 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.client.ui.commons.resources.oidcc4ui;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.ui.commons.BaseSession;
+import org.apache.syncope.client.ui.commons.annotations.Resource;
+import org.apache.syncope.client.ui.commons.panels.OIDCC4UIConstants;
+import org.apache.syncope.common.lib.oidc.OIDCConstants;
+import org.apache.syncope.common.lib.oidc.OIDCRequest;
+import org.apache.syncope.common.rest.api.service.OIDCC4UIService;
+import org.apache.wicket.Session;
+import org.apache.wicket.request.resource.AbstractResource;
+
+@Resource(
+        key = OIDCC4UIConstants.URL_CONTEXT + ".login",
+        path = "/" + OIDCC4UIConstants.URL_CONTEXT + "/login")
+public class LoginResource extends AbstractResource {
+
+    private static final long serialVersionUID = -3076690953674174306L;
+
+    @Override
+    protected ResourceResponse newResourceResponse(final Attributes attributes) {
+        String op = attributes.getRequest().getQueryParameters().
+                getParameterValue(OIDCC4UIConstants.PARAM_OP).toString();
+
+        HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
+        String redirectURI = StringUtils.substringBefore(
+                request.getRequestURL().toString(), "/login") + "/code-consumer";
+
+        OIDCC4UIService service = BaseSession.class.cast(Session.get()).getAnonymousService(OIDCC4UIService.class);
+        OIDCRequest loginRequest = service.createLoginRequest(redirectURI, op);
+
+        Session.get().setAttribute(OIDCConstants.OP, op);
+
+        ResourceResponse response = new ResourceResponse();
+        response.setStatusCode(Response.Status.FOUND.getStatusCode());
+        response.getHeaders().addHeader(HttpHeaders.CACHE_CONTROL, "no-cache, no-store");
+        response.getHeaders().addHeader("Pragma", "no-cache");
+        response.getHeaders().addHeader(HttpHeaders.LOCATION, loginRequest.getLocation());
+
+        return response;
+    }
+}
diff --git a/ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogout.java b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/oidcc4ui/LogoutResource.java
similarity index 62%
copy from ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogout.java
copy to ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/oidcc4ui/LogoutResource.java
index 2cb8c7a..2a602b7 100644
--- a/ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogout.java
+++ b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/oidcc4ui/LogoutResource.java
@@ -16,23 +16,21 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.client.enduser.pages;
+package org.apache.syncope.client.ui.commons.resources.oidcc4ui;
 
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
+import org.apache.wicket.RestartResponseException;
 import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.resource.AbstractResource;
 
-public class OIDCClientLogout extends WebPage {
+public abstract class LogoutResource extends AbstractResource {
 
-    private static final long serialVersionUID = -1453838909720946011L;
+    private static final long serialVersionUID = 273797583932923564L;
 
-    public OIDCClientLogout(final PageParameters parameters) {
-        super(parameters);
+    protected abstract Class<? extends WebPage> getLogoutPageClass();
 
-        SyncopeEnduserSession.get().cleanup();
-
-        SyncopeEnduserSession.get().invalidate();
-
-        setResponsePage(getApplication().getHomePage());
+    @Override
+    protected ResourceResponse newResourceResponse(final Attributes attributes) {
+        throw new RestartResponseException(getLogoutPageClass(), new PageParameters());
     }
 }
diff --git a/ext/oidcclient/client-common-ui/src/main/resources/org/apache/syncope/client/common/ui/panels/AbstractOIDCSSOLoginFormPanel.html b/ext/oidcc4ui/client-common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/AbstractOIDCSSOLoginFormPanel.html
similarity index 100%
rename from ext/oidcclient/client-common-ui/src/main/resources/org/apache/syncope/client/common/ui/panels/AbstractOIDCSSOLoginFormPanel.html
rename to ext/oidcc4ui/client-common-ui/src/main/resources/org/apache/syncope/client/ui/commons/panels/AbstractOIDCSSOLoginFormPanel.html
diff --git a/ext/oidcclient/client-console/pom.xml b/ext/oidcc4ui/client-console/pom.xml
similarity index 76%
rename from ext/oidcclient/client-console/pom.xml
rename to ext/oidcc4ui/client-console/pom.xml
index db35d15..160f247 100644
--- a/ext/oidcclient/client-console/pom.xml
+++ b/ext/oidcc4ui/client-console/pom.xml
@@ -23,14 +23,14 @@ under the License.
 
   <parent>
     <groupId>org.apache.syncope.ext</groupId>
-    <artifactId>syncope-ext-oidcclient</artifactId>
+    <artifactId>syncope-ext-oidcc4ui</artifactId>
     <version>3.0.0-SNAPSHOT</version>
   </parent>
 
-  <name>Apache Syncope Ext: OIDC Client Console</name>
-  <description>Apache Syncope Ext: OIDC Client Console</description>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-client-console</artifactId>
+  <name>Apache Syncope Ext: OIDC C4UI Console</name>
+  <description>Apache Syncope Ext: OIDC C4UI Console</description>
+  <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+  <artifactId>syncope-ext-oidcc4ui-client-console</artifactId>
   <packaging>jar</packaging>
   
   <properties>
@@ -44,19 +44,14 @@ under the License.
     </dependency>
 
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-agent</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
       <groupId>org.apache.syncope.client.idm</groupId>
       <artifactId>syncope-client-idm-console</artifactId>
       <version>${project.version}</version>
     </dependency>
     
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-client-common-ui</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-client-common-ui</artifactId>
       <version>${project.version}</version>
     </dependency>
   </dependencies>
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClient.java b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCC4UI.java
similarity index 88%
rename from ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClient.java
rename to ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCC4UI.java
index 18b65bd..364a0f8 100644
--- a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClient.java
+++ b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCC4UI.java
@@ -24,7 +24,7 @@ import java.util.List;
 import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.syncope.client.console.panels.OIDCProvidersDirectoryPanel;
 import org.apache.syncope.client.ui.commons.annotations.ExtPage;
-import org.apache.syncope.common.lib.types.OIDCClientEntitlement;
+import org.apache.syncope.common.lib.types.OIDC4UIEntitlement;
 import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
 import org.apache.wicket.extensions.markup.html.tabs.ITab;
 import org.apache.wicket.markup.html.WebMarkupContainer;
@@ -32,13 +32,13 @@ import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
-@ExtPage(label = "OpenID Connect 1.0 Client", icon = "fab fa-openid", 
-        listEntitlement = OIDCClientEntitlement.OP_READ, priority = 300)
-public class OIDCClient extends BaseExtPage {
+@ExtPage(label = "OpenID Connect 1.0 C4UI", icon = "fab fa-openid", 
+        listEntitlement = OIDC4UIEntitlement.OP_READ, priority = 300)
+public class OIDCC4UI extends BaseExtPage {
 
     private static final long serialVersionUID = -599601954212606001L;
 
-    public OIDCClient(final PageParameters parameters) {
+    public OIDCC4UI(final PageParameters parameters) {
         super(parameters);
 
         body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientBeforeLogout.java b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientBeforeLogout.java
similarity index 86%
rename from ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientBeforeLogout.java
rename to ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientBeforeLogout.java
index 0a5a766..ed03d8d 100644
--- a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientBeforeLogout.java
+++ b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientBeforeLogout.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.pages;
 
+import org.apache.syncope.client.ui.commons.panels.OIDCC4UIConstants;
 import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.request.UrlUtils;
 import org.apache.wicket.request.cycle.RequestCycle;
@@ -31,6 +32,7 @@ public class OIDCClientBeforeLogout extends WebPage {
         super();
 
         RequestCycle.get().scheduleRequestHandlerAfterCurrent(new RedirectRequestHandler(
-                UrlUtils.rewriteToContextRelative("oidcclient/beforelogout", RequestCycle.get())));
+                UrlUtils.rewriteToContextRelative(OIDCC4UIConstants.URL_CONTEXT + "/before-logout",
+                        RequestCycle.get())));
     }
 }
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientLogin.java b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientLogin.java
similarity index 89%
rename from ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientLogin.java
rename to ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientLogin.java
index 534092f..5e277f8 100644
--- a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientLogin.java
+++ b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientLogin.java
@@ -21,9 +21,9 @@ package org.apache.syncope.client.console.pages;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.ui.commons.panels.OIDCC4UIConstants;
 import org.apache.wicket.authentication.IAuthenticationStrategy;
 import org.apache.wicket.markup.html.WebPage;
-import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -39,8 +39,7 @@ public class OIDCClientLogin extends WebPage {
     public OIDCClientLogin(final PageParameters parameters) {
         super(parameters);
 
-        String token = (String) ((ServletWebRequest) getRequest()).getContainerRequest().
-                getSession().getAttribute(org.apache.syncope.ext.oidcclient.agent.Constants.OIDCCLIENTJWT);
+        String token = parameters.get(OIDCC4UIConstants.OIDCC4UI_JWT).toOptionalString();
         if (StringUtils.isBlank(token)) {
             LOG.error("No JWT found, redirecting to default greeter");
 
@@ -52,7 +51,7 @@ public class OIDCClientLogin extends WebPage {
         IAuthenticationStrategy strategy = getApplication().getSecuritySettings().getAuthenticationStrategy();
 
         if (SyncopeConsoleSession.get().authenticate(token)) {
-            if (parameters.get("logoutSupported").toBoolean(false)) {
+            if (parameters.get(OIDCC4UIConstants.OIDCC4UI_SLO_SUPPORTED).toBoolean(false)) {
                 SyncopeConsoleSession.get().setAttribute(Constants.BEFORE_LOGOUT_PAGE, OIDCClientBeforeLogout.class);
             }
 
@@ -67,5 +66,4 @@ public class OIDCClientLogin extends WebPage {
         }
         strategy.remove();
     }
-
 }
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientLogout.java b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientLogout.java
similarity index 83%
rename from ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientLogout.java
rename to ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientLogout.java
index e13b40c..0141e0e 100644
--- a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientLogout.java
+++ b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientLogout.java
@@ -18,21 +18,16 @@
  */
 package org.apache.syncope.client.console.pages;
 
-import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
 
 public class OIDCClientLogout extends WebPage {
 
     private static final long serialVersionUID = -4862264444058746154L;
 
-    public OIDCClientLogout() {
-        super();
-
-        SyncopeConsoleSession.get().cleanup();
-
-        SyncopeConsoleSession.get().invalidate();
+    public OIDCClientLogout(final PageParameters parameters) {
+        super(parameters);
 
         setResponsePage(getApplication().getHomePage());
     }
-
 }
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientSelfReg.java b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientSelfReg.java
similarity index 100%
rename from ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientSelfReg.java
rename to ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientSelfReg.java
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.java b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.java
similarity index 81%
rename from ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.java
rename to ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.java
index 621e6c4..06a6dde 100644
--- a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.java
+++ b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.java
@@ -47,10 +47,10 @@ import org.apache.syncope.client.ui.commons.panels.WizardModalPanel;
 import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
 import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.OIDCProviderTO;
+import org.apache.syncope.common.lib.to.OIDCC4UIProviderTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.OIDCClientEntitlement;
+import org.apache.syncope.common.lib.types.OIDC4UIEntitlement;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
@@ -66,7 +66,7 @@ import org.apache.wicket.model.Model;
 import org.apache.wicket.model.StringResourceModel;
 
 public class OIDCProvidersDirectoryPanel extends DirectoryPanel<
-        OIDCProviderTO, OIDCProviderTO, OIDCProvidersProvider, OIDCProviderRestClient> {
+        OIDCC4UIProviderTO, OIDCC4UIProviderTO, OIDCProvidersProvider, OIDCProviderRestClient> {
 
     private static final long serialVersionUID = -1356497878858616714L;
 
@@ -75,19 +75,20 @@ public class OIDCProvidersDirectoryPanel extends DirectoryPanel<
     private final BaseModal<Serializable> templateModal;
 
     public OIDCProvidersDirectoryPanel(final String id, final PageReference pageRef) {
-        super(id, new Builder<OIDCProviderTO, OIDCProviderTO, OIDCProviderRestClient>(new OIDCProviderRestClient(),
-                pageRef) {
+        super(id, new Builder<OIDCC4UIProviderTO, OIDCC4UIProviderTO, OIDCProviderRestClient>(
+                new OIDCProviderRestClient(), pageRef) {
 
             private static final long serialVersionUID = -5542535388772406165L;
 
             @Override
-            protected WizardMgtPanel<OIDCProviderTO> newInstance(final String id, final boolean wizardInModal) {
+            protected WizardMgtPanel<OIDCC4UIProviderTO> newInstance(final String id,
+                    final boolean wizardInModal) {
                 throw new UnsupportedOperationException();
             }
         }.disableCheckBoxes());
 
-        this.addNewItemPanelBuilder(new OIDCProviderWizardBuilder(this, new OIDCProviderTO(), pageRef), true);
-        MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, OIDCClientEntitlement.OP_CREATE);
+        this.addNewItemPanelBuilder(new OIDCProviderWizardBuilder(this, new OIDCC4UIProviderTO(), pageRef), true);
+        MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, OIDC4UIEntitlement.OP_CREATE);
 
         modal.size(Modal.Size.Large);
 
@@ -123,16 +124,16 @@ public class OIDCProvidersDirectoryPanel extends DirectoryPanel<
     }
 
     @Override
-    protected ActionLinksTogglePanel<OIDCProviderTO> actionTogglePanel() {
-        return new ActionLinksTogglePanel<OIDCProviderTO>(Constants.OUTER, pageRef) {
+    protected ActionLinksTogglePanel<OIDCC4UIProviderTO> actionTogglePanel() {
+        return new ActionLinksTogglePanel<OIDCC4UIProviderTO>(Constants.OUTER, pageRef) {
 
             private static final long serialVersionUID = -7688359318035249200L;
 
             @Override
             public void updateHeader(final AjaxRequestTarget target, final Serializable object) {
-                if (object instanceof OIDCProviderTO) {
+                if (object instanceof OIDCC4UIProviderTO) {
                     setHeader(target,
-                            StringUtils.abbreviate(((OIDCProviderTO) object).getName(), HEADER_FIRST_ABBREVIATION));
+                            StringUtils.abbreviate(((OIDCC4UIProviderTO) object).getName(), HEADER_FIRST_ABBREVIATION));
                 } else {
                     super.updateHeader(target, object);
                 }
@@ -147,8 +148,8 @@ public class OIDCProvidersDirectoryPanel extends DirectoryPanel<
     }
 
     @Override
-    protected List<IColumn<OIDCProviderTO, String>> getColumns() {
-        List<IColumn<OIDCProviderTO, String>> columns = new ArrayList<>();
+    protected List<IColumn<OIDCC4UIProviderTO, String>> getColumns() {
+        List<IColumn<OIDCC4UIProviderTO, String>> columns = new ArrayList<>();
         columns.add(new KeyPropertyColumn<>(new ResourceModel("key"), "key", "key"));
         columns.add(new PropertyColumn<>(new ResourceModel("name"), "name", "name"));
         columns.add(new PropertyColumn<>(new ResourceModel("issuer"), "issuer", "issuer"));
@@ -163,29 +164,29 @@ public class OIDCProvidersDirectoryPanel extends DirectoryPanel<
     }
 
     @Override
-    public ActionsPanel<OIDCProviderTO> getActions(final IModel<OIDCProviderTO> model) {
-        final ActionsPanel<OIDCProviderTO> panel = super.getActions(model);
+    public ActionsPanel<OIDCC4UIProviderTO> getActions(final IModel<OIDCC4UIProviderTO> model) {
+        final ActionsPanel<OIDCC4UIProviderTO> panel = super.getActions(model);
 
-        panel.add(new ActionLink<OIDCProviderTO>() {
+        panel.add(new ActionLink<OIDCC4UIProviderTO>() {
 
             private static final long serialVersionUID = -3722207913631435501L;
 
             @Override
-            public void onClick(final AjaxRequestTarget target, final OIDCProviderTO ignore) {
-                OIDCProviderTO object = OIDCProviderRestClient.read(model.getObject().getKey());
+            public void onClick(final AjaxRequestTarget target, final OIDCC4UIProviderTO ignore) {
+                OIDCC4UIProviderTO object = OIDCProviderRestClient.read(model.getObject().getKey());
                 send(OIDCProvidersDirectoryPanel.this, Broadcast.EXACT,
                         new AjaxWizard.EditItemActionEvent<>(object, target));
                 modal.header(Model.of(StringUtils.capitalize(("Edit " + object.getName()))));
             }
-        }, ActionLink.ActionType.EDIT, OIDCClientEntitlement.OP_UPDATE);
+        }, ActionLink.ActionType.EDIT, OIDC4UIEntitlement.OP_UPDATE);
 
-        panel.add(new ActionLink<OIDCProviderTO>() {
+        panel.add(new ActionLink<OIDCC4UIProviderTO>() {
 
             private static final long serialVersionUID = 8557679125857348178L;
 
             @Override
-            public void onClick(final AjaxRequestTarget target, final OIDCProviderTO ignore) {
-                final OIDCProviderTO object = OIDCProviderRestClient.read(model.getObject().getKey());
+            public void onClick(final AjaxRequestTarget target, final OIDCC4UIProviderTO ignore) {
+                final OIDCC4UIProviderTO object = OIDCProviderRestClient.read(model.getObject().getKey());
 
                 UserTemplateWizardBuilder builder = new UserTemplateWizardBuilder(
                         object.getUserTemplate(),
@@ -210,14 +211,14 @@ public class OIDCProvidersDirectoryPanel extends DirectoryPanel<
                 target.add(templateModal);
 
             }
-        }, ActionLink.ActionType.TEMPLATE, OIDCClientEntitlement.OP_UPDATE);
+        }, ActionLink.ActionType.TEMPLATE, OIDC4UIEntitlement.OP_UPDATE);
 
-        panel.add(new ActionLink<OIDCProviderTO>() {
+        panel.add(new ActionLink<OIDCC4UIProviderTO>() {
 
             private static final long serialVersionUID = -5467832321897812767L;
 
             @Override
-            public void onClick(final AjaxRequestTarget target, final OIDCProviderTO ignore) {
+            public void onClick(final AjaxRequestTarget target, final OIDCC4UIProviderTO ignore) {
                 try {
                     OIDCProviderRestClient.delete(model.getObject().getKey());
                     SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
@@ -228,7 +229,7 @@ public class OIDCProvidersDirectoryPanel extends DirectoryPanel<
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
-        }, ActionLink.ActionType.DELETE, OIDCClientEntitlement.OP_DELETE, true);
+        }, ActionLink.ActionType.DELETE, OIDC4UIEntitlement.OP_DELETE, true);
         return panel;
     }
 
@@ -254,11 +255,11 @@ public class OIDCProvidersDirectoryPanel extends DirectoryPanel<
         }
     }
 
-    protected static final class OIDCProvidersProvider extends DirectoryDataProvider<OIDCProviderTO> {
+    protected static final class OIDCProvidersProvider extends DirectoryDataProvider<OIDCC4UIProviderTO> {
 
         private static final long serialVersionUID = -2865055116864423761L;
 
-        private final SortableDataProviderComparator<OIDCProviderTO> comparator;
+        private final SortableDataProviderComparator<OIDCC4UIProviderTO> comparator;
 
         public OIDCProvidersProvider(final int paginatorRows) {
             super(paginatorRows);
@@ -268,8 +269,8 @@ public class OIDCProvidersDirectoryPanel extends DirectoryPanel<
         }
 
         @Override
-        public Iterator<OIDCProviderTO> iterator(final long first, final long count) {
-            List<OIDCProviderTO> list = OIDCProviderRestClient.list();
+        public Iterator<OIDCC4UIProviderTO> iterator(final long first, final long count) {
+            List<OIDCC4UIProviderTO> list = OIDCProviderRestClient.list();
             list.sort(comparator);
             return list.subList((int) first, (int) first + (int) count).iterator();
         }
@@ -280,7 +281,7 @@ public class OIDCProvidersDirectoryPanel extends DirectoryPanel<
         }
 
         @Override
-        public IModel<OIDCProviderTO> model(final OIDCProviderTO object) {
+        public IModel<OIDCC4UIProviderTO> model(final OIDCC4UIProviderTO object) {
             return new CompoundPropertyModel<>(object);
         }
     }
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCSSOLoginFormPanel.java b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCSSOLoginFormPanel.java
similarity index 93%
rename from ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCSSOLoginFormPanel.java
rename to ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCSSOLoginFormPanel.java
index a8323f4..85d4647 100644
--- a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCSSOLoginFormPanel.java
+++ b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCSSOLoginFormPanel.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.client.console.panels;
 
-import org.apache.syncope.client.common.ui.panels.AbstractOIDCSSOLoginFormPanel;
+import org.apache.syncope.client.ui.commons.panels.AbstractOIDCSSOLoginFormPanel;
 import org.apache.syncope.client.ui.commons.BaseSession;
 
 public class OIDCSSOLoginFormPanel extends AbstractOIDCSSOLoginFormPanel {
@@ -28,5 +28,4 @@ public class OIDCSSOLoginFormPanel extends AbstractOIDCSSOLoginFormPanel {
     public OIDCSSOLoginFormPanel(final String id, final BaseSession session) {
         super(id, session);
     }
-
 }
diff --git a/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/resources/ConsoleCodeConsumerResource.java b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/resources/ConsoleCodeConsumerResource.java
new file mode 100644
index 0000000..3638cdc
--- /dev/null
+++ b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/resources/ConsoleCodeConsumerResource.java
@@ -0,0 +1,43 @@
+/*
+ * 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.client.console.resources;
+
+import org.apache.syncope.client.console.pages.OIDCClientLogin;
+import org.apache.syncope.client.ui.commons.annotations.Resource;
+import org.apache.syncope.client.ui.commons.panels.OIDCC4UIConstants;
+import org.apache.syncope.client.ui.commons.resources.oidcc4ui.CodeConsumerResource;
+import org.apache.wicket.markup.html.WebPage;
+
+@Resource(
+        key = OIDCC4UIConstants.URL_CONTEXT + ".codeConsumer",
+        path = "/" + OIDCC4UIConstants.URL_CONTEXT + "/code-consumer")
+public class ConsoleCodeConsumerResource extends CodeConsumerResource {
+
+    private static final long serialVersionUID = 8348262380011763032L;
+
+    @Override
+    protected Class<? extends WebPage> getLoginPageClass() {
+        return OIDCClientLogin.class;
+    }
+
+    @Override
+    protected Class<? extends WebPage> getSelfRegPageClass() {
+        throw new UnsupportedOperationException("Self-registration not supported by Admin Console");
+    }
+}
diff --git a/ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogout.java b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/resources/ConsoleLogoutResource.java
similarity index 55%
copy from ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogout.java
copy to ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/resources/ConsoleLogoutResource.java
index 2cb8c7a..7116f88 100644
--- a/ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogout.java
+++ b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/resources/ConsoleLogoutResource.java
@@ -16,23 +16,23 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.client.enduser.pages;
+package org.apache.syncope.client.console.resources;
 
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
+import org.apache.syncope.client.console.pages.OIDCClientLogout;
+import org.apache.syncope.client.ui.commons.annotations.Resource;
+import org.apache.syncope.client.ui.commons.panels.OIDCC4UIConstants;
+import org.apache.syncope.client.ui.commons.resources.oidcc4ui.LogoutResource;
 import org.apache.wicket.markup.html.WebPage;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
 
-public class OIDCClientLogout extends WebPage {
+@Resource(
+        key = OIDCC4UIConstants.URL_CONTEXT + ".logout",
+        path = "/" + OIDCC4UIConstants.URL_CONTEXT + "/logout")
+public class ConsoleLogoutResource extends LogoutResource {
 
-    private static final long serialVersionUID = -1453838909720946011L;
+    private static final long serialVersionUID = -4250716706885039749L;
 
-    public OIDCClientLogout(final PageParameters parameters) {
-        super(parameters);
-
-        SyncopeEnduserSession.get().cleanup();
-
-        SyncopeEnduserSession.get().invalidate();
-
-        setResponsePage(getApplication().getHomePage());
+    @Override
+    protected Class<? extends WebPage> getLogoutPageClass() {
+        return OIDCClientLogout.class;
     }
 }
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/rest/OIDCProviderRestClient.java b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/rest/OIDCProviderRestClient.java
similarity index 56%
rename from ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/rest/OIDCProviderRestClient.java
rename to ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/rest/OIDCProviderRestClient.java
index c2feba7..ca9aa1c 100644
--- a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/rest/OIDCProviderRestClient.java
+++ b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/rest/OIDCProviderRestClient.java
@@ -20,34 +20,34 @@ package org.apache.syncope.client.console.rest;
 
 import java.util.List;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.common.lib.to.OIDCProviderTO;
-import org.apache.syncope.common.rest.api.service.OIDCProviderService;
+import org.apache.syncope.common.lib.to.OIDCC4UIProviderTO;
+import org.apache.syncope.common.rest.api.service.OIDCC4UIProviderService;
 
 public class OIDCProviderRestClient extends BaseRestClient {
 
     private static final long serialVersionUID = -4006712447589576324L;
 
-    public static List<OIDCProviderTO> list() {
-        return getService(OIDCProviderService.class).list();
+    public static List<OIDCC4UIProviderTO> list() {
+        return getService(OIDCC4UIProviderService.class).list();
     }
 
-    public static void create(final OIDCProviderTO op) {
-        SyncopeConsoleSession.get().getService(OIDCProviderService.class).create(op);
+    public static void create(final OIDCC4UIProviderTO op) {
+        SyncopeConsoleSession.get().getService(OIDCC4UIProviderService.class).create(op);
     }
 
-    public static void createFromDiscovery(final OIDCProviderTO op) {
-        SyncopeConsoleSession.get().getService(OIDCProviderService.class).createFromDiscovery(op);
+    public static void createFromDiscovery(final OIDCC4UIProviderTO op) {
+        SyncopeConsoleSession.get().getService(OIDCC4UIProviderService.class).createFromDiscovery(op);
     }
 
-    public static OIDCProviderTO read(final String key) {
-        return getService(OIDCProviderService.class).read(key);
+    public static OIDCC4UIProviderTO read(final String key) {
+        return getService(OIDCC4UIProviderService.class).read(key);
     }
 
-    public static void update(final OIDCProviderTO op) {
-        getService(OIDCProviderService.class).update(op);
+    public static void update(final OIDCC4UIProviderTO op) {
+        getService(OIDCC4UIProviderService.class).update(op);
     }
 
     public static void delete(final String key) {
-        getService(OIDCProviderService.class).delete(key);
+        getService(OIDCC4UIProviderService.class).delete(key);
     }
 }
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder.java b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder.java
similarity index 95%
rename from ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder.java
rename to ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder.java
index dbccdd5..128aaa4 100644
--- a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder.java
+++ b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder.java
@@ -40,7 +40,7 @@ import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPalettePanel;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.ui.commons.wizards.AjaxWizardBuilder;
 import org.apache.syncope.common.lib.to.EntityTO;
-import org.apache.syncope.common.lib.to.OIDCProviderTO;
+import org.apache.syncope.common.lib.to.OIDCC4UIProviderTO;
 import org.apache.syncope.common.lib.types.OIDCClientImplementationType;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -55,7 +55,7 @@ import org.apache.wicket.model.StringResourceModel;
 import org.apache.wicket.model.util.ListModel;
 import org.apache.wicket.validation.validator.UrlValidator;
 
-public class OIDCProviderWizardBuilder extends AjaxWizardBuilder<OIDCProviderTO> {
+public class OIDCProviderWizardBuilder extends AjaxWizardBuilder<OIDCC4UIProviderTO> {
 
     private static final long serialVersionUID = -3310772400714122768L;
 
@@ -72,14 +72,17 @@ public class OIDCProviderWizardBuilder extends AjaxWizardBuilder<OIDCProviderTO>
         }
     };
 
-    public OIDCProviderWizardBuilder(final OIDCProvidersDirectoryPanel directoryPanel, final OIDCProviderTO defaultItem,
+    public OIDCProviderWizardBuilder(
+            final OIDCProvidersDirectoryPanel directoryPanel,
+            final OIDCC4UIProviderTO defaultItem,
             final PageReference pageRef) {
+
         super(defaultItem, pageRef);
         this.directoryPanel = directoryPanel;
     }
 
     @Override
-    protected Serializable onApplyInternal(final OIDCProviderTO modelObject) {
+    protected Serializable onApplyInternal(final OIDCC4UIProviderTO modelObject) {
         if (modelObject.getKey() == null) {
             if (modelObject.getHasDiscovery()) {
                 OIDCProviderRestClient.createFromDiscovery(modelObject);
@@ -94,7 +97,7 @@ public class OIDCProviderWizardBuilder extends AjaxWizardBuilder<OIDCProviderTO>
     }
 
     @Override
-    protected WizardModel buildModelSteps(final OIDCProviderTO modelObject, final WizardModel wizardModel) {
+    protected WizardModel buildModelSteps(final OIDCC4UIProviderTO modelObject, final WizardModel wizardModel) {
         wizardModel.add(new OP(modelObject));
         if (modelObject.getKey() == null) {
             wizardModel.add(new OPContinue(modelObject));
@@ -141,7 +144,7 @@ public class OIDCProviderWizardBuilder extends AjaxWizardBuilder<OIDCProviderTO>
 
         private static final long serialVersionUID = 7127421283216134900L;
 
-        public OP(final OIDCProviderTO opTO) {
+        public OP(final OIDCC4UIProviderTO opTO) {
             AjaxTextFieldPanel name = new AjaxTextFieldPanel(
                     "name", "name", new PropertyModel<>(opTO, "name"), false);
             name.addRequiredLabel();
@@ -189,7 +192,7 @@ public class OIDCProviderWizardBuilder extends AjaxWizardBuilder<OIDCProviderTO>
 
         private static final long serialVersionUID = -7087008312629522790L;
 
-        public OPContinue(final OIDCProviderTO opTO) {
+        public OPContinue(final OIDCC4UIProviderTO opTO) {
             final WebMarkupContainer content = new WebMarkupContainer("content");
             this.setOutputMarkupId(true);
             content.setOutputMarkupId(true);
@@ -257,7 +260,7 @@ public class OIDCProviderWizardBuilder extends AjaxWizardBuilder<OIDCProviderTO>
             });
         }
 
-        public OPContinue(final OIDCProviderTO opTO, final boolean readOnly) {
+        public OPContinue(final OIDCC4UIProviderTO opTO, final boolean readOnly) {
             WebMarkupContainer content = new WebMarkupContainer("content");
             this.setOutputMarkupId(true);
             content.setOutputMarkupId(true);
@@ -324,7 +327,7 @@ public class OIDCProviderWizardBuilder extends AjaxWizardBuilder<OIDCProviderTO>
 
         private static final long serialVersionUID = 3454904947720856253L;
 
-        Mapping(final OIDCProviderTO item) {
+        Mapping(final OIDCC4UIProviderTO item) {
             setTitleModel(Model.of("Mapping"));
             setSummaryModel(Model.of(StringUtils.EMPTY));
         }
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/OIDCProviderMappingPanel.java b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/OIDCProviderMappingPanel.java
similarity index 97%
rename from ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/OIDCProviderMappingPanel.java
rename to ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/OIDCProviderMappingPanel.java
index db9632d..2a5116c 100644
--- a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/OIDCProviderMappingPanel.java
+++ b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/OIDCProviderMappingPanel.java
@@ -26,7 +26,7 @@ import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.common.lib.to.ItemTO;
-import org.apache.syncope.common.lib.to.OIDCProviderTO;
+import org.apache.syncope.common.lib.to.OIDCC4UIProviderTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.wicket.model.IModel;
@@ -39,7 +39,7 @@ public class OIDCProviderMappingPanel extends AbstractMappingPanel {
 
     public OIDCProviderMappingPanel(
             final String id,
-            final OIDCProviderTO opTO,
+            final OIDCC4UIProviderTO opTO,
             final ItemTransformersTogglePanel mapItemTransformers,
             final JEXLTransformersTogglePanel jexlTransformers) {
 
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCClient.html b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCC4UI.html
similarity index 95%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCClient.html
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCC4UI.html
index d243d8a..b076c13 100644
--- a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCClient.html
+++ b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCC4UI.html
@@ -31,7 +31,7 @@ under the License.
                 <a wicket:id="dashboardBr"><i class="fa fa-tachometer-alt"></i> <wicket:message key="dashboard"></wicket:message></a>
               </li>
               <li class="breadcrumb-item"><wicket:message key="extensions"/></li>
-              <li class="breadcrumb-item active">OIDC Client</li>
+              <li class="breadcrumb-item active">OpenID Connect 1.0 C4UI</li>
             </ol>
           </div>
         </div>
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCClient_ru.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCC4UI_it.properties
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCClient_ru.properties
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCC4UI_it.properties
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCClient_pt_BR.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCC4UI_ru.properties
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCClient_pt_BR.properties
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCC4UI_ru.properties
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCClient.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCClient.properties
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCClient.properties
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCClient.properties
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.html b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.html
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.html
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.html
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.properties
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.properties
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.properties
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel_it.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel_it.properties
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel_it.properties
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel_it.properties
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel_pt_BR.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel_pt_BR.properties
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel_pt_BR.properties
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel_pt_BR.properties
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel_ru.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel_ru.properties
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel_ru.properties
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel_ru.properties
diff --git a/ext/oidcclient/client-enduser/src/main/resources/org/apache/syncope/client/enduser/panels/OIDCSSOLoginFormPanel.html b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCSSOLoginFormPanel.html
similarity index 100%
rename from ext/oidcclient/client-enduser/src/main/resources/org/apache/syncope/client/enduser/panels/OIDCSSOLoginFormPanel.html
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCSSOLoginFormPanel.html
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$Mapping.html b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$Mapping.html
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$Mapping.html
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$Mapping.html
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP.html b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP.html
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP.html
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP.html
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP.properties
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP.properties
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP.properties
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue.html b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue.html
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue.html
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue.html
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue.properties
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue.properties
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue.properties
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue_it.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue_it.properties
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue_it.properties
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue_it.properties
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue_pt_BR.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue_pt_BR.properties
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue_pt_BR.properties
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue_pt_BR.properties
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue_ru.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue_ru.properties
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue_ru.properties
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OPContinue_ru.properties
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP_it.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP_it.properties
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP_it.properties
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP_it.properties
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP_pt_BR.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP_pt_BR.properties
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP_pt_BR.properties
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP_pt_BR.properties
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP_ru.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP_ru.properties
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP_ru.properties
rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder$OP_ru.properties
diff --git a/ext/oidcclient/client-enduser/pom.xml b/ext/oidcc4ui/client-enduser/pom.xml
similarity index 76%
rename from ext/oidcclient/client-enduser/pom.xml
rename to ext/oidcc4ui/client-enduser/pom.xml
index 347a253..61334fe 100644
--- a/ext/oidcclient/client-enduser/pom.xml
+++ b/ext/oidcc4ui/client-enduser/pom.xml
@@ -23,14 +23,14 @@ under the License.
 
   <parent>
     <groupId>org.apache.syncope.ext</groupId>
-    <artifactId>syncope-ext-oidcclient</artifactId>
+    <artifactId>syncope-ext-oidcc4ui</artifactId>
     <version>3.0.0-SNAPSHOT</version>
   </parent>
 
-  <name>Apache Syncope Ext: OIDC Client Enduser</name>
-  <description>Apache Syncope Ext: OIDC Client Enduser</description>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-client-enduser</artifactId>
+  <name>Apache Syncope Ext: OIDC C4UI Enduser</name>
+  <description>Apache Syncope Ext: OIDC C4UI Enduser</description>
+  <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+  <artifactId>syncope-ext-oidcc4ui-client-enduser</artifactId>
   <packaging>jar</packaging>
   
   <properties>
@@ -44,19 +44,14 @@ under the License.
     </dependency>
 
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-agent</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
       <groupId>org.apache.syncope.client.idrepo</groupId>
       <artifactId>syncope-client-idrepo-enduser</artifactId>
       <version>${project.version}</version>
     </dependency>
     
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-client-common-ui</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-client-common-ui</artifactId>
       <version>${project.version}</version>
     </dependency>
   </dependencies>
diff --git a/ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientBeforeLogout.java b/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientBeforeLogout.java
similarity index 86%
rename from ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientBeforeLogout.java
rename to ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientBeforeLogout.java
index fd22b0e..5989fde 100644
--- a/ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientBeforeLogout.java
+++ b/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientBeforeLogout.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.enduser.pages;
 
+import org.apache.syncope.client.ui.commons.panels.OIDCC4UIConstants;
 import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.request.UrlUtils;
 import org.apache.wicket.request.cycle.RequestCycle;
@@ -31,6 +32,7 @@ public class OIDCClientBeforeLogout extends WebPage {
         super();
 
         RequestCycle.get().scheduleRequestHandlerAfterCurrent(new RedirectRequestHandler(
-                UrlUtils.rewriteToContextRelative("oidcclient/beforelogout", RequestCycle.get())));
+                UrlUtils.rewriteToContextRelative(OIDCC4UIConstants.URL_CONTEXT + "/before-logout",
+                        RequestCycle.get())));
     }
 }
diff --git a/ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogin.java b/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogin.java
similarity index 89%
rename from ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogin.java
rename to ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogin.java
index 8af5551..5096ec1 100644
--- a/ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogin.java
+++ b/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogin.java
@@ -21,9 +21,9 @@ package org.apache.syncope.client.enduser.pages;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.ui.commons.panels.OIDCC4UIConstants;
 import org.apache.wicket.authentication.IAuthenticationStrategy;
 import org.apache.wicket.markup.html.WebPage;
-import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -39,8 +39,7 @@ public class OIDCClientLogin extends WebPage {
     public OIDCClientLogin(final PageParameters parameters) {
         super(parameters);
 
-        String token = (String) ((ServletWebRequest) getRequest()).getContainerRequest().
-                getSession().getAttribute(org.apache.syncope.ext.oidcclient.agent.Constants.OIDCCLIENTJWT);
+        String token = parameters.get(OIDCC4UIConstants.OIDCC4UI_JWT).toOptionalString();
         if (StringUtils.isBlank(token)) {
             LOG.error("No JWT found, redirecting to default greeter");
 
@@ -52,7 +51,7 @@ public class OIDCClientLogin extends WebPage {
         IAuthenticationStrategy strategy = getApplication().getSecuritySettings().getAuthenticationStrategy();
 
         if (SyncopeEnduserSession.get().authenticate(token)) {
-            if (parameters.get("logoutSupported").toBoolean(false)) {
+            if (parameters.get(OIDCC4UIConstants.OIDCC4UI_SLO_SUPPORTED).toBoolean(false)) {
                 SyncopeEnduserSession.get().setAttribute(Constants.BEFORE_LOGOUT_PAGE, OIDCClientBeforeLogout.class);
             }
 
@@ -67,5 +66,4 @@ public class OIDCClientLogin extends WebPage {
         }
         strategy.remove();
     }
-
 }
diff --git a/ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogout.java b/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogout.java
similarity index 88%
copy from ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogout.java
copy to ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogout.java
index 2cb8c7a..e998e8e 100644
--- a/ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogout.java
+++ b/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogout.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.client.enduser.pages;
 
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
@@ -29,10 +28,6 @@ public class OIDCClientLogout extends WebPage {
     public OIDCClientLogout(final PageParameters parameters) {
         super(parameters);
 
-        SyncopeEnduserSession.get().cleanup();
-
-        SyncopeEnduserSession.get().invalidate();
-
         setResponsePage(getApplication().getHomePage());
     }
 }
diff --git a/ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientSelfReg.java b/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientSelfReg.java
similarity index 89%
rename from ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientSelfReg.java
rename to ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientSelfReg.java
index babf60d..8270e99 100644
--- a/ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientSelfReg.java
+++ b/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientSelfReg.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.client.enduser.pages;
 
-import org.apache.syncope.ext.oidcclient.agent.Constants;
+import org.apache.syncope.client.ui.commons.panels.OIDCC4UIConstants;
 import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
@@ -36,10 +36,9 @@ public class OIDCClientSelfReg extends WebPage {
 
         PageParameters params = new PageParameters();
         try {
-            params.add(
-                    Self.NEW_USER_PARAM,
+            params.add(Self.NEW_USER_PARAM,
                     ((ServletWebRequest) getRequest()).getContainerRequest().
-                            getSession().getAttribute(Constants.OIDCC4UI_NEW_USER));
+                            getSession().getAttribute(OIDCC4UIConstants.OIDCC4UI_NEW_USER));
         } catch (Exception e) {
             LOG.error("While getting user data from social registration", e);
 
diff --git a/ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/panels/OIDCSSOLoginFormPanel.java b/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/panels/OIDCSSOLoginFormPanel.java
similarity index 93%
rename from ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/panels/OIDCSSOLoginFormPanel.java
rename to ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/panels/OIDCSSOLoginFormPanel.java
index 72f34e7..ca89994 100644
--- a/ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/panels/OIDCSSOLoginFormPanel.java
+++ b/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/panels/OIDCSSOLoginFormPanel.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.client.enduser.panels;
 
-import org.apache.syncope.client.common.ui.panels.AbstractOIDCSSOLoginFormPanel;
+import org.apache.syncope.client.ui.commons.panels.AbstractOIDCSSOLoginFormPanel;
 import org.apache.syncope.client.ui.commons.BaseSession;
 
 public class OIDCSSOLoginFormPanel extends AbstractOIDCSSOLoginFormPanel {
@@ -28,5 +28,4 @@ public class OIDCSSOLoginFormPanel extends AbstractOIDCSSOLoginFormPanel {
     public OIDCSSOLoginFormPanel(final String id, final BaseSession session) {
         super(id, session);
     }
-
 }
diff --git a/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/resources/EnduserCodeConsumerResource.java b/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/resources/EnduserCodeConsumerResource.java
new file mode 100644
index 0000000..d83940d
--- /dev/null
+++ b/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/resources/EnduserCodeConsumerResource.java
@@ -0,0 +1,44 @@
+/*
+ * 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.client.enduser.resources;
+
+import org.apache.syncope.client.enduser.pages.OIDCClientLogin;
+import org.apache.syncope.client.enduser.pages.Self;
+import org.apache.syncope.client.ui.commons.annotations.Resource;
+import org.apache.syncope.client.ui.commons.panels.OIDCC4UIConstants;
+import org.apache.syncope.client.ui.commons.resources.oidcc4ui.CodeConsumerResource;
+import org.apache.wicket.markup.html.WebPage;
+
+@Resource(
+        key = OIDCC4UIConstants.URL_CONTEXT + ".codeConsumer",
+        path = "/" + OIDCC4UIConstants.URL_CONTEXT + "/code-consumer")
+public class EnduserCodeConsumerResource extends CodeConsumerResource {
+
+    private static final long serialVersionUID = 8348262380011763032L;
+
+    @Override
+    protected Class<? extends WebPage> getLoginPageClass() {
+        return OIDCClientLogin.class;
+    }
+
+    @Override
+    protected Class<? extends WebPage> getSelfRegPageClass() {
+        return Self.class;
+    }
+}
diff --git a/ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogout.java b/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/resources/EnduserLogoutResource.java
similarity index 55%
rename from ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogout.java
rename to ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/resources/EnduserLogoutResource.java
index 2cb8c7a..8ef3bec 100644
--- a/ext/oidcclient/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogout.java
+++ b/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/resources/EnduserLogoutResource.java
@@ -16,23 +16,23 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.client.enduser.pages;
+package org.apache.syncope.client.enduser.resources;
 
-import org.apache.syncope.client.enduser.SyncopeEnduserSession;
+import org.apache.syncope.client.enduser.pages.OIDCClientLogout;
+import org.apache.syncope.client.ui.commons.annotations.Resource;
+import org.apache.syncope.client.ui.commons.panels.OIDCC4UIConstants;
+import org.apache.syncope.client.ui.commons.resources.oidcc4ui.LogoutResource;
 import org.apache.wicket.markup.html.WebPage;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
 
-public class OIDCClientLogout extends WebPage {
+@Resource(
+        key = OIDCC4UIConstants.URL_CONTEXT + ".logout",
+        path = "/" + OIDCC4UIConstants.URL_CONTEXT + "/logout")
+public class EnduserLogoutResource extends LogoutResource {
 
-    private static final long serialVersionUID = -1453838909720946011L;
+    private static final long serialVersionUID = -4250716706885039749L;
 
-    public OIDCClientLogout(final PageParameters parameters) {
-        super(parameters);
-
-        SyncopeEnduserSession.get().cleanup();
-
-        SyncopeEnduserSession.get().invalidate();
-
-        setResponsePage(getApplication().getHomePage());
+    @Override
+    protected Class<? extends WebPage> getLogoutPageClass() {
+        return OIDCClientLogout.class;
     }
 }
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCSSOLoginFormPanel.html b/ext/oidcc4ui/client-enduser/src/main/resources/org/apache/syncope/client/enduser/panels/OIDCSSOLoginFormPanel.html
similarity index 100%
rename from ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/panels/OIDCSSOLoginFormPanel.html
rename to ext/oidcc4ui/client-enduser/src/main/resources/org/apache/syncope/client/enduser/panels/OIDCSSOLoginFormPanel.html
diff --git a/ext/oidcclient/common-lib/pom.xml b/ext/oidcc4ui/common-lib/pom.xml
similarity index 79%
rename from ext/oidcclient/common-lib/pom.xml
rename to ext/oidcc4ui/common-lib/pom.xml
index 6486094..d85ec7b 100644
--- a/ext/oidcclient/common-lib/pom.xml
+++ b/ext/oidcc4ui/common-lib/pom.xml
@@ -23,14 +23,14 @@ under the License.
 
   <parent>
     <groupId>org.apache.syncope.ext</groupId>
-    <artifactId>syncope-ext-oidcclient</artifactId>
+    <artifactId>syncope-ext-oidcc4ui</artifactId>
     <version>3.0.0-SNAPSHOT</version>
   </parent>
 
-  <name>Apache Syncope Ext: OIDC Client Common Lib</name>
-  <description>Apache Syncope Ext: OIDC Client Common Lib</description>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-common-lib</artifactId>
+  <name>Apache Syncope Ext: OIDC C4UI Common Lib</name>
+  <description>Apache Syncope Ext: OIDC C4UI Common Lib</description>
+  <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+  <artifactId>syncope-ext-oidcc4ui-common-lib</artifactId>
   <packaging>jar</packaging>
   
   <properties>
@@ -39,8 +39,8 @@ under the License.
 
   <dependencies>
     <dependency>
-      <groupId>org.apache.syncope.common.idm</groupId>
-      <artifactId>syncope-common-idm-lib</artifactId>
+      <groupId>org.apache.syncope.common.am</groupId>
+      <artifactId>syncope-common-am-lib</artifactId>
       <version>${project.version}</version>
     </dependency>
   </dependencies>
diff --git a/ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/OIDCConstants.java b/ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/oidc/OIDCConstants.java
similarity index 72%
rename from ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/OIDCConstants.java
rename to ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/oidc/OIDCConstants.java
index 78b00b6..7096ae1 100644
--- a/ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/OIDCConstants.java
+++ b/ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/oidc/OIDCConstants.java
@@ -16,22 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.common.lib;
+package org.apache.syncope.common.lib.oidc;
 
 public final class OIDCConstants {
 
-    public static final String CLIENT_ID = "client_id";
-
-    public static final String CLIENT_SECRET = "client_secret";
-
-    public static final String SCOPE = "scope";
-
-    public static final String RESPONSE_TYPE = "response_type";
-
-    public static final String STATE = "state";
-    
-    public static final String POST_LOGOUT_REDIRECT_URI = "post_logout_redirect_uri";
-
     public static final String REDIRECT_URI = "redirect_uri";
 
     public static final String CODE = "code";
@@ -41,5 +29,4 @@ public final class OIDCConstants {
     private OIDCConstants() {
         // private constructor for static utility class
     }
-
 }
diff --git a/ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/to/OIDCLoginResponseTO.java b/ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/oidc/OIDCLoginResponse.java
similarity index 96%
rename from ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/to/OIDCLoginResponseTO.java
rename to ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/oidc/OIDCLoginResponse.java
index 40b86f8..c21fb86 100644
--- a/ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/to/OIDCLoginResponseTO.java
+++ b/ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/oidc/OIDCLoginResponse.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.common.lib.to;
+package org.apache.syncope.common.lib.oidc;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
@@ -28,7 +28,7 @@ import java.util.Optional;
 import java.util.Set;
 import org.apache.syncope.common.lib.Attr;
 
-public class OIDCLoginResponseTO implements Serializable {
+public class OIDCLoginResponse implements Serializable {
 
     private static final long serialVersionUID = -5971442076182154492L;
 
diff --git a/ext/oidcclient/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/OIDCProviderDataBinder.java b/ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/oidc/OIDCRequest.java
similarity index 68%
copy from ext/oidcclient/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/OIDCProviderDataBinder.java
copy to ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/oidc/OIDCRequest.java
index acea05d..a0333f2 100644
--- a/ext/oidcclient/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/OIDCProviderDataBinder.java
+++ b/ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/oidc/OIDCRequest.java
@@ -16,17 +16,21 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.core.provisioning.api.data;
+package org.apache.syncope.common.lib.oidc;
 
-import org.apache.syncope.common.lib.to.OIDCProviderTO;
-import org.apache.syncope.core.persistence.api.entity.OIDCProvider;
+import java.io.Serializable;
 
-public interface OIDCProviderDataBinder {
+public class OIDCRequest implements Serializable {
 
-    OIDCProvider create(OIDCProviderTO op);
+    private static final long serialVersionUID = -3509031322459942441L;
 
-    OIDCProvider update(OIDCProvider op, OIDCProviderTO opTO);
+    private String location;
 
-    OIDCProviderTO getOIDCProviderTO(OIDCProvider op);
+    public String getLocation() {
+        return location;
+    }
 
+    public void setLocation(final String location) {
+        this.location = location;
+    }
 }
diff --git a/ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/to/OIDCProviderTO.java b/ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/to/OIDCC4UIProviderTO.java
similarity index 93%
rename from ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/to/OIDCProviderTO.java
rename to ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/to/OIDCC4UIProviderTO.java
index 76da99b..f03eda7 100644
--- a/ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/to/OIDCProviderTO.java
+++ b/ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/to/OIDCC4UIProviderTO.java
@@ -25,7 +25,7 @@ import java.util.List;
 import java.util.Optional;
 import javax.ws.rs.PathParam;
 
-public class OIDCProviderTO implements EntityTO, ItemContainerTO {
+public class OIDCC4UIProviderTO implements EntityTO, ItemContainerTO {
 
     private static final long serialVersionUID = -1229802774546135794L;
 
@@ -200,8 +200,8 @@ public class OIDCProviderTO implements EntityTO, ItemContainerTO {
 
     @Override
     public boolean setConnObjectKeyItem(final ItemTO connObjectKeyItem) {
-        return Optional.ofNullable(connObjectKeyItem)
-                .map(this::addConnObjectKeyItem).orElseGet(() -> remove(getConnObjectKeyItem()));
+        return Optional.ofNullable(connObjectKeyItem).
+                map(this::addConnObjectKeyItem).orElseGet(() -> remove(getConnObjectKeyItem()));
     }
 
     @JacksonXmlElementWrapper(localName = "items")
@@ -213,8 +213,8 @@ public class OIDCProviderTO implements EntityTO, ItemContainerTO {
 
     @Override
     public boolean add(final ItemTO item) {
-        return Optional.ofNullable(item)
-                .filter(itemTO -> this.items.contains(itemTO) || this.items.add(itemTO)).isPresent();
+        return Optional.ofNullable(item).
+                filter(itemTO -> this.items.contains(itemTO) || this.items.add(itemTO)).isPresent();
     }
 
     public boolean remove(final ItemTO item) {
diff --git a/ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/types/OIDCClientEntitlement.java b/ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/types/OIDC4UIEntitlement.java
similarity index 91%
rename from ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/types/OIDCClientEntitlement.java
rename to ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/types/OIDC4UIEntitlement.java
index 98cf4d6..3f6a0a9 100644
--- a/ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/types/OIDCClientEntitlement.java
+++ b/ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/types/OIDC4UIEntitlement.java
@@ -24,7 +24,7 @@ import java.util.Collections;
 import java.util.Set;
 import java.util.TreeSet;
 
-public final class OIDCClientEntitlement {
+public final class OIDC4UIEntitlement {
 
     public static final String OP_READ = "OP_READ";
 
@@ -38,7 +38,7 @@ public final class OIDCClientEntitlement {
 
     static {
         Set<String> values = new TreeSet<>();
-        for (Field field : OIDCClientEntitlement.class.getDeclaredFields()) {
+        for (Field field : OIDC4UIEntitlement.class.getDeclaredFields()) {
             if (Modifier.isStatic(field.getModifiers()) && String.class.equals(field.getType())) {
                 values.add(field.getName());
             }
@@ -50,8 +50,7 @@ public final class OIDCClientEntitlement {
         return VALUES;
     }
 
-    private OIDCClientEntitlement() {
+    private OIDC4UIEntitlement() {
         // private constructor for static utility class
     }
-
 }
diff --git a/ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/types/OIDCClientImplementationType.java b/ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/types/OIDCClientImplementationType.java
similarity index 97%
rename from ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/types/OIDCClientImplementationType.java
rename to ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/types/OIDCClientImplementationType.java
index 895c3eb..164e47f 100644
--- a/ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/types/OIDCClientImplementationType.java
+++ b/ext/oidcc4ui/common-lib/src/main/java/org/apache/syncope/common/lib/types/OIDCClientImplementationType.java
@@ -26,7 +26,7 @@ public final class OIDCClientImplementationType {
     public static final String OP_ACTIONS = "OP_ACTIONS";
 
     private static final Map<String, String> VALUES = Map.ofEntries(
-            Pair.of(OP_ACTIONS, "org.apache.syncope.core.provisioning.api.OIDCProviderActions"));
+            Pair.of(OP_ACTIONS, "org.apache.syncope.core.provisioning.api.OIDCC4UIProviderActions"));
 
     public static Map<String, String> values() {
         return VALUES;
diff --git a/ext/oidcclient/provisioning-java/pom.xml b/ext/oidcc4ui/logic/pom.xml
similarity index 72%
copy from ext/oidcclient/provisioning-java/pom.xml
copy to ext/oidcc4ui/logic/pom.xml
index 3ed6496..c0d4075 100644
--- a/ext/oidcclient/provisioning-java/pom.xml
+++ b/ext/oidcc4ui/logic/pom.xml
@@ -23,14 +23,14 @@ under the License.
 
   <parent>
     <groupId>org.apache.syncope.ext</groupId>
-    <artifactId>syncope-ext-oidcclient</artifactId>
+    <artifactId>syncope-ext-oidcc4ui</artifactId>
     <version>3.0.0-SNAPSHOT</version>
   </parent>
 
-  <name>Apache Syncope Ext: OIDC Client Provisioning Java</name>
-  <description>Apache Syncope Ext: OIDC Client Provisioning Java</description>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-provisioning-java</artifactId>
+  <name>Apache Syncope Ext: OIDC C4UI Logic</name>
+  <description>Apache Syncope Ext: OIDC C4UI Logic</description>
+  <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+  <artifactId>syncope-ext-oidcc4ui-logic</artifactId>
   <packaging>jar</packaging>
   
   <properties>
@@ -39,15 +39,21 @@ under the License.
 
   <dependencies>
     <dependency>
-      <groupId>org.apache.syncope.core</groupId>
-      <artifactId>syncope-core-provisioning-java</artifactId>
+      <groupId>org.apache.syncope.core.idm</groupId>
+      <artifactId>syncope-core-idm-logic</artifactId>
       <version>${project.version}</version>
     </dependency>
+    
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-provisioning-api</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-provisioning-java</artifactId>
       <version>${project.version}</version>
     </dependency>
+
+    <dependency>
+      <groupId>org.pac4j</groupId>
+      <artifactId>pac4j-oidc</artifactId>
+    </dependency>
   </dependencies>
 
   <build>
diff --git a/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/OIDCC4UILogic.java b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/OIDCC4UILogic.java
new file mode 100644
index 0000000..8cef563
--- /dev/null
+++ b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/OIDCC4UILogic.java
@@ -0,0 +1,290 @@
+/*
+ * 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.core.logic;
+
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.oauth2.sdk.AuthorizationCode;
+import java.lang.reflect.Method;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.Attr;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.EntityTO;
+import org.apache.syncope.common.lib.oidc.OIDCRequest;
+import org.apache.syncope.common.lib.oidc.OIDCLoginResponse;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.IdRepoEntitlement;
+import org.apache.syncope.core.logic.oidc.OIDC4UIContext;
+import org.apache.syncope.core.logic.oidc.OIDCClientCache;
+import org.apache.syncope.core.logic.oidc.OIDCUserManager;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.provisioning.api.data.AccessTokenDataBinder;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthDataAccessor;
+import org.apache.syncope.core.spring.security.Encryptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProviderItem;
+import org.apache.syncope.core.persistence.api.dao.OIDCC4UIProviderDAO;
+import org.pac4j.core.exception.http.WithLocationAction;
+import org.pac4j.oidc.client.OidcClient;
+import org.pac4j.oidc.config.OidcConfiguration;
+import org.pac4j.oidc.credentials.OidcCredentials;
+import org.pac4j.oidc.profile.OidcProfile;
+
+@Component
+public class OIDCC4UILogic extends AbstractTransactionalLogic<EntityTO> {
+
+    private static final String JWT_CLAIM_OP_NAME = "OP_NAME";
+
+    private static final String JWT_CLAIM_ID_TOKEN = "ID_TOKEN";
+
+    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
+    @Autowired
+    private OIDCClientCache oidcClientClientCache;
+
+    @Autowired
+    private AuthDataAccessor authDataAccessor;
+
+    @Autowired
+    private AccessTokenDataBinder accessTokenDataBinder;
+
+    @Autowired
+    private OIDCC4UIProviderDAO opDAO;
+
+    @Autowired
+    private OIDCUserManager userManager;
+
+    private OidcClient<OidcConfiguration> getOidcClient(final OIDCC4UIProvider op, final String callbackUrl) {
+        return oidcClientClientCache.get(op.getName()).orElseGet(() -> oidcClientClientCache.add(op, callbackUrl));
+    }
+
+    private OidcClient<OidcConfiguration> getOidcClient(final String opName, final String callbackUrl) {
+        OIDCC4UIProvider op = opDAO.findByName(opName);
+        if (op == null) {
+            throw new NotFoundException("OIDC Provider '" + opName + '\'');
+        }
+
+        return getOidcClient(op, callbackUrl);
+    }
+
+    @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
+    public OIDCRequest createLoginRequest(final String redirectURI, final String opName) {
+        // 1. look for OidcClient
+        OidcClient<OidcConfiguration> oidcClient = getOidcClient(opName, redirectURI);
+        oidcClient.setCallbackUrl(redirectURI);
+
+        // 2. create OIDCRequest
+        WithLocationAction action = oidcClient.getRedirectionAction(new OIDC4UIContext()).
+                map(WithLocationAction.class::cast).
+                orElseThrow(() -> {
+                    SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unknown);
+                    sce.getElements().add("No RedirectionAction generated for LoginRequest");
+                    return sce;
+                });
+
+        OIDCRequest loginRequest = new OIDCRequest();
+        loginRequest.setLocation(action.getLocation());
+        return loginRequest;
+    }
+
+    @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
+    public OIDCLoginResponse login(final String redirectURI, final String authorizationCode, final String opName) {
+        // 0. look for OP
+        OIDCC4UIProvider op = opDAO.findByName(opName);
+        if (op == null) {
+            throw new NotFoundException("OIDC Provider '" + opName + '\'');
+        }
+
+        // 1. look for configured client
+        OidcClient<OidcConfiguration> oidcClient = getOidcClient(opName, redirectURI);
+        oidcClient.setCallbackUrl(redirectURI);
+
+        // 2. get OpenID Connect tokens
+        String idTokenHint;
+        JWTClaimsSet idToken;
+        try {
+            OidcCredentials credentials = new OidcCredentials();
+            credentials.setCode(new AuthorizationCode(authorizationCode));
+
+            OIDC4UIContext ctx = new OIDC4UIContext();
+
+            oidcClient.getAuthenticator().validate(credentials, ctx);
+
+            idToken = credentials.getIdToken().getJWTClaimsSet();
+            idTokenHint = credentials.getIdToken().serialize();
+        } catch (Exception e) {
+            LOG.error("While validating Token Response", e);
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unknown);
+            sce.getElements().add(e.getMessage());
+            throw sce;
+        }
+
+        // 3. prepare the result
+        OIDCLoginResponse loginResponse = new OIDCLoginResponse();
+        loginResponse.setLogoutSupported(StringUtils.isNotBlank(op.getEndSessionEndpoint()));
+
+        // 3a. find matching user (if any) and return the received attributes
+        String keyValue = idToken.getSubject();
+        for (OIDCC4UIProviderItem item : op.getItems()) {
+            Attr attrTO = new Attr();
+            attrTO.setSchema(item.getExtAttrName());
+
+            String value = idToken.getClaim(item.getExtAttrName()) == null
+                    ? null
+                    : idToken.getClaim(item.getExtAttrName()).toString();
+            if (value != null) {
+                attrTO.getValues().add(value);
+                loginResponse.getAttrs().add(attrTO);
+                if (item.isConnObjectKey()) {
+                    keyValue = value;
+                }
+            }
+        }
+
+        List<String> matchingUsers = keyValue == null
+                ? List.of()
+                : userManager.findMatchingUser(keyValue, op.getConnObjectKeyItem().get());
+        LOG.debug("Found {} matching users for {}", matchingUsers.size(), keyValue);
+
+        // 3b. not found: create or selfreg if configured
+        String username;
+        if (matchingUsers.isEmpty()) {
+            if (op.isCreateUnmatching()) {
+                LOG.debug("No user matching {}, about to create", keyValue);
+
+                String defaultUsername = keyValue;
+                username = AuthContextUtils.callAsAdmin(AuthContextUtils.getDomain(),
+                        () -> userManager.create(op, loginResponse, defaultUsername));
+            } else if (op.isSelfRegUnmatching()) {
+                UserTO userTO = new UserTO();
+
+                userManager.fill(op, loginResponse, userTO);
+
+                loginResponse.getAttrs().clear();
+                loginResponse.getAttrs().addAll(userTO.getPlainAttrs());
+                if (StringUtils.isNotBlank(userTO.getUsername())) {
+                    loginResponse.setUsername(userTO.getUsername());
+                } else {
+                    loginResponse.setUsername(keyValue);
+                }
+
+                loginResponse.setSelfReg(true);
+
+                return loginResponse;
+            } else {
+                throw new NotFoundException(Optional.ofNullable(keyValue).
+                        map(value -> "User matching the provided value " + value).
+                        orElse("User marching the provided claims"));
+            }
+        } else if (matchingUsers.size() > 1) {
+            throw new IllegalArgumentException("Several users match the provided value " + keyValue);
+        } else {
+            if (op.isUpdateMatching()) {
+                LOG.debug("About to update {} for {}", matchingUsers.get(0), keyValue);
+
+                username = AuthContextUtils.callAsAdmin(AuthContextUtils.getDomain(),
+                        () -> userManager.update(matchingUsers.get(0), op, loginResponse));
+            } else {
+                username = matchingUsers.get(0);
+            }
+        }
+
+        loginResponse.setUsername(username);
+
+        // 4. generate JWT for further access
+        Map<String, Object> claims = new HashMap<>();
+        claims.put(JWT_CLAIM_OP_NAME, opName);
+        claims.put(JWT_CLAIM_ID_TOKEN, idTokenHint);
+
+        byte[] authorities = null;
+        try {
+            authorities = ENCRYPTOR.encode(POJOHelper.serialize(
+                    authDataAccessor.getAuthorities(loginResponse.getUsername())), CipherAlgorithm.AES).
+                    getBytes();
+        } catch (Exception e) {
+            LOG.error("Could not fetch authorities", e);
+        }
+
+        Pair<String, Date> accessTokenInfo =
+                accessTokenDataBinder.create(loginResponse.getUsername(), claims, authorities, true);
+        loginResponse.setAccessToken(accessTokenInfo.getLeft());
+        loginResponse.setAccessTokenExpiryTime(accessTokenInfo.getRight());
+
+        return loginResponse;
+    }
+
+    @PreAuthorize("isAuthenticated() and not(hasRole('" + IdRepoEntitlement.ANONYMOUS + "'))")
+    public OIDCRequest createLogoutRequest(final String accessToken, final String redirectURI) {
+        // 0. fetch the current JWT used for Syncope authentication
+        JWTClaimsSet claimsSet;
+        try {
+            SignedJWT jwt = SignedJWT.parse(accessToken);
+            claimsSet = jwt.getJWTClaimsSet();
+        } catch (ParseException e) {
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidAccessToken);
+            sce.getElements().add(e.getMessage());
+            throw sce;
+        }
+
+        // 1. look for OidcClient
+        OidcClient<OidcConfiguration> oidcClient =
+                getOidcClient((String) claimsSet.getClaim(JWT_CLAIM_OP_NAME), redirectURI);
+        oidcClient.setCallbackUrl(redirectURI);
+
+        // 2. create OIDCRequest
+        OidcProfile profile = new OidcProfile();
+        profile.setIdTokenString((String) claimsSet.getClaim(JWT_CLAIM_ID_TOKEN));
+
+        WithLocationAction action = oidcClient.getLogoutAction(
+                new OIDC4UIContext(),
+                profile,
+                redirectURI).
+                map(WithLocationAction.class::cast).
+                orElseThrow(() -> {
+                    SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unknown);
+                    sce.getElements().add("No RedirectionAction generated for LogoutRequest");
+                    return sce;
+                });
+
+        OIDCRequest logoutRequest = new OIDCRequest();
+        logoutRequest.setLocation(action.getLocation());
+        return logoutRequest;
+    }
+
+    @Override
+    protected EntityTO resolveReference(
+            final Method method, final Object... args) throws UnresolvedReferenceException {
+
+        throw new UnresolvedReferenceException();
+    }
+}
diff --git a/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/OIDCC4UIProviderLogic.java b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/OIDCC4UIProviderLogic.java
new file mode 100644
index 0000000..6c5d646
--- /dev/null
+++ b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/OIDCC4UIProviderLogic.java
@@ -0,0 +1,148 @@
+/*
+ * 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.core.logic;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.ItemTO;
+import org.apache.syncope.common.lib.to.OIDCC4UIProviderTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.OIDC4UIEntitlement;
+import org.apache.syncope.core.logic.oidc.OIDCClientCache;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider;
+import org.apache.syncope.core.persistence.api.dao.OIDCC4UIProviderDAO;
+import org.apache.syncope.core.provisioning.api.data.OIDCC4UIProviderDataBinder;
+
+@Component
+public class OIDCC4UIProviderLogic extends AbstractTransactionalLogic<OIDCC4UIProviderTO> {
+
+    @Autowired
+    private OIDCClientCache oidcClientClientCache;
+
+    @Autowired
+    private OIDCC4UIProviderDAO opDAO;
+
+    @Autowired
+    private OIDCC4UIProviderDataBinder binder;
+
+    @PreAuthorize("hasRole('" + OIDC4UIEntitlement.OP_CREATE + "')")
+    public String createFromDiscovery(final OIDCC4UIProviderTO opTO) {
+        OIDCClientCache.importMetadata(opTO);
+
+        return create(opTO);
+    }
+
+    @PreAuthorize("hasRole('" + OIDC4UIEntitlement.OP_CREATE + "')")
+    public String create(final OIDCC4UIProviderTO opTO) {
+        if (opTO.getConnObjectKeyItem() == null) {
+            ItemTO connObjectKeyItem = new ItemTO();
+            connObjectKeyItem.setIntAttrName("username");
+            connObjectKeyItem.setExtAttrName("email");
+            opTO.setConnObjectKeyItem(connObjectKeyItem);
+        }
+
+        OIDCC4UIProvider provider = opDAO.save(binder.create(opTO));
+
+        return provider.getKey();
+    }
+
+    @PreAuthorize("isAuthenticated()")
+    @Transactional(readOnly = true)
+    public List<OIDCC4UIProviderTO> list() {
+        return opDAO.findAll().stream().map(binder::getOIDCProviderTO).collect(Collectors.toList());
+    }
+
+    @PreAuthorize("hasRole('" + OIDC4UIEntitlement.OP_READ + "')")
+    @Transactional(readOnly = true)
+    public OIDCC4UIProviderTO read(final String key) {
+        OIDCC4UIProvider op = opDAO.find(key);
+        if (op == null) {
+            throw new NotFoundException("OIDC Provider '" + key + '\'');
+        }
+        return binder.getOIDCProviderTO(op);
+    }
+
+    @PreAuthorize("hasRole('" + OIDC4UIEntitlement.OP_UPDATE + "')")
+    public void update(final OIDCC4UIProviderTO opTO) {
+        OIDCC4UIProvider op = opDAO.find(opTO.getKey());
+        if (op == null) {
+            throw new NotFoundException("OIDC Provider '" + opTO.getKey() + '\'');
+        }
+
+        if (!op.getIssuer().equals(opTO.getIssuer())) {
+            LOG.error("Issuers do not match: expected {}, found {}",
+                    op.getIssuer(), opTO.getIssuer());
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidEntity);
+            sce.getElements().add("Issuers do not match");
+            throw sce;
+        }
+        String opName = op.getName();
+
+        opDAO.save(binder.update(op, opTO));
+        oidcClientClientCache.removeAll(opName);
+    }
+
+    @PreAuthorize("hasRole('" + OIDC4UIEntitlement.OP_DELETE + "')")
+    public void delete(final String key) {
+        OIDCC4UIProvider op = opDAO.find(key);
+        if (op == null) {
+            throw new NotFoundException("OIDC Provider '" + key + '\'');
+        }
+        String opName = op.getName();
+
+        opDAO.delete(key);
+        oidcClientClientCache.removeAll(opName);
+    }
+
+    @Override
+    protected OIDCC4UIProviderTO resolveReference(
+            final Method method, final Object... args) throws UnresolvedReferenceException {
+
+        String key = null;
+
+        if (ArrayUtils.isNotEmpty(args)) {
+            for (int i = 0; key == null && i < args.length; i++) {
+                if (args[i] instanceof String) {
+                    key = (String) args[i];
+                } else if (args[i] instanceof OIDCC4UIProviderTO) {
+                    key = ((OIDCC4UIProviderTO) args[i]).getKey();
+                }
+            }
+        }
+
+        if (key != null) {
+            try {
+                return binder.getOIDCProviderTO(opDAO.find(key));
+            } catch (Throwable ignore) {
+                LOG.debug("Unresolved reference", ignore);
+                throw new UnresolvedReferenceException(ignore);
+            }
+        }
+
+        throw new UnresolvedReferenceException();
+    }
+}
diff --git a/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/init/OIDCClientLoader.java b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/init/OIDCC4UILoader.java
similarity index 87%
rename from ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/init/OIDCClientLoader.java
rename to ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/init/OIDCC4UILoader.java
index 11270a0..75f331c 100644
--- a/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/init/OIDCClientLoader.java
+++ b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/init/OIDCC4UILoader.java
@@ -20,13 +20,13 @@ package org.apache.syncope.core.logic.init;
 
 import org.apache.syncope.common.lib.types.EntitlementsHolder;
 import org.apache.syncope.common.lib.types.ImplementationTypesHolder;
-import org.apache.syncope.common.lib.types.OIDCClientEntitlement;
+import org.apache.syncope.common.lib.types.OIDC4UIEntitlement;
 import org.apache.syncope.common.lib.types.OIDCClientImplementationType;
 import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
 import org.springframework.stereotype.Component;
 
 @Component
-public class OIDCClientLoader implements SyncopeCoreLoader {
+public class OIDCC4UILoader implements SyncopeCoreLoader {
 
     @Override
     public int getOrder() {
@@ -35,7 +35,7 @@ public class OIDCClientLoader implements SyncopeCoreLoader {
 
     @Override
     public void load() {
-        EntitlementsHolder.getInstance().addAll(OIDCClientEntitlement.values());
+        EntitlementsHolder.getInstance().addAll(OIDC4UIEntitlement.values());
         ImplementationTypesHolder.getInstance().putAll(OIDCClientImplementationType.values());
     }
 }
diff --git a/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/model/TokenEndpointResponse.java b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/model/TokenEndpointResponse.java
similarity index 99%
rename from ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/model/TokenEndpointResponse.java
rename to ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/model/TokenEndpointResponse.java
index 7908b88..dbc9eae 100644
--- a/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/model/TokenEndpointResponse.java
+++ b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/model/TokenEndpointResponse.java
@@ -82,5 +82,4 @@ public class TokenEndpointResponse {
     public void setTokenType(final String tokenType) {
         this.tokenType = tokenType;
     }
-
 }
diff --git a/ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCEntityFactory.java b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/NoOpLogoutHandler.java
similarity index 82%
copy from ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCEntityFactory.java
copy to ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/NoOpLogoutHandler.java
index 489ce86..8dcc984 100644
--- a/ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCEntityFactory.java
+++ b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/NoOpLogoutHandler.java
@@ -16,10 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.core.persistence.api.entity;
+package org.apache.syncope.core.logic.oidc;
 
-public interface OIDCEntityFactory {
-
-    <E extends Entity> E newEntity(Class<E> reference);
+import org.pac4j.core.logout.handler.LogoutHandler;
 
+public class NoOpLogoutHandler implements LogoutHandler<OIDC4UIContext> {
 }
diff --git a/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/NoOpSessionStore.java b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/NoOpSessionStore.java
new file mode 100644
index 0000000..11cf61f
--- /dev/null
+++ b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/NoOpSessionStore.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.core.logic.oidc;
+
+import java.util.Optional;
+import org.pac4j.core.context.session.SessionStore;
+
+public final class NoOpSessionStore implements SessionStore<OIDC4UIContext> {
+
+    public static final NoOpSessionStore INSTANCE = new NoOpSessionStore();
+
+    private NoOpSessionStore() {
+        // private constructor for singleton
+    }
+
+    @Override
+    public String getOrCreateSessionId(final OIDC4UIContext context) {
+        return "<NO_KEY>";
+    }
+
+    @Override
+    public Optional<Object> get(final OIDC4UIContext context, final String key) {
+        return Optional.empty();
+    }
+
+    @Override
+    public void set(final OIDC4UIContext context, final String key, final Object value) {
+        // nothing to do
+    }
+
+    @Override
+    public boolean destroySession(final OIDC4UIContext context) {
+        return true;
+    }
+
+    @Override
+    public Optional<?> getTrackableSession(final OIDC4UIContext context) {
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<SessionStore<OIDC4UIContext>> buildFromTrackableSession(
+            final OIDC4UIContext context,
+            final Object trackableSession) {
+
+        return Optional.empty();
+    }
+
+    @Override
+    public boolean renewSession(final OIDC4UIContext context) {
+        return false;
+    }
+}
diff --git a/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDC4UIContext.java b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDC4UIContext.java
new file mode 100644
index 0000000..9eb4fb9
--- /dev/null
+++ b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDC4UIContext.java
@@ -0,0 +1,121 @@
+/*
+ * 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.core.logic.oidc;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import javax.ws.rs.HttpMethod;
+import org.pac4j.core.context.Cookie;
+import org.pac4j.core.context.WebContext;
+import org.pac4j.core.context.session.SessionStore;
+
+public class OIDC4UIContext implements WebContext {
+
+    @Override
+    public String getRequestMethod() {
+        return HttpMethod.GET;
+    }
+
+    @Override
+    public SessionStore<OIDC4UIContext> getSessionStore() {
+        return NoOpSessionStore.INSTANCE;
+    }
+
+    @Override
+    public Optional<String> getRequestParameter(final String name) {
+        return Optional.empty();
+    }
+
+    @Override
+    public Map<String, String[]> getRequestParameters() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Optional<String> getRequestAttribute(final String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setRequestAttribute(final String name, final Object value) {
+        // nothing to do
+    }
+
+    @Override
+    public Optional<String> getRequestHeader(final String name) {
+        return Optional.empty();
+    }
+
+    @Override
+    public String getRemoteAddr() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setResponseHeader(final String name, final String value) {
+        // nothing to do
+    }
+
+    @Override
+    public String getServerName() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getServerPort() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getScheme() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isSecure() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getFullRequestURL() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Collection<Cookie> getRequestCookies() {
+        return Set.of();
+    }
+
+    @Override
+    public void addResponseCookie(final Cookie cookie) {
+        // nothing to do
+    }
+
+    @Override
+    public String getPath() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setResponseContentType(final String content) {
+        // nothing to do
+    }
+}
diff --git a/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCClientCache.java b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCClientCache.java
new file mode 100644
index 0000000..a56b193
--- /dev/null
+++ b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCClientCache.java
@@ -0,0 +1,126 @@
+/*
+ * 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.core.logic.oidc;
+
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.oauth2.sdk.id.Issuer;
+import com.nimbusds.openid.connect.sdk.SubjectType;
+import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
+import java.io.IOException;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.OIDCC4UIProviderTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider;
+import org.pac4j.core.http.callback.NoParameterCallbackUrlResolver;
+import org.pac4j.oidc.client.OidcClient;
+import org.pac4j.oidc.config.OidcConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * Basic in-memory cache for available {@link OidcClient} instances.
+ */
+@Component
+public class OIDCClientCache {
+
+    protected static final Logger LOG = LoggerFactory.getLogger(OIDCClientCache.class);
+
+    private final List<OidcClient<OidcConfiguration>> cache = Collections.synchronizedList(new ArrayList<>());
+
+    private static OIDCProviderMetadata getDiscoveryDocument(final String issuer) {
+        String discoveryDocumentURL = issuer + "/.well-known/openid-configuration";
+        try {
+            HttpResponse<String> response = HttpClient.newBuilder().build().send(
+                    HttpRequest.newBuilder(URI.create(discoveryDocumentURL)).GET().build(),
+                    HttpResponse.BodyHandlers.ofString());
+
+            return OIDCProviderMetadata.parse(response.body());
+        } catch (IOException | InterruptedException | ParseException e) {
+            LOG.error("While getting the Discovery Document at {}", discoveryDocumentURL, e);
+
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unknown);
+            sce.getElements().add(e.getMessage());
+            throw sce;
+        }
+    }
+
+    public static void importMetadata(final OIDCC4UIProviderTO opTO) {
+        OIDCProviderMetadata metadata = getDiscoveryDocument(opTO.getIssuer());
+
+        opTO.setIssuer(
+                Optional.ofNullable(metadata.getIssuer()).map(Issuer::getValue).orElse(null));
+        opTO.setJwksUri(
+                Optional.ofNullable(metadata.getJWKSetURI()).map(URI::toASCIIString).orElse(null));
+        opTO.setAuthorizationEndpoint(
+                Optional.ofNullable(metadata.getAuthorizationEndpointURI()).map(URI::toASCIIString).orElse(null));
+        opTO.setTokenEndpoint(
+                Optional.ofNullable(metadata.getTokenEndpointURI()).map(URI::toASCIIString).orElse(null));
+        opTO.setUserinfoEndpoint(
+                Optional.ofNullable(metadata.getUserInfoEndpointURI()).map(URI::toASCIIString).orElse(null));
+        opTO.setEndSessionEndpoint(
+                Optional.ofNullable(metadata.getEndSessionEndpointURI()).map(URI::toASCIIString).orElse(null));
+    }
+
+    public Optional<OidcClient<OidcConfiguration>> get(final String opName) {
+        return cache.stream().filter(c -> opName.equals(c.getName())).findFirst();
+    }
+
+    public OidcClient<OidcConfiguration> add(final OIDCC4UIProvider op, final String callbackUrl) {
+        OIDCProviderMetadata metadata = new OIDCProviderMetadata(
+                new Issuer(op.getIssuer()),
+                List.of(SubjectType.PUBLIC),
+                Optional.ofNullable(op.getJwksUri()).map(URI::create).orElse(null));
+        metadata.setAuthorizationEndpointURI(
+                Optional.ofNullable(op.getAuthorizationEndpoint()).map(URI::create).orElse(null));
+        metadata.setTokenEndpointURI(
+                Optional.ofNullable(op.getTokenEndpoint()).map(URI::create).orElse(null));
+        metadata.setUserInfoEndpointURI(
+                Optional.ofNullable(op.getUserinfoEndpoint()).map(URI::create).orElse(null));
+        metadata.setEndSessionEndpointURI(
+                Optional.ofNullable(op.getEndSessionEndpoint()).map(URI::create).orElse(null));
+
+        OidcConfiguration config = new OidcConfiguration();
+        config.setClientId(op.getClientID());
+        config.setSecret(op.getClientSecret());
+        config.setProviderMetadata(metadata);
+        config.setScope("openid profile email address phone offline_access");
+        config.setUseNonce(false);
+        config.setLogoutHandler(new NoOpLogoutHandler());
+
+        OidcClient<OidcConfiguration> client = new OidcClient<>(config);
+        client.setName(op.getName());
+        client.setCallbackUrlResolver(new NoParameterCallbackUrlResolver());
+        client.setCallbackUrl(callbackUrl);
+        client.init();
+        return client;
+    }
+
+    public boolean removeAll(final String opName) {
+        return cache.removeIf(c -> opName.equals(c.getName()));
+    }
+}
diff --git a/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCUserManager.java b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCUserManager.java
similarity index 84%
rename from ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCUserManager.java
rename to ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCUserManager.java
index f6d13fe..cb13fa2 100644
--- a/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCUserManager.java
+++ b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCUserManager.java
@@ -31,17 +31,14 @@ import org.apache.syncope.common.lib.EntityTOUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.request.UserCR;
 import org.apache.syncope.common.lib.request.UserUR;
-import org.apache.syncope.common.lib.to.OIDCLoginResponseTO;
+import org.apache.syncope.common.lib.oidc.OIDCLoginResponse;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.OIDCProvider;
-import org.apache.syncope.core.persistence.api.entity.OIDCProviderItem;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.IntAttrName;
 import org.apache.syncope.core.provisioning.api.IntAttrNameParser;
-import org.apache.syncope.core.provisioning.api.OIDCProviderActions;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
@@ -55,6 +52,9 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
+import org.apache.syncope.core.provisioning.api.OIDCC4UIProviderActions;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProviderItem;
 
 @Component
 public class OIDCUserManager {
@@ -82,7 +82,10 @@ public class OIDCUserManager {
     private UserDataBinder binder;
 
     @Transactional(readOnly = true)
-    public List<String> findMatchingUser(final String connObjectKeyValue, final OIDCProviderItem connObjectKeyItem) {
+    public List<String> findMatchingUser(
+            final String connObjectKeyValue,
+            final OIDCC4UIProviderItem connObjectKeyItem) {
+
         return inboundMatcher.matchByConnObjectKeyValue(
                 connObjectKeyItem, connObjectKeyValue, AnyTypeKind.USER, false, null).stream().
                 filter(match -> match.getAny() != null).
@@ -90,8 +93,8 @@ public class OIDCUserManager {
                 collect(Collectors.toList());
     }
 
-    private List<OIDCProviderActions> getActions(final OIDCProvider op) {
-        List<OIDCProviderActions> actions = new ArrayList<>();
+    private List<OIDCC4UIProviderActions> getActions(final OIDCC4UIProvider op) {
+        List<OIDCC4UIProviderActions> actions = new ArrayList<>();
         op.getActions().forEach(impl -> {
             try {
                 actions.add(ImplementationManager.build(impl));
@@ -103,10 +106,10 @@ public class OIDCUserManager {
         return actions;
     }
 
-    public void fill(final OIDCProvider op, final OIDCLoginResponseTO responseTO, final UserTO userTO) {
+    public void fill(final OIDCC4UIProvider op, final OIDCLoginResponse loginResponse, final UserTO userTO) {
         op.getItems().forEach(item -> {
             List<String> values = new ArrayList<>();
-            Optional<Attr> oidcAttr = responseTO.getAttr(item.getExtAttrName());
+            Optional<Attr> oidcAttr = loginResponse.getAttr(item.getExtAttrName());
             if (oidcAttr.isPresent() && !oidcAttr.get().getValues().isEmpty()) {
                 values.addAll(oidcAttr.get().getValues());
 
@@ -161,7 +164,7 @@ public class OIDCUserManager {
     }
 
     @Transactional(propagation = Propagation.REQUIRES_NEW)
-    public String create(final OIDCProvider op, final OIDCLoginResponseTO responseTO, final String email) {
+    public String create(final OIDCC4UIProvider op, final OIDCLoginResponse responseTO, final String defaultUsername) {
         UserCR userCR = new UserCR();
         userCR.setStorePassword(false);
 
@@ -169,8 +172,8 @@ public class OIDCUserManager {
             templateUtils.apply(userCR, op.getUserTemplate().get());
         }
 
-        List<OIDCProviderActions> actions = getActions(op);
-        for (OIDCProviderActions action : actions) {
+        List<OIDCC4UIProviderActions> actions = getActions(op);
+        for (OIDCC4UIProviderActions action : actions) {
             userCR = action.beforeCreate(userCR, responseTO);
         }
 
@@ -182,14 +185,14 @@ public class OIDCUserManager {
             userCR.setRealm(SyncopeConstants.ROOT_REALM);
         }
         if (userCR.getUsername() == null) {
-            userCR.setUsername(email);
+            userCR.setUsername(defaultUsername);
         }
 
         Pair<String, List<PropagationStatus>> created =
                 provisioningManager.create(userCR, false, userCR.getUsername(), OIDC_CLIENT_CONTEXT);
         userTO = binder.getUserTO(created.getKey());
 
-        for (OIDCProviderActions action : actions) {
+        for (OIDCC4UIProviderActions action : actions) {
             userTO = action.afterCreate(userTO, responseTO);
         }
 
@@ -197,7 +200,7 @@ public class OIDCUserManager {
     }
 
     @Transactional(propagation = Propagation.REQUIRES_NEW)
-    public String update(final String username, final OIDCProvider op, final OIDCLoginResponseTO responseTO) {
+    public String update(final String username, final OIDCC4UIProvider op, final OIDCLoginResponse responseTO) {
         UserTO userTO = binder.getUserTO(userDAO.findKey(username));
         UserTO original = SerializationUtils.clone(userTO);
 
@@ -205,8 +208,8 @@ public class OIDCUserManager {
 
         UserUR userUR = AnyOperations.diff(userTO, original, true);
 
-        List<OIDCProviderActions> actions = getActions(op);
-        for (OIDCProviderActions action : actions) {
+        List<OIDCC4UIProviderActions> actions = getActions(op);
+        for (OIDCC4UIProviderActions action : actions) {
             userUR = action.beforeUpdate(userUR, responseTO);
         }
 
@@ -214,7 +217,7 @@ public class OIDCUserManager {
                 provisioningManager.update(userUR, false, userTO.getUsername(), OIDC_CLIENT_CONTEXT);
         userTO = binder.getUserTO(updated.getLeft().getKey());
 
-        for (OIDCProviderActions action : actions) {
+        for (OIDCC4UIProviderActions action : actions) {
             userTO = action.afterUpdate(userTO, responseTO);
         }
 
diff --git a/ext/oidcclient/persistence-api/pom.xml b/ext/oidcc4ui/persistence-api/pom.xml
similarity index 80%
rename from ext/oidcclient/persistence-api/pom.xml
rename to ext/oidcc4ui/persistence-api/pom.xml
index c2ffc7d..b0b7dcb 100644
--- a/ext/oidcclient/persistence-api/pom.xml
+++ b/ext/oidcc4ui/persistence-api/pom.xml
@@ -23,14 +23,14 @@ under the License.
 
   <parent>
     <groupId>org.apache.syncope.ext</groupId>
-    <artifactId>syncope-ext-oidcclient</artifactId>
+    <artifactId>syncope-ext-oidcc4ui</artifactId>
     <version>3.0.0-SNAPSHOT</version>
   </parent>
 
-  <name>Apache Syncope Ext: OIDC Client Persistence API</name>
-  <description>Apache Syncope Ext: OIDC Client Persistence API</description>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-persistence-api</artifactId>
+  <name>Apache Syncope Ext: OIDC C4UI Persistence API</name>
+  <description>Apache Syncope Ext: OIDC C4UI Persistence API</description>
+  <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+  <artifactId>syncope-ext-oidcc4ui-persistence-api</artifactId>
   <packaging>jar</packaging>
   
   <properties>
@@ -44,8 +44,8 @@ under the License.
       <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-common-lib</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-common-lib</artifactId>
       <version>${project.version}</version>
     </dependency>
   </dependencies>
diff --git a/ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/OIDCProviderDAO.java b/ext/oidcc4ui/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/OIDCC4UIProviderDAO.java
similarity index 76%
rename from ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/OIDCProviderDAO.java
rename to ext/oidcc4ui/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/OIDCC4UIProviderDAO.java
index 2319947..93e795e 100644
--- a/ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/OIDCProviderDAO.java
+++ b/ext/oidcc4ui/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/OIDCC4UIProviderDAO.java
@@ -19,17 +19,17 @@
 package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.OIDCProvider;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider;
 
-public interface OIDCProviderDAO {
+public interface OIDCC4UIProviderDAO {
 
-    OIDCProvider find(String key);
+    OIDCC4UIProvider find(String key);
 
-    OIDCProvider findByName(String name);
+    OIDCC4UIProvider findByName(String name);
 
-    List<OIDCProvider> findAll();
+    List<OIDCC4UIProvider> findAll();
 
-    OIDCProvider save(OIDCProvider op);
+    OIDCC4UIProvider save(OIDCC4UIProvider op);
 
     void delete(String key);
 }
diff --git a/ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCEntityFactory.java b/ext/oidcc4ui/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCC4UIEntityFactory.java
similarity index 95%
rename from ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCEntityFactory.java
rename to ext/oidcc4ui/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCC4UIEntityFactory.java
index 489ce86..51c9612 100644
--- a/ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCEntityFactory.java
+++ b/ext/oidcc4ui/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCC4UIEntityFactory.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.core.persistence.api.entity;
 
-public interface OIDCEntityFactory {
+public interface OIDCC4UIEntityFactory {
 
     <E extends Entity> E newEntity(Class<E> reference);
 
diff --git a/ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCProvider.java b/ext/oidcc4ui/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCC4UIProvider.java
similarity index 84%
rename from ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCProvider.java
rename to ext/oidcc4ui/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCC4UIProvider.java
index b6daf54..7f3bc78 100644
--- a/ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCProvider.java
+++ b/ext/oidcc4ui/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCC4UIProvider.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.persistence.api.entity;
 import java.util.List;
 import java.util.Optional;
 
-public interface OIDCProvider extends Entity {
+public interface OIDCC4UIProvider extends Entity {
 
     String getName();
 
@@ -75,17 +75,17 @@ public interface OIDCProvider extends Entity {
 
     void setUpdateMatching(boolean updateMatching);
 
-    OIDCUserTemplate getUserTemplate();
+    OIDCC4UIUserTemplate getUserTemplate();
 
-    void setUserTemplate(OIDCUserTemplate userTemplate);
+    void setUserTemplate(OIDCC4UIUserTemplate userTemplate);
 
-    List<? extends OIDCProviderItem> getItems();
+    List<? extends OIDCC4UIProviderItem> getItems();
 
-    Optional<? extends OIDCProviderItem> getConnObjectKeyItem();
+    Optional<? extends OIDCC4UIProviderItem> getConnObjectKeyItem();
 
-    void setConnObjectKeyItem(OIDCProviderItem item);
+    void setConnObjectKeyItem(OIDCC4UIProviderItem item);
 
-    boolean add(OIDCProviderItem item);
+    boolean add(OIDCC4UIProviderItem item);
 
     boolean add(Implementation action);
 
diff --git a/ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCProviderItem.java b/ext/oidcc4ui/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCC4UIProviderItem.java
similarity index 88%
rename from ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCProviderItem.java
rename to ext/oidcc4ui/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCC4UIProviderItem.java
index 3047c88..8f87121 100644
--- a/ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCProviderItem.java
+++ b/ext/oidcc4ui/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCC4UIProviderItem.java
@@ -20,10 +20,10 @@ package org.apache.syncope.core.persistence.api.entity;
 
 import org.apache.syncope.core.persistence.api.entity.resource.Item;
 
-public interface OIDCProviderItem extends Item {
+public interface OIDCC4UIProviderItem extends Item {
 
-    OIDCProvider getOP();
+    OIDCC4UIProvider getOP();
 
-    void setOP(OIDCProvider op);
+    void setOP(OIDCC4UIProvider op);
 
 }
diff --git a/ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCUserTemplate.java b/ext/oidcc4ui/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCC4UIUserTemplate.java
similarity index 87%
rename from ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCUserTemplate.java
rename to ext/oidcc4ui/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCC4UIUserTemplate.java
index 339f6ec9..f8ddb38 100644
--- a/ext/oidcclient/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCUserTemplate.java
+++ b/ext/oidcc4ui/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/OIDCC4UIUserTemplate.java
@@ -18,10 +18,10 @@
  */
 package org.apache.syncope.core.persistence.api.entity;
 
-public interface OIDCUserTemplate extends AnyTemplate {
+public interface OIDCC4UIUserTemplate extends AnyTemplate {
 
-    OIDCProvider getOP();
+    OIDCC4UIProvider getOP();
 
-    void setOP(OIDCProvider op);
+    void setOP(OIDCC4UIProvider op);
 
 }
diff --git a/ext/oidcclient/persistence-jpa/pom.xml b/ext/oidcc4ui/persistence-jpa/pom.xml
similarity index 90%
rename from ext/oidcclient/persistence-jpa/pom.xml
rename to ext/oidcc4ui/persistence-jpa/pom.xml
index 8ce5496..1628636 100644
--- a/ext/oidcclient/persistence-jpa/pom.xml
+++ b/ext/oidcc4ui/persistence-jpa/pom.xml
@@ -23,14 +23,14 @@ under the License.
 
   <parent>
     <groupId>org.apache.syncope.ext</groupId>
-    <artifactId>syncope-ext-oidcclient</artifactId>
+    <artifactId>syncope-ext-oidcc4ui</artifactId>
     <version>3.0.0-SNAPSHOT</version>
   </parent>
 
-  <name>Apache Syncope Ext: OIDC Client Persistence JPA</name>
-  <description>Apache Syncope Ext: OIDC Client Persistence JPA</description>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-persistence-jpa</artifactId>
+  <name>Apache Syncope Ext: OIDC C4UI Persistence JPA</name>
+  <description>Apache Syncope Ext: OIDC C4UI Persistence JPA</description>
+  <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+  <artifactId>syncope-ext-oidcc4ui-persistence-jpa</artifactId>
   <packaging>jar</packaging>
   
   <properties>
@@ -44,8 +44,8 @@ under the License.
       <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-persistence-api</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-persistence-api</artifactId>
       <version>${project.version}</version>
     </dependency>
   </dependencies>
diff --git a/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAOIDCProviderDAO.java b/ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAOIDCC4UIProviderDAO.java
similarity index 61%
rename from ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAOIDCProviderDAO.java
rename to ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAOIDCC4UIProviderDAO.java
index 91e3af0..a4e4f35 100644
--- a/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAOIDCProviderDAO.java
+++ b/ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAOIDCC4UIProviderDAO.java
@@ -21,30 +21,30 @@ package org.apache.syncope.core.persistence.jpa.dao;
 import java.util.List;
 import javax.persistence.NoResultException;
 import javax.persistence.TypedQuery;
-import org.apache.syncope.core.persistence.api.dao.OIDCProviderDAO;
-import org.apache.syncope.core.persistence.api.entity.OIDCProvider;
-import org.apache.syncope.core.persistence.jpa.entity.JPAOIDCProvider;
+import org.apache.syncope.core.persistence.jpa.entity.JPAOIDCC4UIProvider;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Transactional;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider;
+import org.apache.syncope.core.persistence.api.dao.OIDCC4UIProviderDAO;
 
 @Repository
-public class JPAOIDCProviderDAO extends AbstractDAO<OIDCProvider> implements OIDCProviderDAO {
+public class JPAOIDCC4UIProviderDAO extends AbstractDAO<OIDCC4UIProvider> implements OIDCC4UIProviderDAO {
 
     @Transactional(readOnly = true)
     @Override
-    public OIDCProvider find(final String key) {
-        return entityManager().find(JPAOIDCProvider.class, key);
+    public OIDCC4UIProvider find(final String key) {
+        return entityManager().find(JPAOIDCC4UIProvider.class, key);
     }
 
     @Transactional(readOnly = true)
     @Override
-    public OIDCProvider findByName(final String name) {
-        TypedQuery<OIDCProvider> query = entityManager().createQuery(
-                "SELECT e FROM " + JPAOIDCProvider.class.getSimpleName()
-                + " e WHERE e.name = :name", OIDCProvider.class);
+    public OIDCC4UIProvider findByName(final String name) {
+        TypedQuery<OIDCC4UIProvider> query = entityManager().createQuery(
+                "SELECT e FROM " + JPAOIDCC4UIProvider.class.getSimpleName()
+                + " e WHERE e.name = :name", OIDCC4UIProvider.class);
         query.setParameter("name", name);
 
-        OIDCProvider result = null;
+        OIDCC4UIProvider result = null;
         try {
             result = query.getSingleResult();
         } catch (NoResultException e) {
@@ -56,23 +56,22 @@ public class JPAOIDCProviderDAO extends AbstractDAO<OIDCProvider> implements OID
 
     @Transactional(readOnly = true)
     @Override
-    public List<OIDCProvider> findAll() {
-        TypedQuery<OIDCProvider> query = entityManager().createQuery(
-                "SELECT e FROM " + JPAOIDCProvider.class.getSimpleName() + " e", OIDCProvider.class);
+    public List<OIDCC4UIProvider> findAll() {
+        TypedQuery<OIDCC4UIProvider> query = entityManager().createQuery(
+                "SELECT e FROM " + JPAOIDCC4UIProvider.class.getSimpleName() + " e", OIDCC4UIProvider.class);
         return query.getResultList();
     }
 
     @Override
-    public OIDCProvider save(final OIDCProvider op) {
+    public OIDCC4UIProvider save(final OIDCC4UIProvider op) {
         return entityManager().merge(op);
     }
 
     @Override
     public void delete(final String key) {
-        OIDCProvider op = find(key);
+        OIDCC4UIProvider op = find(key);
         if (op != null) {
             entityManager().remove(op);
         }
     }
-
 }
diff --git a/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCEntityFactory.java b/ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCC4UIEntityFactory.java
similarity index 67%
rename from ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCEntityFactory.java
rename to ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCC4UIEntityFactory.java
index 81608bb..e5552b0 100644
--- a/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCEntityFactory.java
+++ b/ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCC4UIEntityFactory.java
@@ -19,27 +19,27 @@
 package org.apache.syncope.core.persistence.jpa.entity;
 
 import org.apache.syncope.core.persistence.api.entity.Entity;
-import org.apache.syncope.core.persistence.api.entity.OIDCEntityFactory;
-import org.apache.syncope.core.persistence.api.entity.OIDCProvider;
-import org.apache.syncope.core.persistence.api.entity.OIDCProviderItem;
-import org.apache.syncope.core.persistence.api.entity.OIDCUserTemplate;
 import org.apache.syncope.core.spring.security.SecureRandomUtils;
 import org.springframework.stereotype.Component;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIEntityFactory;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProviderItem;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIUserTemplate;
 
 @Component
-public class JPAOIDCEntityFactory implements OIDCEntityFactory {
+public class JPAOIDCC4UIEntityFactory implements OIDCC4UIEntityFactory {
 
     @Override
     @SuppressWarnings("unchecked")
     public <E extends Entity> E newEntity(final Class<E> reference) {
         E result;
 
-        if (reference.equals(OIDCProvider.class)) {
-            result = (E) new JPAOIDCProvider();
-        } else if (reference.equals(OIDCProviderItem.class)) {
-            result = (E) new JPAOIDCProviderItem();
-        } else if (reference.equals(OIDCUserTemplate.class)) {
-            result = (E) new JPAOIDCUserTemplate();
+        if (reference.equals(OIDCC4UIProvider.class)) {
+            result = (E) new JPAOIDCC4UIProvider();
+        } else if (reference.equals(OIDCC4UIProviderItem.class)) {
+            result = (E) new JPAOIDCC4UIProviderItem();
+        } else if (reference.equals(OIDCC4UIUserTemplate.class)) {
+            result = (E) new JPAOIDCC4UIUserTemplate();
         } else {
             throw new IllegalArgumentException("Could not find a JPA implementation of " + reference.getName());
         }
diff --git a/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCProvider.java b/ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCC4UIProvider.java
similarity index 84%
rename from ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCProvider.java
rename to ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCC4UIProvider.java
index 6cb3c08..48301e5 100644
--- a/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCProvider.java
+++ b/ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCC4UIProvider.java
@@ -35,17 +35,17 @@ import javax.persistence.Table;
 import javax.validation.constraints.NotNull;
 import org.apache.syncope.common.lib.types.OIDCClientImplementationType;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
-import org.apache.syncope.core.persistence.api.entity.OIDCProvider;
-import org.apache.syncope.core.persistence.api.entity.OIDCProviderItem;
-import org.apache.syncope.core.persistence.api.entity.OIDCUserTemplate;
 import org.apache.syncope.core.persistence.api.entity.resource.Item;
-import org.apache.syncope.core.persistence.jpa.validation.entity.OIDCProviderCheck;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProviderItem;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIUserTemplate;
+import org.apache.syncope.core.persistence.jpa.validation.entity.OIDCC4UIProviderCheck;
 
 @Entity
-@Table(name = JPAOIDCProvider.TABLE)
+@Table(name = JPAOIDCC4UIProvider.TABLE)
 @Cacheable
-@OIDCProviderCheck
-public class JPAOIDCProvider extends AbstractGeneratedKeyEntity implements OIDCProvider {
+@OIDCC4UIProviderCheck
+public class JPAOIDCC4UIProvider extends AbstractGeneratedKeyEntity implements OIDCC4UIProvider {
 
     public static final String TABLE = "OIDCProvider";
 
@@ -82,10 +82,10 @@ public class JPAOIDCProvider extends AbstractGeneratedKeyEntity implements OIDCP
     private boolean hasDiscovery;
 
     @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "op")
-    private JPAOIDCUserTemplate userTemplate;
+    private JPAOIDCC4UIUserTemplate userTemplate;
 
     @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "op")
-    private List<JPAOIDCProviderItem> items = new ArrayList<>();
+    private List<JPAOIDCC4UIProviderItem> items = new ArrayList<>();
 
     @NotNull
     private Boolean createUnmatching = false;
@@ -235,34 +235,34 @@ public class JPAOIDCProvider extends AbstractGeneratedKeyEntity implements OIDCP
     }
 
     @Override
-    public OIDCUserTemplate getUserTemplate() {
+    public OIDCC4UIUserTemplate getUserTemplate() {
         return userTemplate;
     }
 
     @Override
-    public void setUserTemplate(final OIDCUserTemplate userTemplate) {
-        checkType(userTemplate, JPAOIDCUserTemplate.class);
-        this.userTemplate = (JPAOIDCUserTemplate) userTemplate;
+    public void setUserTemplate(final OIDCC4UIUserTemplate userTemplate) {
+        checkType(userTemplate, JPAOIDCC4UIUserTemplate.class);
+        this.userTemplate = (JPAOIDCC4UIUserTemplate) userTemplate;
     }
 
     @Override
-    public boolean add(final OIDCProviderItem item) {
-        checkType(item, JPAOIDCProviderItem.class);
-        return items.contains((JPAOIDCProviderItem) item) || items.add((JPAOIDCProviderItem) item);
+    public boolean add(final OIDCC4UIProviderItem item) {
+        checkType(item, JPAOIDCC4UIProviderItem.class);
+        return items.contains((JPAOIDCC4UIProviderItem) item) || items.add((JPAOIDCC4UIProviderItem) item);
     }
 
     @Override
-    public List<? extends OIDCProviderItem> getItems() {
+    public List<? extends OIDCC4UIProviderItem> getItems() {
         return items;
     }
 
     @Override
-    public Optional<? extends OIDCProviderItem> getConnObjectKeyItem() {
+    public Optional<? extends OIDCC4UIProviderItem> getConnObjectKeyItem() {
         return getItems().stream().filter(Item::isConnObjectKey).findFirst();
     }
 
     @Override
-    public void setConnObjectKeyItem(final OIDCProviderItem item) {
+    public void setConnObjectKeyItem(final OIDCC4UIProviderItem item) {
         item.setConnObjectKey(true);
         this.add(item);
     }
diff --git a/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCProviderItem.java b/ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCC4UIProviderItem.java
similarity index 83%
rename from ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCProviderItem.java
rename to ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCC4UIProviderItem.java
index f2afe3a..85ee0a6 100644
--- a/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCProviderItem.java
+++ b/ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCC4UIProviderItem.java
@@ -31,31 +31,31 @@ import javax.persistence.Table;
 import javax.persistence.UniqueConstraint;
 import org.apache.syncope.common.lib.types.IdRepoImplementationType;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
-import org.apache.syncope.core.persistence.api.entity.OIDCProvider;
-import org.apache.syncope.core.persistence.api.entity.OIDCProviderItem;
 import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractItem;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProviderItem;
 
 @Entity
-@Table(name = JPAOIDCProviderItem.TABLE)
+@Table(name = JPAOIDCC4UIProviderItem.TABLE)
 @Cacheable
-public class JPAOIDCProviderItem extends AbstractItem implements OIDCProviderItem {
+public class JPAOIDCC4UIProviderItem extends AbstractItem implements OIDCC4UIProviderItem {
 
     public static final String TABLE = "OIDCProviderItem";
 
     private static final long serialVersionUID = -6903418265811089724L;
 
     @ManyToOne
-    private JPAOIDCProvider op;
+    private JPAOIDCC4UIProvider op;
 
     @Override
-    public OIDCProvider getOP() {
+    public OIDCC4UIProvider getOP() {
         return op;
     }
 
     @Override
-    public void setOP(final OIDCProvider op) {
-        checkType(op, JPAOIDCProvider.class);
-        this.op = (JPAOIDCProvider) op;
+    public void setOP(final OIDCC4UIProvider op) {
+        checkType(op, JPAOIDCC4UIProvider.class);
+        this.op = (JPAOIDCC4UIProvider) op;
     }
 
     @ManyToMany(fetch = FetchType.EAGER)
diff --git a/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCUserTemplate.java b/ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCC4UIUserTemplate.java
similarity index 72%
rename from ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCUserTemplate.java
rename to ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCC4UIUserTemplate.java
index 54eea72..303c409 100644
--- a/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCUserTemplate.java
+++ b/ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCC4UIUserTemplate.java
@@ -22,31 +22,31 @@ import javax.persistence.Entity;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
 import javax.persistence.UniqueConstraint;
-import org.apache.syncope.core.persistence.api.entity.OIDCProvider;
-import org.apache.syncope.core.persistence.api.entity.OIDCUserTemplate;
 import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractAnyTemplate;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIUserTemplate;
 
 @Entity
-@Table(name = JPAOIDCUserTemplate.TABLE, uniqueConstraints =
+@Table(name = JPAOIDCC4UIUserTemplate.TABLE, uniqueConstraints =
         @UniqueConstraint(columnNames = { "op_id" }))
-public class JPAOIDCUserTemplate extends AbstractAnyTemplate implements OIDCUserTemplate {
+public class JPAOIDCC4UIUserTemplate extends AbstractAnyTemplate implements OIDCC4UIUserTemplate {
 
     public static final String TABLE = "OIDCUserTemplate";
 
     private static final long serialVersionUID = 3964321047520954968L;
 
     @ManyToOne
-    private JPAOIDCProvider op;
+    private JPAOIDCC4UIProvider op;
 
     @Override
-    public OIDCProvider getOP() {
+    public OIDCC4UIProvider getOP() {
         return op;
     }
 
     @Override
-    public void setOP(final OIDCProvider op) {
-        checkType(op, JPAOIDCProvider.class);
-        this.op = (JPAOIDCProvider) op;
+    public void setOP(final OIDCC4UIProvider op) {
+        checkType(op, JPAOIDCC4UIProvider.class);
+        this.op = (JPAOIDCC4UIProvider) op;
     }
 
 }
diff --git a/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/OIDCProviderCheck.java b/ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/OIDCC4UIProviderCheck.java
similarity index 91%
rename from ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/OIDCProviderCheck.java
rename to ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/OIDCC4UIProviderCheck.java
index 2f96a33..41f9eed 100644
--- a/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/OIDCProviderCheck.java
+++ b/ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/OIDCC4UIProviderCheck.java
@@ -29,11 +29,11 @@ import javax.validation.Payload;
 
 @Target({ ElementType.TYPE })
 @Retention(RetentionPolicy.RUNTIME)
-@Constraint(validatedBy = OIDCProviderValidator.class)
+@Constraint(validatedBy = OIDCC4UIProviderValidator.class)
 @Documented
-public @interface OIDCProviderCheck {
+public @interface OIDCC4UIProviderCheck {
 
-    String message() default "{org.apache.syncope.core.persistence.validation.oidcprovider}";
+    String message() default "{org.apache.syncope.core.persistence.validation.oidcc4uiprovider}";
 
     Class<?>[] groups() default {};
 
diff --git a/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/OIDCProviderValidator.java b/ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/OIDCC4UIProviderValidator.java
similarity index 93%
rename from ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/OIDCProviderValidator.java
rename to ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/OIDCC4UIProviderValidator.java
index 63eb75b..53560ad 100644
--- a/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/OIDCProviderValidator.java
+++ b/ext/oidcc4ui/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/OIDCC4UIProviderValidator.java
@@ -21,14 +21,14 @@ 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.common.lib.types.ImplementationEngine;
-import org.apache.syncope.core.persistence.api.entity.OIDCProvider;
 import org.apache.syncope.core.persistence.api.entity.resource.Item;
 import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider;
 
-public class OIDCProviderValidator extends AbstractValidator<OIDCProviderCheck, OIDCProvider> {
+public class OIDCC4UIProviderValidator extends AbstractValidator<OIDCC4UIProviderCheck, OIDCC4UIProvider> {
 
     @Override
-    public boolean isValid(final OIDCProvider oidcProvider, final ConstraintValidatorContext context) {
+    public boolean isValid(final OIDCC4UIProvider oidcProvider, final ConstraintValidatorContext context) {
         context.disableDefaultConstraintViolation();
 
         if (isHtml(oidcProvider.getKey())) {
@@ -90,5 +90,4 @@ public class OIDCProviderValidator extends AbstractValidator<OIDCProviderCheck,
 
         return isValid[0];
     }
-
 }
diff --git a/ext/oidcclient/pom.xml b/ext/oidcc4ui/pom.xml
similarity index 90%
rename from ext/oidcclient/pom.xml
rename to ext/oidcc4ui/pom.xml
index a4ad217..92974c7 100644
--- a/ext/oidcclient/pom.xml
+++ b/ext/oidcc4ui/pom.xml
@@ -27,10 +27,10 @@ under the License.
     <version>3.0.0-SNAPSHOT</version>
   </parent>
 
-  <name>Apache Syncope Ext: OIDC Client</name>
-  <description>Apache Syncope Ext: OIDC Client</description>
+  <name>Apache Syncope Ext: OIDC C4UI</name>
+  <description>Apache Syncope Ext: OIDC C4UI</description>
   <groupId>org.apache.syncope.ext</groupId>
-  <artifactId>syncope-ext-oidcclient</artifactId>
+  <artifactId>syncope-ext-oidcc4ui</artifactId>
   <packaging>pom</packaging>
   
   <properties>
@@ -45,7 +45,6 @@ under the License.
     <module>rest-cxf</module>
     <module>persistence-api</module>
     <module>persistence-jpa</module>
-    <module>agent</module>
     <module>client-console</module>
     <module>client-enduser</module>
     <module>provisioning-api</module>
diff --git a/ext/oidcclient/provisioning-api/pom.xml b/ext/oidcc4ui/provisioning-api/pom.xml
similarity index 76%
rename from ext/oidcclient/provisioning-api/pom.xml
rename to ext/oidcc4ui/provisioning-api/pom.xml
index c13312a..74857e5 100644
--- a/ext/oidcclient/provisioning-api/pom.xml
+++ b/ext/oidcc4ui/provisioning-api/pom.xml
@@ -23,14 +23,14 @@ under the License.
 
   <parent>
     <groupId>org.apache.syncope.ext</groupId>
-    <artifactId>syncope-ext-oidcclient</artifactId>
+    <artifactId>syncope-ext-oidcc4ui</artifactId>
     <version>3.0.0-SNAPSHOT</version>
   </parent>
 
-  <name>Apache Syncope Ext: OIDC Client Provisioning API</name>
-  <description>Apache Syncope Ext: OIDC Client Provisioning API</description>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-provisioning-api</artifactId>
+  <name>Apache Syncope Ext: OIDC C4UI Provisioning API</name>
+  <description>Apache Syncope Ext: OIDC C4UI Provisioning API</description>
+  <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+  <artifactId>syncope-ext-oidcc4ui-provisioning-api</artifactId>
   <packaging>jar</packaging>
   
   <properties>
@@ -45,13 +45,13 @@ under the License.
     </dependency>
 
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-persistence-api</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-persistence-api</artifactId>
       <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-common-lib</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-common-lib</artifactId>
       <version>${project.version}</version>
     </dependency>
   </dependencies>
diff --git a/ext/oidcclient/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/OIDCProviderActions.java b/ext/oidcc4ui/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/OIDCC4UIProviderActions.java
similarity index 72%
rename from ext/oidcclient/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/OIDCProviderActions.java
rename to ext/oidcc4ui/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/OIDCC4UIProviderActions.java
index 6a08e70..d0e47a2 100644
--- a/ext/oidcclient/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/OIDCProviderActions.java
+++ b/ext/oidcc4ui/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/OIDCC4UIProviderActions.java
@@ -20,24 +20,24 @@ package org.apache.syncope.core.provisioning.api;
 
 import org.apache.syncope.common.lib.request.UserCR;
 import org.apache.syncope.common.lib.request.UserUR;
-import org.apache.syncope.common.lib.to.OIDCLoginResponseTO;
+import org.apache.syncope.common.lib.oidc.OIDCLoginResponse;
 import org.apache.syncope.common.lib.to.UserTO;
 
-public interface OIDCProviderActions {
+public interface OIDCC4UIProviderActions {
 
-    default UserCR beforeCreate(UserCR input, OIDCLoginResponseTO loginResponse) {
+    default UserCR beforeCreate(UserCR input, OIDCLoginResponse loginResponse) {
         return input;
     }
 
-    default UserTO afterCreate(UserTO input, OIDCLoginResponseTO loginResponse) {
+    default UserTO afterCreate(UserTO input, OIDCLoginResponse loginResponse) {
         return input;
     }
 
-    default UserUR beforeUpdate(UserUR input, OIDCLoginResponseTO loginResponse) {
+    default UserUR beforeUpdate(UserUR input, OIDCLoginResponse loginResponse) {
         return input;
     }
 
-    default UserTO afterUpdate(UserTO input, OIDCLoginResponseTO loginResponse) {
+    default UserTO afterUpdate(UserTO input, OIDCLoginResponse loginResponse) {
         return input;
     }
 }
diff --git a/ext/oidcclient/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/OIDCProviderDataBinder.java b/ext/oidcc4ui/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/OIDCC4UIProviderDataBinder.java
similarity index 70%
rename from ext/oidcclient/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/OIDCProviderDataBinder.java
rename to ext/oidcc4ui/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/OIDCC4UIProviderDataBinder.java
index acea05d..803c594 100644
--- a/ext/oidcclient/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/OIDCProviderDataBinder.java
+++ b/ext/oidcc4ui/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/OIDCC4UIProviderDataBinder.java
@@ -18,15 +18,15 @@
  */
 package org.apache.syncope.core.provisioning.api.data;
 
-import org.apache.syncope.common.lib.to.OIDCProviderTO;
-import org.apache.syncope.core.persistence.api.entity.OIDCProvider;
+import org.apache.syncope.common.lib.to.OIDCC4UIProviderTO;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider;
 
-public interface OIDCProviderDataBinder {
+public interface OIDCC4UIProviderDataBinder {
 
-    OIDCProvider create(OIDCProviderTO op);
+    OIDCC4UIProvider create(OIDCC4UIProviderTO op);
 
-    OIDCProvider update(OIDCProvider op, OIDCProviderTO opTO);
+    OIDCC4UIProvider update(OIDCC4UIProvider op, OIDCC4UIProviderTO opTO);
 
-    OIDCProviderTO getOIDCProviderTO(OIDCProvider op);
+    OIDCC4UIProviderTO getOIDCProviderTO(OIDCC4UIProvider op);
 
 }
diff --git a/ext/oidcclient/provisioning-java/pom.xml b/ext/oidcc4ui/provisioning-java/pom.xml
similarity index 79%
rename from ext/oidcclient/provisioning-java/pom.xml
rename to ext/oidcc4ui/provisioning-java/pom.xml
index 3ed6496..a144a0e 100644
--- a/ext/oidcclient/provisioning-java/pom.xml
+++ b/ext/oidcc4ui/provisioning-java/pom.xml
@@ -23,14 +23,14 @@ under the License.
 
   <parent>
     <groupId>org.apache.syncope.ext</groupId>
-    <artifactId>syncope-ext-oidcclient</artifactId>
+    <artifactId>syncope-ext-oidcc4ui</artifactId>
     <version>3.0.0-SNAPSHOT</version>
   </parent>
 
-  <name>Apache Syncope Ext: OIDC Client Provisioning Java</name>
-  <description>Apache Syncope Ext: OIDC Client Provisioning Java</description>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-provisioning-java</artifactId>
+  <name>Apache Syncope Ext: OIDC C4UI Provisioning Java</name>
+  <description>Apache Syncope Ext: OIDC C4UI Provisioning Java</description>
+  <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+  <artifactId>syncope-ext-oidcc4ui-provisioning-java</artifactId>
   <packaging>jar</packaging>
   
   <properties>
@@ -44,8 +44,8 @@ under the License.
       <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-provisioning-api</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-provisioning-api</artifactId>
       <version>${project.version}</version>
     </dependency>
   </dependencies>
diff --git a/ext/oidcclient/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/OIDCProviderDataBinderImpl.java b/ext/oidcc4ui/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/OIDCC4UIProviderDataBinderImpl.java
similarity index 86%
rename from ext/oidcclient/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/OIDCProviderDataBinderImpl.java
rename to ext/oidcc4ui/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/OIDCC4UIProviderDataBinderImpl.java
index c978a97..ff7d138 100644
--- a/ext/oidcclient/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/OIDCProviderDataBinderImpl.java
+++ b/ext/oidcc4ui/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/OIDCC4UIProviderDataBinderImpl.java
@@ -23,7 +23,7 @@ import java.util.stream.Collectors;
 import org.apache.syncope.common.lib.SyncopeClientCompositeException;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.ItemTO;
-import org.apache.syncope.common.lib.to.OIDCProviderTO;
+import org.apache.syncope.common.lib.to.OIDCC4UIProviderTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
@@ -31,48 +31,48 @@ import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
-import org.apache.syncope.core.persistence.api.dao.OIDCProviderDAO;
 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.OIDCEntityFactory;
-import org.apache.syncope.core.persistence.api.entity.OIDCProvider;
-import org.apache.syncope.core.persistence.api.entity.OIDCProviderItem;
-import org.apache.syncope.core.persistence.api.entity.OIDCUserTemplate;
 import org.apache.syncope.core.provisioning.api.IntAttrName;
-import org.apache.syncope.core.provisioning.api.data.OIDCProviderDataBinder;
 import org.apache.syncope.core.provisioning.api.jexl.JexlUtils;
 import org.apache.syncope.core.provisioning.api.IntAttrNameParser;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIEntityFactory;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProvider;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIProviderItem;
+import org.apache.syncope.core.persistence.api.entity.OIDCC4UIUserTemplate;
+import org.apache.syncope.core.persistence.api.dao.OIDCC4UIProviderDAO;
+import org.apache.syncope.core.provisioning.api.data.OIDCC4UIProviderDataBinder;
 
 @Component
-public class OIDCProviderDataBinderImpl implements OIDCProviderDataBinder {
+public class OIDCC4UIProviderDataBinderImpl implements OIDCC4UIProviderDataBinder {
 
-    private static final Logger LOG = LoggerFactory.getLogger(OIDCProviderDataBinder.class);
+    private static final Logger LOG = LoggerFactory.getLogger(OIDCC4UIProviderDataBinder.class);
 
     @Autowired
     private AnyTypeDAO anyTypeDAO;
 
     @Autowired
-    private OIDCProviderDAO oidcOPDAO;
+    private OIDCC4UIProviderDAO oidcOPDAO;
 
     @Autowired
     private ImplementationDAO implementationDAO;
 
     @Autowired
-    private OIDCEntityFactory entityFactory;
+    private OIDCC4UIEntityFactory entityFactory;
 
     @Autowired
     private IntAttrNameParser intAttrNameParser;
 
     @Override
-    public OIDCProvider create(final OIDCProviderTO opTO) {
-        return update(entityFactory.newEntity(OIDCProvider.class), opTO);
+    public OIDCC4UIProvider create(final OIDCC4UIProviderTO opTO) {
+        return update(entityFactory.newEntity(OIDCC4UIProvider.class), opTO);
     }
 
-    private void populateItems(final OIDCProviderTO opTO, final OIDCProvider op) {
+    private void populateItems(final OIDCC4UIProviderTO opTO, final OIDCC4UIProvider op) {
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
         SyncopeClientException invalidMapping =
                 SyncopeClientException.build(ClientExceptionType.InvalidMapping);
@@ -108,7 +108,7 @@ public class OIDCProviderDataBinderImpl implements OIDCProviderDataBinder {
                         scce.addException(invalidMandatoryCondition);
                     }
 
-                    OIDCProviderItem item = entityFactory.newEntity(OIDCProviderItem.class);
+                    OIDCC4UIProviderItem item = entityFactory.newEntity(OIDCC4UIProviderItem.class);
                     item.setIntAttrName(itemTO.getIntAttrName());
                     item.setExtAttrName(itemTO.getExtAttrName());
                     item.setMandatoryCondition(itemTO.getMandatoryCondition());
@@ -145,7 +145,7 @@ public class OIDCProviderDataBinderImpl implements OIDCProviderDataBinder {
     }
 
     @Override
-    public OIDCProvider update(final OIDCProvider op, final OIDCProviderTO opTO) {
+    public OIDCC4UIProvider update(final OIDCC4UIProvider op, final OIDCC4UIProviderTO opTO) {
         op.setAuthorizationEndpoint(opTO.getAuthorizationEndpoint());
         op.setClientID(opTO.getClientID());
         op.setClientSecret(opTO.getClientSecret());
@@ -163,9 +163,9 @@ public class OIDCProviderDataBinderImpl implements OIDCProviderDataBinder {
         if (opTO.getUserTemplate() == null) {
             op.setUserTemplate(null);
         } else {
-            OIDCUserTemplate userTemplate = op.getUserTemplate();
+            OIDCC4UIUserTemplate userTemplate = op.getUserTemplate();
             if (userTemplate == null) {
-                userTemplate = entityFactory.newEntity(OIDCUserTemplate.class);
+                userTemplate = entityFactory.newEntity(OIDCC4UIUserTemplate.class);
                 userTemplate.setAnyType(anyTypeDAO.findUser());
                 userTemplate.setOP(op);
                 op.setUserTemplate(userTemplate);
@@ -190,7 +190,7 @@ public class OIDCProviderDataBinderImpl implements OIDCProviderDataBinder {
         return oidcOPDAO.save(op);
     }
 
-    private static void populateItems(final OIDCProvider op, final OIDCProviderTO opTO) {
+    private static void populateItems(final OIDCC4UIProvider op, final OIDCC4UIProviderTO opTO) {
         op.getItems().forEach(item -> {
             ItemTO itemTO = new ItemTO();
             itemTO.setKey(item.getKey());
@@ -212,8 +212,8 @@ public class OIDCProviderDataBinderImpl implements OIDCProviderDataBinder {
     }
 
     @Override
-    public OIDCProviderTO getOIDCProviderTO(final OIDCProvider op) {
-        OIDCProviderTO opTO = new OIDCProviderTO();
+    public OIDCC4UIProviderTO getOIDCProviderTO(final OIDCC4UIProvider op) {
+        OIDCC4UIProviderTO opTO = new OIDCC4UIProviderTO();
 
         opTO.setKey(op.getKey());
         opTO.setAuthorizationEndpoint(op.getAuthorizationEndpoint());
diff --git a/ext/oidcclient/rest-api/pom.xml b/ext/oidcc4ui/rest-api/pom.xml
similarity index 84%
rename from ext/oidcclient/rest-api/pom.xml
rename to ext/oidcc4ui/rest-api/pom.xml
index 2b1ff88..f1dc0c2 100644
--- a/ext/oidcclient/rest-api/pom.xml
+++ b/ext/oidcc4ui/rest-api/pom.xml
@@ -23,14 +23,14 @@ under the License.
 
   <parent>
     <groupId>org.apache.syncope.ext</groupId>
-    <artifactId>syncope-ext-oidcclient</artifactId>
+    <artifactId>syncope-ext-oidcc4ui</artifactId>
     <version>3.0.0-SNAPSHOT</version>
   </parent>
 
-  <name>Apache Syncope Ext: OIDC Client REST API</name>
-  <description>Apache Syncope Ext: OIDC Client REST API</description>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-rest-api</artifactId>
+  <name>Apache Syncope Ext: OIDC C4UI REST API</name>
+  <description>Apache Syncope Ext: OIDC C4UI REST API</description>
+  <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+  <artifactId>syncope-ext-oidcc4ui-rest-api</artifactId>
   <packaging>jar</packaging>
   
   <properties>
@@ -45,8 +45,8 @@ under the License.
     </dependency>
     
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-common-lib</artifactId>      
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-common-lib</artifactId>      
       <version>${project.version}</version>
     </dependency>    
   </dependencies>
diff --git a/ext/oidcclient/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCProviderService.java b/ext/oidcc4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCC4UIProviderService.java
similarity index 92%
rename from ext/oidcclient/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCProviderService.java
rename to ext/oidcc4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCC4UIProviderService.java
index de816d0..91d2bf0 100644
--- a/ext/oidcclient/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCProviderService.java
+++ b/ext/oidcc4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCC4UIProviderService.java
@@ -35,7 +35,7 @@ import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.to.OIDCProviderTO;
+import org.apache.syncope.common.lib.to.OIDCC4UIProviderTO;
 import java.util.List;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.PUT;
@@ -46,12 +46,12 @@ import org.apache.syncope.common.rest.api.RESTHeaders;
 /**
  * REST operations for OpenID Connect Providers.
  */
-@Tag(name = "OpenID Connect 1.0")
+@Tag(name = "OpenID Connect 1.0 C4UI")
 @SecurityRequirements({
     @SecurityRequirement(name = "BasicAuthentication"),
     @SecurityRequirement(name = "Bearer") })
-@Path("oidcclient/providers")
-public interface OIDCProviderService extends JAXRSService {
+@Path("oidcc4ui/providers")
+public interface OIDCC4UIProviderService extends JAXRSService {
 
     /**
      * Returns a list of all defined OIDC Providers.
@@ -60,7 +60,7 @@ public interface OIDCProviderService extends JAXRSService {
      */
     @GET
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
-    List<OIDCProviderTO> list();
+    List<OIDCC4UIProviderTO> list();
 
     /**
      * Returns the OIDC Provider with matching key, if available.
@@ -71,7 +71,7 @@ public interface OIDCProviderService extends JAXRSService {
     @GET
     @Path("{key}")
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
-    OIDCProviderTO read(@PathParam("key") String key);
+    OIDCC4UIProviderTO read(@PathParam("key") String key);
 
     /**
      * Creates a new OIDC Provider.
@@ -91,7 +91,7 @@ public interface OIDCProviderService extends JAXRSService {
     @POST
     @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
-    Response create(OIDCProviderTO oidcProviderTO);
+    Response create(OIDCC4UIProviderTO oidcProviderTO);
 
     /**
      * Creates a new OIDC Provider by using its Discovery Document.
@@ -112,7 +112,7 @@ public interface OIDCProviderService extends JAXRSService {
     @Path("fromDiscovery")
     @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
-    Response createFromDiscovery(OIDCProviderTO oidcProviderTO);
+    Response createFromDiscovery(OIDCC4UIProviderTO oidcProviderTO);
 
     /**
      * Updates the OIDC Provider with matching key.
@@ -127,7 +127,7 @@ public interface OIDCProviderService extends JAXRSService {
     @Path("{key}")
     @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
-    void update(@NotNull OIDCProviderTO oidcProviderTO);
+    void update(@NotNull OIDCC4UIProviderTO oidcProviderTO);
 
     /**
      * Deletes the OIDC Provider with matching key.
@@ -140,5 +140,4 @@ public interface OIDCProviderService extends JAXRSService {
     @Path("{key}")
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
     void delete(@PathParam("key") String key);
-
 }
diff --git a/ext/oidcclient/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCClientService.java b/ext/oidcc4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCC4UIService.java
similarity index 81%
rename from ext/oidcclient/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCClientService.java
rename to ext/oidcc4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCC4UIService.java
index 37851c5..be1a1f0 100644
--- a/ext/oidcclient/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCClientService.java
+++ b/ext/oidcc4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCC4UIService.java
@@ -26,21 +26,20 @@ import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
-import org.apache.syncope.common.lib.OIDCConstants;
-import org.apache.syncope.common.lib.to.OIDCLoginRequestTO;
-import org.apache.syncope.common.lib.to.OIDCLoginResponseTO;
-import org.apache.syncope.common.lib.to.OIDCLogoutRequestTO;
+import org.apache.syncope.common.lib.oidc.OIDCConstants;
+import org.apache.syncope.common.lib.oidc.OIDCRequest;
+import org.apache.syncope.common.lib.oidc.OIDCLoginResponse;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 
 /**
  * REST operations for OpenID Connect Clients.
  */
-@Tag(name = "OpenID Connect 1.0")
+@Tag(name = "OpenID Connect 1.0 C4UI")
 @SecurityRequirements({
     @SecurityRequirement(name = "BasicAuthentication"),
     @SecurityRequirement(name = "Bearer") })
-@Path("oidcclient/clients")
-public interface OIDCClientService extends JAXRSService {
+@Path("oidcc4ui/clients")
+public interface OIDCC4UIService extends JAXRSService {
 
     /**
      * Generates OpenID Connect authentication request for the Provider matching the provided op.
@@ -52,7 +51,7 @@ public interface OIDCClientService extends JAXRSService {
     @POST
     @Path("loginRequest")
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
-    OIDCLoginRequestTO createLoginRequest(
+    OIDCRequest createLoginRequest(
             @QueryParam(OIDCConstants.REDIRECT_URI) String redirectURI,
             @QueryParam(OIDCConstants.OP) String op);
 
@@ -68,20 +67,19 @@ public interface OIDCClientService extends JAXRSService {
     @POST
     @Path("login")
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
-    OIDCLoginResponseTO login(
+    OIDCLoginResponse login(
             @QueryParam(OIDCConstants.REDIRECT_URI) String redirectURI,
             @QueryParam("authorizationCode") String authorizationCode,
             @QueryParam(OIDCConstants.OP) String op);
 
     /**
-     * Returns the endSession endpoint for the provided op.
+     * Returns the endSession endpoint for the OP matching the requesting access token.
      *
-     * @param op OpenID Connect Provider
-     * @return endSession endpoint for the provided op
+     * @param redirectURI redirect URI
+     * @return endSession endpoint for the OP matching the requesting access token
      */
     @POST
     @Path("logout")
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
-    OIDCLogoutRequestTO createLogoutRequest(@QueryParam(OIDCConstants.OP) String op);
-
+    OIDCRequest createLogoutRequest(@QueryParam(OIDCConstants.REDIRECT_URI) String redirectURI);
 }
diff --git a/ext/oidcclient/rest-cxf/pom.xml b/ext/oidcc4ui/rest-cxf/pom.xml
similarity index 75%
rename from ext/oidcclient/rest-cxf/pom.xml
rename to ext/oidcc4ui/rest-cxf/pom.xml
index f675f44..c298fe9 100644
--- a/ext/oidcclient/rest-cxf/pom.xml
+++ b/ext/oidcc4ui/rest-cxf/pom.xml
@@ -23,14 +23,14 @@ under the License.
 
   <parent>
     <groupId>org.apache.syncope.ext</groupId>
-    <artifactId>syncope-ext-oidcclient</artifactId>
+    <artifactId>syncope-ext-oidcc4ui</artifactId>
     <version>3.0.0-SNAPSHOT</version>
   </parent>
 
-  <name>Apache Syncope Ext: OIDC Client REST CXF</name>
-  <description>Apache Syncope Ext: OIDC Client REST CXF</description>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-rest-cxf</artifactId>
+  <name>Apache Syncope Ext: OIDC C4UI REST CXF</name>
+  <description>Apache Syncope Ext: OIDC C4UI REST CXF</description>
+  <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+  <artifactId>syncope-ext-oidcc4ui-rest-cxf</artifactId>
   <packaging>jar</packaging>
   
   <properties>
@@ -44,19 +44,19 @@ under the License.
       <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-rest-api</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-rest-api</artifactId>
       <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-rest-api</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-rest-api</artifactId>
       <version>${project.version}</version>
       <classifier>javadoc</classifier>
     </dependency>
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-logic</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-logic</artifactId>
       <version>${project.version}</version>
     </dependency>
   </dependencies>
diff --git a/ext/oidcclient/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCProviderServiceImpl.java b/ext/oidcc4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCC4UIProviderServiceImpl.java
similarity index 74%
rename from ext/oidcclient/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCProviderServiceImpl.java
rename to ext/oidcc4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCC4UIProviderServiceImpl.java
index 7fc586e..8b4bcf4 100644
--- a/ext/oidcclient/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCProviderServiceImpl.java
+++ b/ext/oidcc4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCC4UIProviderServiceImpl.java
@@ -21,21 +21,21 @@ package org.apache.syncope.core.rest.cxf.service;
 import java.net.URI;
 import java.util.List;
 import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.to.OIDCProviderTO;
+import org.apache.syncope.common.lib.to.OIDCC4UIProviderTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.common.rest.api.service.OIDCProviderService;
-import org.apache.syncope.core.logic.OIDCProviderLogic;
+import org.apache.syncope.core.logic.OIDCC4UIProviderLogic;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.apache.syncope.common.rest.api.service.OIDCC4UIProviderService;
 
 @Service
-public class OIDCProviderServiceImpl extends AbstractServiceImpl implements OIDCProviderService {
+public class OIDCC4UIProviderServiceImpl extends AbstractServiceImpl implements OIDCC4UIProviderService {
 
     @Autowired
-    private OIDCProviderLogic logic;
+    private OIDCC4UIProviderLogic logic;
 
     @Override
-    public Response create(final OIDCProviderTO oidcProviderTO) {
+    public Response create(final OIDCC4UIProviderTO oidcProviderTO) {
         String created = logic.create(oidcProviderTO);
 
         URI location = uriInfo.getAbsolutePathBuilder().path(created).build();
@@ -45,7 +45,7 @@ public class OIDCProviderServiceImpl extends AbstractServiceImpl implements OIDC
     }
 
     @Override
-    public Response createFromDiscovery(final OIDCProviderTO oidcProviderTO) {
+    public Response createFromDiscovery(final OIDCC4UIProviderTO oidcProviderTO) {
         String created = logic.createFromDiscovery(oidcProviderTO);
 
         URI location = uriInfo.getAbsolutePathBuilder().path(created).build();
@@ -55,18 +55,18 @@ public class OIDCProviderServiceImpl extends AbstractServiceImpl implements OIDC
     }
 
     @Override
-    public List<OIDCProviderTO> list() {
+    public List<OIDCC4UIProviderTO> list() {
         return logic.list();
 
     }
 
     @Override
-    public OIDCProviderTO read(final String key) {
+    public OIDCC4UIProviderTO read(final String key) {
         return logic.read(key);
     }
 
     @Override
-    public void update(final OIDCProviderTO oidcProviderTO) {
+    public void update(final OIDCC4UIProviderTO oidcProviderTO) {
         logic.update(oidcProviderTO);
     }
 
diff --git a/ext/oidcclient/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCClientServiceImpl.java b/ext/oidcc4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCC4UIServiceImpl.java
similarity index 51%
rename from ext/oidcclient/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCClientServiceImpl.java
rename to ext/oidcc4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCC4UIServiceImpl.java
index f86de45..fa77fa5 100644
--- a/ext/oidcclient/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCClientServiceImpl.java
+++ b/ext/oidcc4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCC4UIServiceImpl.java
@@ -18,33 +18,43 @@
  */
 package org.apache.syncope.core.rest.cxf.service;
 
-import org.apache.syncope.common.lib.to.OIDCLoginRequestTO;
-import org.apache.syncope.common.rest.api.service.OIDCClientService;
-import org.apache.syncope.core.logic.OIDCClientLogic;
+import java.util.Optional;
+import javax.ws.rs.core.HttpHeaders;
+import org.apache.syncope.common.lib.oidc.OIDCRequest;
+import org.apache.syncope.core.logic.OIDCC4UILogic;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import org.apache.syncope.common.lib.to.OIDCLoginResponseTO;
-import org.apache.syncope.common.lib.to.OIDCLogoutRequestTO;
+import org.apache.syncope.common.lib.oidc.OIDCLoginResponse;
+import org.apache.syncope.common.rest.api.service.OIDCC4UIService;
 
 @Service
-public class OIDCClientServiceImpl extends AbstractServiceImpl implements OIDCClientService {
+public class OIDCC4UIServiceImpl extends AbstractServiceImpl implements OIDCC4UIService {
 
     @Autowired
-    private OIDCClientLogic logic;
+    private OIDCC4UILogic logic;
 
     @Override
-    public OIDCLoginRequestTO createLoginRequest(final String redirectURI, final String op) {
+    public OIDCRequest createLoginRequest(final String redirectURI, final String op) {
         return logic.createLoginRequest(redirectURI, op);
     }
 
     @Override
-    public OIDCLoginResponseTO login(final String redirectURI, final String authorizationCode, final String op) {
+    public OIDCLoginResponse login(final String redirectURI, final String authorizationCode, final String op) {
         return logic.login(redirectURI, authorizationCode, op);
     }
 
     @Override
-    public OIDCLogoutRequestTO createLogoutRequest(final String op) {
-        return logic.createLogoutRequest(op);
+    public OIDCRequest createLogoutRequest(final String redirectURI) {
+        return logic.createLogoutRequest(getAccessToken(), redirectURI);
     }
 
+    private String getAccessToken() {
+        String auth = messageContext.getHttpHeaders().getHeaderString(HttpHeaders.AUTHORIZATION);
+        String[] parts = Optional.ofNullable(auth).map(s -> s.split(" ")).orElse(null);
+        if (parts == null || parts.length != 2 || !"Bearer".equals(parts[0])) {
+            return null;
+        }
+
+        return parts[1];
+    }
 }
diff --git a/ext/oidcclient/agent/pom.xml b/ext/oidcclient/agent/pom.xml
deleted file mode 100644
index d0c37b7..0000000
--- a/ext/oidcclient/agent/pom.xml
+++ /dev/null
@@ -1,136 +0,0 @@
-<?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-oidcclient</artifactId>
-    <version>3.0.0-SNAPSHOT</version>
-  </parent>
-
-  <name>Apache Syncope Ext: OIDC Client Agent</name>
-  <description>Apache Syncope Ext: OIDC Client Agent</description>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-agent</artifactId>
-  <packaging>jar</packaging>
-  
-  <properties>
-    <rootpom.basedir>${basedir}/../../..</rootpom.basedir>
-  </properties>
-
-  <dependencies>
-    <dependency> 
-      <groupId>javax.servlet</groupId> 
-      <artifactId>javax.servlet-api</artifactId> 
-    </dependency>
-    <dependency>
-      <groupId>javax.servlet.jsp</groupId>
-      <artifactId>javax.servlet.jsp-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.taglibs</groupId>
-      <artifactId>taglibs-standard-impl</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.syncope.common.keymaster</groupId>
-      <artifactId>syncope-common-keymaster-client-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.syncope.client.idrepo</groupId>
-      <artifactId>syncope-client-idrepo-lib</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-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>
-      
-      <resource>
-        <directory>${basedir}</directory>
-        <targetPath>META-INF</targetPath>
-        <includes>
-          <include>LICENSE</include>
-          <include>NOTICE</include>
-        </includes>
-      </resource>
-    </resources>
-  </build>
-  
-  <profiles>
-    <profile>
-      <id>apache-release</id>
-
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-source-plugin</artifactId>
-            <inherited>false</inherited>
-            <executions>
-              <execution>
-                <id>attach-sources</id>
-                <goals>
-                  <goal>jar-no-fork</goal>
-                </goals>
-                <configuration>
-                  <includes>
-                    <include>${basedir}/LICENSE</include>
-                    <include>${basedir}/NOTICE</include>
-                  </includes>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
-</project>
diff --git a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/AbstractOIDCClientServlet.java b/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/AbstractOIDCClientServlet.java
deleted file mode 100644
index b484f56..0000000
--- a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/AbstractOIDCClientServlet.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.oidcclient.agent;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServlet;
-import org.apache.syncope.client.lib.AnonymousAuthenticationHandler;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
-import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
-import org.apache.syncope.common.keymaster.client.api.ServiceOps;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationContext;
-
-class AbstractOIDCClientServlet extends HttpServlet {
-
-    private static final long serialVersionUID = 4738590657326972169L;
-
-    protected static final Logger LOG = LoggerFactory.getLogger(AbstractOIDCClientServlet.class);
-
-    private static final String SYNCOPE_CLIENT_FACTORY = "SyncopeClientFactory";
-
-    private static final String SYNCOPE_ANONYMOUS_CLIENT = "SyncopeAnonymousClient";
-
-    private final ApplicationContext ctx;
-
-    protected AbstractOIDCClientServlet(final ApplicationContext ctx) {
-        super();
-        this.ctx = ctx;
-    }
-
-    protected SyncopeClientFactoryBean getClientFactory(
-            final ServletContext servletContext,
-            final boolean useGZIPCompression) {
-
-        SyncopeClientFactoryBean clientFactory =
-                (SyncopeClientFactoryBean) servletContext.getAttribute(SYNCOPE_CLIENT_FACTORY);
-        if (clientFactory == null) {
-            ServiceOps serviceOps = ctx.getBean(ServiceOps.class);
-            clientFactory = new SyncopeClientFactoryBean().
-                    setAddress(serviceOps.get(NetworkService.Type.CORE).getAddress()).
-                    setUseCompression(useGZIPCompression);
-
-            servletContext.setAttribute(SYNCOPE_CLIENT_FACTORY, clientFactory);
-        }
-
-        return clientFactory;
-    }
-
-    protected SyncopeClient getAnonymousClient(
-            final ServletContext servletContext,
-            final String anonymousUser,
-            final String anonymousKey,
-            final boolean useGZIPCompression) {
-
-        SyncopeClient anonymousClient = (SyncopeClient) servletContext.getAttribute(SYNCOPE_ANONYMOUS_CLIENT);
-        if (anonymousClient == null) {
-            SyncopeClientFactoryBean clientFactory = getClientFactory(servletContext, useGZIPCompression);
-            anonymousClient = clientFactory.create(new AnonymousAuthenticationHandler(anonymousUser, anonymousKey));
-
-            servletContext.setAttribute(SYNCOPE_ANONYMOUS_CLIENT, anonymousClient);
-        }
-
-        return anonymousClient;
-    }
-}
diff --git a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/BeforeLogout.java b/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/BeforeLogout.java
deleted file mode 100644
index 948865b..0000000
--- a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/BeforeLogout.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.oidcclient.agent;
-
-import java.io.IOException;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.UriBuilder;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
-import org.apache.syncope.common.lib.OIDCConstants;
-import org.apache.syncope.common.lib.to.OIDCLogoutRequestTO;
-import org.apache.syncope.common.rest.api.service.OIDCClientService;
-import org.springframework.context.ApplicationContext;
-
-public class BeforeLogout extends AbstractOIDCClientServlet {
-
-    private static final long serialVersionUID = -5920740403138557179L;
-
-    private final boolean useGZIPCompression;
-
-    public BeforeLogout(
-            final ApplicationContext ctx,
-            final boolean useGZIPCompression) {
-
-        super(ctx);
-        this.useGZIPCompression = useGZIPCompression;
-    }
-
-    @Override
-    protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
-            throws ServletException, IOException {
-
-        response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache, no-store");
-        response.setHeader("Pragma", "no-cache");
-        response.setStatus(HttpServletResponse.SC_SEE_OTHER);
-
-        String accessToken = (String) request.getSession().getAttribute(Constants.OIDCCLIENTJWT);
-        if (StringUtils.isBlank(accessToken)) {
-            throw new IllegalArgumentException("No access token found ");
-        }
-
-        SyncopeClientFactoryBean clientFactory = getClientFactory(request.getServletContext(), useGZIPCompression);
-        OIDCLogoutRequestTO requestTO = clientFactory.create(accessToken).getService(OIDCClientService.class).
-                createLogoutRequest(request.getSession().getAttribute(OIDCConstants.OP).toString());
-
-        String postLogoutRedirectURI = StringUtils.substringBefore(request.getRequestURL().toString(), "/beforelogout")
-                + "/logout";
-        UriBuilder ub = UriBuilder.fromUri(requestTO.getEndSessionEndpoint());
-        ub.queryParam(OIDCConstants.POST_LOGOUT_REDIRECT_URI, postLogoutRedirectURI);
-        response.setHeader(HttpHeaders.LOCATION, ub.build().toASCIIString());
-    }
-}
diff --git a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/CodeConsumer.java b/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/CodeConsumer.java
deleted file mode 100644
index 7ad6168..0000000
--- a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/CodeConsumer.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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.oidcclient.agent;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import java.io.IOException;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.OIDCConstants;
-import org.apache.syncope.common.lib.to.OIDCLoginResponseTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.rest.api.service.OIDCClientService;
-import org.springframework.context.ApplicationContext;
-
-public class CodeConsumer extends AbstractOIDCClientServlet {
-
-    private static final long serialVersionUID = 968480296813639041L;
-
-    private static final ObjectMapper MAPPER =
-            new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
-
-    private final String anonymousUser;
-
-    private final String anonymousKey;
-
-    private final boolean useGZIPCompression;
-
-    public CodeConsumer(
-            final ApplicationContext ctx,
-            final String anonymousUser,
-            final String anonymousKey,
-            final boolean useGZIPCompression) {
-
-        super(ctx);
-        this.anonymousUser = anonymousUser;
-        this.anonymousKey = anonymousKey;
-        this.useGZIPCompression = useGZIPCompression;
-    }
-
-    @Override
-    protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
-            throws ServletException, IOException {
-
-        try {
-            String authorizationCode = request.getParameter(OIDCConstants.CODE);
-            String state = request.getParameter(OIDCConstants.STATE);
-            if (StringUtils.isBlank(authorizationCode) || StringUtils.isBlank(state)) {
-                throw new IllegalArgumentException("Empty " + OIDCConstants.CODE + " or " + OIDCConstants.STATE);
-            }
-            if (state.equals(request.getSession().getAttribute(OIDCConstants.STATE).toString())) {
-                SyncopeClient anonymous = getAnonymousClient(
-                        request.getServletContext(), anonymousUser, anonymousKey, useGZIPCompression);
-
-                OIDCLoginResponseTO responseTO = anonymous.getService(OIDCClientService.class).login(
-                        request.getRequestURL().toString(),
-                        authorizationCode,
-                        request.getSession().getAttribute(OIDCConstants.OP).toString());
-                if (responseTO.isSelfReg()) {
-                    UserTO newUser = new UserTO();
-                    newUser.setUsername(responseTO.getUsername());
-                    newUser.getPlainAttrs().addAll(responseTO.getAttrs());
-                    request.getSession(true).
-                            setAttribute(Constants.OIDCC4UI_NEW_USER, MAPPER.writeValueAsString(newUser));
-
-                    String selfRegRedirectURL =
-                            getServletContext().getInitParameter(Constants.CONTEXT_PARAM_REDIRECT_SELFREG_URL);
-                    if (selfRegRedirectURL == null) {
-                        request.setAttribute("responseTO", responseTO);
-                        request.getRequestDispatcher("loginSuccess.jsp").forward(request, response);
-                    } else {
-                        response.sendRedirect(selfRegRedirectURL);
-                    }
-                } else {
-                    request.getSession().setAttribute(
-                            Constants.OIDCCLIENTJWT, responseTO.getAccessToken());
-                    request.getSession().setAttribute(
-                            Constants.OIDCCLIENTJWT_EXPIRE, responseTO.getAccessTokenExpiryTime());
-
-                    String successURL = getServletContext().getInitParameter(Constants.CONTEXT_PARAM_LOGIN_SUCCESS_URL);
-                    if (successURL == null) {
-                        request.setAttribute("responseTO", responseTO);
-                        request.getRequestDispatcher("loginSuccess.jsp").forward(request, response);
-                    } else {
-                        response.sendRedirect(successURL + "?logoutSupported=" + responseTO.isLogoutSupported());
-                    }
-                }
-            } else {
-                throw new IllegalArgumentException("Invalid " + OIDCConstants.STATE + " provided");
-            }
-        } catch (Exception e) {
-            LOG.error("While processing authentication response from OP", e);
-            String errorURL = getServletContext().getInitParameter(Constants.CONTEXT_PARAM_LOGIN_ERROR_URL);
-
-            if (errorURL == null) {
-                request.setAttribute("exception", e);
-                request.getRequestDispatcher("loginError.jsp").forward(request, response);
-
-                e.printStackTrace(response.getWriter());
-            } else {
-                response.sendRedirect(errorURL + "?errorMessage="
-                        + URLEncoder.encode(e.getMessage(), StandardCharsets.UTF_8));
-            }
-        }
-    }
-}
diff --git a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Constants.java b/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Constants.java
deleted file mode 100644
index e6c12f4..0000000
--- a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Constants.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.oidcclient.agent;
-
-public final class Constants {
-
-    public static final String URL_CONTEXT = "oidcc4ui";
-
-    public static final String PARAM_OP = "op";
-
-    public static final String CONTEXT_PARAM_LOGIN_SUCCESS_URL = "oidcclient.login.success.url";
-
-    public static final String CONTEXT_PARAM_LOGIN_ERROR_URL = "oidcclient.login.error.url";
-
-    public static final String CONTEXT_PARAM_LOGOUT_SUCCESS_URL = "oidcclient.logout.success.url";
-
-    public static final String CONTEXT_PARAM_LOGOUT_ERROR_URL = "oidcclient.logout.error.url";
-
-    public static final String CONTEXT_PARAM_REDIRECT_SELFREG_URL = "oidcclient.redirect.selfreg";
-
-    public static final String OIDCCLIENTJWT = "oidcclient.jwt";
-
-    public static final String OIDCCLIENTJWT_EXPIRE = "oidcclient.jwt.expire";
-
-    public static final String OIDCC4UI_NEW_USER = "oidcc4ui.newUser";
-
-    private Constants() {
-        // private constructor for static utility class
-    }
-}
diff --git a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Login.java b/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Login.java
deleted file mode 100644
index 7a637b9..0000000
--- a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Login.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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.oidcclient.agent;
-
-import java.io.IOException;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.UriBuilder;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.OIDCConstants;
-import org.apache.syncope.common.lib.to.OIDCLoginRequestTO;
-import org.apache.syncope.common.rest.api.service.OIDCClientService;
-import org.springframework.context.ApplicationContext;
-
-public class Login extends AbstractOIDCClientServlet {
-
-    private static final long serialVersionUID = 968480296813639041L;
-
-    private final String anonymousUser;
-
-    private final String anonymousKey;
-
-    private final boolean useGZIPCompression;
-
-    public Login(final ApplicationContext ctx,
-            final String anonymousUser,
-            final String anonymousKey,
-            final boolean useGZIPCompression) {
-
-        super(ctx);
-        this.anonymousUser = anonymousUser;
-        this.anonymousKey = anonymousKey;
-        this.useGZIPCompression = useGZIPCompression;
-    }
-
-    @Override
-    protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
-            throws ServletException, IOException {
-
-        String op = request.getParameter(Constants.PARAM_OP);
-
-        SyncopeClient anonymous =
-                getAnonymousClient(request.getServletContext(), anonymousUser, anonymousKey, useGZIPCompression);
-        try {
-            String redirectURI = StringUtils.substringBefore(request.getRequestURL().toString(), "/login")
-                    + "/code-consumer";
-            OIDCLoginRequestTO requestTO = anonymous.getService(OIDCClientService.class).
-                    createLoginRequest(redirectURI, op);
-
-            request.getSession().setAttribute(OIDCConstants.STATE, requestTO.getState());
-            request.getSession().setAttribute(OIDCConstants.OP, op);
-
-            response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache, no-store");
-            response.setHeader("Pragma", "no-cache");
-            response.setStatus(HttpServletResponse.SC_SEE_OTHER);
-
-            UriBuilder ub = UriBuilder.fromUri(requestTO.getProviderAddress());
-            ub.queryParam(OIDCConstants.CLIENT_ID, requestTO.getClientId());
-            ub.queryParam(OIDCConstants.REDIRECT_URI, requestTO.getRedirectURI());
-            ub.queryParam(OIDCConstants.RESPONSE_TYPE, requestTO.getResponseType());
-            ub.queryParam(OIDCConstants.SCOPE, requestTO.getScope());
-            ub.queryParam(OIDCConstants.STATE, requestTO.getState());
-            response.setHeader(HttpHeaders.LOCATION, ub.build().toASCIIString());
-        } catch (Exception e) {
-            LOG.error("While preparing the Authentication Request", e);
-
-            String errorURL = getServletContext().getInitParameter(Constants.CONTEXT_PARAM_LOGIN_ERROR_URL);
-            if (errorURL == null) {
-                request.setAttribute("exception", e);
-                request.getRequestDispatcher("loginError.jsp").forward(request, response);
-
-                e.printStackTrace(response.getWriter());
-            } else {
-                response.sendRedirect(errorURL + "?errorMessage="
-                        + URLEncoder.encode(e.getMessage(), StandardCharsets.UTF_8));
-            }
-        }
-    }
-}
diff --git a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Logout.java b/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Logout.java
deleted file mode 100644
index d948b30..0000000
--- a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Logout.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.oidcclient.agent;
-
-import java.io.IOException;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class Logout extends HttpServlet {
-
-    private static final long serialVersionUID = 2383239908659843071L;
-
-    protected static final Logger LOG = LoggerFactory.getLogger(Logout.class);
-
-    @Override
-    protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
-            throws ServletException, IOException {
-
-        try {
-            String successURL = getServletContext().getInitParameter(Constants.CONTEXT_PARAM_LOGOUT_SUCCESS_URL);
-            if (successURL == null) {
-                request.getRequestDispatcher("logoutSuccess.jsp").forward(request, response);
-            } else {
-                response.sendRedirect(successURL);
-            }
-            request.getSession().removeAttribute(Constants.OIDCCLIENTJWT);
-        } catch (Exception e) {
-            LOG.error("While processing authentication response from IdP", e);
-
-            String errorURL = getServletContext().getInitParameter(Constants.CONTEXT_PARAM_LOGOUT_ERROR_URL);
-            if (errorURL == null) {
-                request.setAttribute("exception", e);
-                request.getRequestDispatcher("logoutError.jsp").forward(request, response);
-
-                e.printStackTrace(response.getWriter());
-            } else {
-                response.sendRedirect(errorURL + "?errorMessage="
-                        + URLEncoder.encode(e.getMessage(), StandardCharsets.UTF_8));
-            }
-        }
-    }
-}
diff --git a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/OIDCClientAgentContext.java b/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/OIDCClientAgentContext.java
deleted file mode 100644
index 61a346a..0000000
--- a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/OIDCClientAgentContext.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.oidcclient.agent;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.web.servlet.ServletRegistrationBean;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.PropertySource;
-
-@PropertySource("classpath:oidcclient-agent.properties")
-@PropertySource(value = "file:${conf.directory}/oidcclient-agent.properties", ignoreResourceNotFound = true)
-@Configuration
-public class OIDCClientAgentContext {
-
-    @Value("${anonymousUser}")
-    private String anonymousUser;
-
-    @Value("${anonymousKey}")
-    private String anonymousKey;
-
-    @Value("${useGZIPCompression}")
-    private boolean useGZIPCompression;
-
-    @Autowired
-    private ApplicationContext ctx;
-
-    @Bean
-    public ServletRegistrationBean<Login> oidcClientLogin() {
-        ServletRegistrationBean<Login> bean = new ServletRegistrationBean<>(
-                new Login(ctx, anonymousUser, anonymousKey, useGZIPCompression), "/oidcclient/login");
-        bean.setName("oidcClientLogin");
-        return bean;
-    }
-
-    @Bean
-    public ServletRegistrationBean<CodeConsumer> oidcClientCodeConsumer() {
-        ServletRegistrationBean<CodeConsumer> bean = new ServletRegistrationBean<>(
-                new CodeConsumer(ctx, anonymousUser, anonymousKey, useGZIPCompression), "/oidcclient/code-consumer");
-        bean.setName("oidcClientCodeConsumer");
-        return bean;
-    }
-
-    @Bean
-    public ServletRegistrationBean<BeforeLogout> oidcClientBeforeLogout() {
-        ServletRegistrationBean<BeforeLogout> bean =
-                new ServletRegistrationBean<>(new BeforeLogout(ctx, useGZIPCompression), "/oidcclient/beforelogout");
-        bean.setName("oidcClientBeforeLogout");
-        return bean;
-    }
-
-    @Bean
-    public ServletRegistrationBean<Logout> oidcClientLogout() {
-        ServletRegistrationBean<Logout> bean = new ServletRegistrationBean<>(new Logout(), "/oidcclient/logout");
-        bean.setName("oidcClientLogout");
-        return bean;
-    }
-}
diff --git a/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/loginError.jsp b/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/loginError.jsp
deleted file mode 100644
index b3c80d9..0000000
--- a/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/loginError.jsp
+++ /dev/null
@@ -1,35 +0,0 @@
-<%--
-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.
---%>
-<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
-<%
-    Exception exception = (Exception) request.getAttribute("exception");
-%>
-<html>
-  <head>
-    <title>Apache Syncope ${syncope.version} - OIDC CLIENT - Login Error</title>
-  </head>
-  <body>
-    <h1>An error was found</h1>
-
-    <h2><%=exception.getMessage()%></h2>
-    <pre>
-      <%exception.printStackTrace(new java.io.PrintWriter(out));%>
-    </pre>
-  </body>
-</html>
\ No newline at end of file
diff --git a/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/loginSuccess.jsp b/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/loginSuccess.jsp
deleted file mode 100644
index 7c28904..0000000
--- a/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/loginSuccess.jsp
+++ /dev/null
@@ -1,33 +0,0 @@
-<%--
-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.
---%>
-<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
-<%@page import="org.apache.syncope.common.lib.to.OIDCLoginResponseTO"%>
-<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
-<c:set var="responseTO" value="${requestScope['responseTO']}"/>
-<html>
-  <head>
-    <title>Apache Syncope ${syncope.version} - OIDC CLIENT - Successful Login</title>
-  </head>
-  <body>
-    <h1>Welcome ${responseTO.username}</h1>
-
-    <p>You have been successfully authenticated by the requested OIDC Provider</p>
-
-  </body>
-</html>
\ No newline at end of file
diff --git a/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/logoutError.jsp b/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/logoutError.jsp
deleted file mode 100644
index df0cb3d..0000000
--- a/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/logoutError.jsp
+++ /dev/null
@@ -1,35 +0,0 @@
-<%--
-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.
---%>
-<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
-<%
-    Exception exception = (Exception) request.getAttribute("exception");
-%>
-<html>
-  <head>
-    <title>Apache Syncope ${syncope.version} - OIDC CLIENT - Logout Error</title>
-  </head>
-  <body>
-    <h1>An error was found</h1>
-
-    <h2><%=exception.getMessage()%></h2>
-    <pre>
-      <%exception.printStackTrace(new java.io.PrintWriter(out));%>
-    </pre>
-  </body>
-</html>
\ No newline at end of file
diff --git a/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/logoutSuccess.jsp b/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/logoutSuccess.jsp
deleted file mode 100644
index ecbdc77..0000000
--- a/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/logoutSuccess.jsp
+++ /dev/null
@@ -1,27 +0,0 @@
-<%--
-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.
---%>
-<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
-<html>
-  <head>
-    <title>Apache Syncope ${syncope.version} - OIDC CLIENT - Successful Logout</title>
-  </head>
-  <body>
-    <h1>You have been successfully logged out.</h1>
-  </body>
-</html>
\ No newline at end of file
diff --git a/ext/oidcclient/agent/src/main/resources/META-INF/spring.factories b/ext/oidcclient/agent/src/main/resources/META-INF/spring.factories
deleted file mode 100644
index 344c41d..0000000
--- a/ext/oidcclient/agent/src/main/resources/META-INF/spring.factories
+++ /dev/null
@@ -1,19 +0,0 @@
-# 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.
-
-org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-  org.apache.syncope.ext.oidcclient.agent.OIDCClientAgentContext
diff --git a/ext/oidcclient/agent/src/main/resources/META-INF/web-fragment.xml b/ext/oidcclient/agent/src/main/resources/META-INF/web-fragment.xml
deleted file mode 100644
index 2379292..0000000
--- a/ext/oidcclient/agent/src/main/resources/META-INF/web-fragment.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?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_4_0.xsd"
-              id="${pom.artifactId}" version="4.0">
-
-</web-fragment>
\ No newline at end of file
diff --git a/ext/oidcclient/agent/src/main/resources/oidcclient-agent.properties b/ext/oidcclient/agent/src/main/resources/oidcclient-agent.properties
deleted file mode 100644
index 7e5b0d5..0000000
--- a/ext/oidcclient/agent/src/main/resources/oidcclient-agent.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-# 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.
-conf.directory=${conf.directory}
-
-anonymousUser=${anonymousUser}
-anonymousKey=${anonymousKey}
-
-useGZIPCompression=true
diff --git a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCClient_it.properties b/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCClient_it.properties
deleted file mode 100644
index b34f11c..0000000
--- a/ext/oidcclient/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCClient_it.properties
+++ /dev/null
@@ -1,17 +0,0 @@
-# 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.
-op=OIDC Providers
diff --git a/ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/to/OIDCLoginRequestTO.java b/ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/to/OIDCLoginRequestTO.java
deleted file mode 100644
index 8189809..0000000
--- a/ext/oidcclient/common-lib/src/main/java/org/apache/syncope/common/lib/to/OIDCLoginRequestTO.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.common.lib.to;
-
-import java.io.Serializable;
-
-public class OIDCLoginRequestTO implements Serializable {
-
-    private static final long serialVersionUID = -3509031322459942441L;
-
-    private String providerAddress;
-
-    private String clientId;
-
-    private String scope;
-
-    private String responseType;
-
-    private String redirectURI;
-
-    private String state;
-
-    public String getProviderAddress() {
-        return providerAddress;
-    }
-
-    public void setProviderAddress(final String providerAddress) {
-        this.providerAddress = providerAddress;
-    }
-
-    public String getClientId() {
-        return clientId;
-    }
-
-    public void setClientId(final String clientId) {
-        this.clientId = clientId;
-    }
-
-    public String getScope() {
-        return scope;
-    }
-
-    public void setScope(final String scope) {
-        this.scope = scope;
-    }
-
-    public String getResponseType() {
-        return responseType;
-    }
-
-    public void setResponseType(final String responseType) {
-        this.responseType = responseType;
-    }
-
-    public String getRedirectURI() {
-        return redirectURI;
-    }
-
-    public void setRedirectURI(final String redirectURI) {
-        this.redirectURI = redirectURI;
-    }
-
-    public String getState() {
-        return state;
-    }
-
-    public void setState(final String state) {
-        this.state = state;
-    }
-
-}
diff --git a/ext/oidcclient/logic/pom.xml b/ext/oidcclient/logic/pom.xml
deleted file mode 100644
index 94c73dc..0000000
--- a/ext/oidcclient/logic/pom.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?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-oidcclient</artifactId>
-    <version>3.0.0-SNAPSHOT</version>
-  </parent>
-
-  <name>Apache Syncope Ext: OIDC Client Logic</name>
-  <description>Apache Syncope Ext: OIDC Client Logic</description>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-logic</artifactId>
-  <packaging>jar</packaging>
-  
-  <properties>
-    <rootpom.basedir>${basedir}/../../..</rootpom.basedir>
-  </properties>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.syncope.core.idm</groupId>
-      <artifactId>syncope-core-idm-logic</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    
-    <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-provisioning-java</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    
-    <dependency>
-      <groupId>org.apache.cxf</groupId>
-      <artifactId>cxf-rt-rs-extension-providers</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cxf</groupId>
-      <artifactId>cxf-rt-rs-security-sso-oidc</artifactId>
-    </dependency>
-    
-    <dependency>
-      <groupId>com.fasterxml.jackson.jaxrs</groupId>
-      <artifactId>jackson-jaxrs-json-provider</artifactId>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/OIDCClientLogic.java b/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/OIDCClientLogic.java
deleted file mode 100644
index 61ae570..0000000
--- a/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/OIDCClientLogic.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * 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.core.logic;
-
-import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Method;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.cxf.helpers.IOUtils;
-import org.apache.cxf.jaxrs.client.WebClient;
-import org.apache.cxf.jaxrs.provider.json.JsonMapObjectProvider;
-import org.apache.cxf.rs.security.jose.jaxrs.JsonWebKeysProvider;
-import org.apache.cxf.rs.security.oauth2.client.Consumer;
-import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
-import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
-import org.apache.cxf.rs.security.oidc.common.AbstractUserInfo;
-import org.apache.cxf.rs.security.oidc.common.IdToken;
-import org.apache.cxf.rs.security.oidc.common.UserInfo;
-import org.apache.cxf.rs.security.oidc.rp.IdTokenReader;
-import org.apache.cxf.rs.security.oidc.rp.UserInfoClient;
-import org.apache.syncope.common.lib.Attr;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.EntityTO;
-import org.apache.syncope.common.lib.to.OIDCLoginRequestTO;
-import org.apache.syncope.common.lib.to.OIDCLoginResponseTO;
-import org.apache.syncope.common.lib.to.OIDCLogoutRequestTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.IdRepoEntitlement;
-import org.apache.syncope.core.logic.model.TokenEndpointResponse;
-import org.apache.syncope.core.logic.oidc.OIDCUserManager;
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.dao.OIDCProviderDAO;
-import org.apache.syncope.core.persistence.api.entity.OIDCProvider;
-import org.apache.syncope.core.persistence.api.entity.OIDCProviderItem;
-import org.apache.syncope.core.provisioning.api.data.AccessTokenDataBinder;
-import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
-import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.apache.syncope.core.spring.security.AuthDataAccessor;
-import org.apache.syncope.core.spring.security.Encryptor;
-import org.apache.syncope.core.spring.security.SecureRandomUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
-
-@Component
-public class OIDCClientLogic extends AbstractTransactionalLogic<EntityTO> {
-
-    private static final String JWT_CLAIM_OP_ENTITYID = "OP_ENTITYID";
-
-    private static final String JWT_CLAIM_USERID = "USERID";
-
-    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
-
-    @Autowired
-    private AuthDataAccessor authDataAccessor;
-
-    @Autowired
-    private AccessTokenDataBinder accessTokenDataBinder;
-
-    @Autowired
-    private OIDCProviderDAO opDAO;
-
-    @Autowired
-    private OIDCUserManager userManager;
-
-    private OIDCProvider getOIDCProvider(final String opName) {
-        OIDCProvider op = null;
-        if (StringUtils.isBlank(opName)) {
-            List<OIDCProvider> ops = opDAO.findAll();
-            if (!ops.isEmpty()) {
-                op = ops.get(0);
-            }
-        } else {
-            op = opDAO.findByName(opName);
-        }
-        if (op == null) {
-            throw new NotFoundException(StringUtils.isBlank(opName)
-                    ? "Any OIDC Provider"
-                    : "OIDC Provider '" + opName + '\'');
-        }
-        return op;
-    }
-
-    @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
-    public OIDCLoginRequestTO createLoginRequest(final String redirectURI, final String opName) {
-        // 1. look for Provider
-        OIDCProvider op = getOIDCProvider(opName);
-
-        // 2. create AuthnRequest
-        OIDCLoginRequestTO requestTO = new OIDCLoginRequestTO();
-        requestTO.setProviderAddress(op.getAuthorizationEndpoint());
-        requestTO.setClientId(op.getClientID());
-        requestTO.setScope("openid email profile");
-        requestTO.setResponseType(OAuthConstants.CODE_RESPONSE_TYPE);
-        requestTO.setRedirectURI(redirectURI);
-        requestTO.setState(SecureRandomUtils.generateRandomUUID().toString());
-        return requestTO;
-    }
-
-    @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
-    public OIDCLoginResponseTO login(final String redirectURI, final String authorizationCode, final String opName) {
-        OIDCProvider op = getOIDCProvider(opName);
-
-        // 1. get OpenID Connect tokens
-        String body = OAuthConstants.AUTHORIZATION_CODE_VALUE + '=' + authorizationCode
-                + '&' + OAuthConstants.CLIENT_ID + '=' + op.getClientID()
-                + '&' + OAuthConstants.CLIENT_SECRET + '=' + op.getClientSecret()
-                + '&' + OAuthConstants.REDIRECT_URI + '=' + redirectURI
-                + '&' + OAuthConstants.GRANT_TYPE + '=' + OAuthConstants.AUTHORIZATION_CODE_GRANT;
-        TokenEndpointResponse tokenEndpointResponse;
-        try {
-            tokenEndpointResponse = getOIDCTokens(op.getTokenEndpoint(), body);
-        } catch (IOException e) {
-            LOG.error("Unexpected response for OIDC Tokens", e);
-
-            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unknown);
-            sce.getElements().add("Unexpected response for OIDC Tokens: " + e.getMessage());
-            throw sce;
-        }
-
-        Consumer consumer = new Consumer(op.getClientID(), op.getClientSecret());
-
-        // 2. validate token
-        LOG.debug("Id Token to be validated: {}", tokenEndpointResponse.getIdToken());
-        IdToken idToken = getValidatedIdToken(op, consumer, tokenEndpointResponse.getIdToken());
-
-        // 3. prepare the result:
-        final OIDCLoginResponseTO responseTO = new OIDCLoginResponseTO();
-        responseTO.setLogoutSupported(StringUtils.isNotBlank(op.getEndSessionEndpoint()));
-
-        // 3a. extract user info from userInfoEndpoint if exists otherwise from idToken
-        AbstractUserInfo userInfo = StringUtils.isBlank(op.getUserinfoEndpoint())
-                ? idToken
-                : getUserInfo(op.getUserinfoEndpoint(), tokenEndpointResponse.getAccessToken(), idToken, consumer);
-
-        // 3b. find matching user (if any) and return the received attributes
-        String keyValue = userInfo.getEmail();
-        for (OIDCProviderItem item : op.getItems()) {
-            Attr attrTO = new Attr();
-            attrTO.setSchema(item.getExtAttrName());
-            switch (item.getExtAttrName()) {
-                case UserInfo.PREFERRED_USERNAME_CLAIM:
-                    attrTO.getValues().add(userInfo.getPreferredUserName());
-                    responseTO.getAttrs().add(attrTO);
-                    if (item.isConnObjectKey()) {
-                        keyValue = userInfo.getPreferredUserName();
-                    }
-                    break;
-
-                case UserInfo.PROFILE_CLAIM:
-                    attrTO.getValues().add(userInfo.getProfile());
-                    responseTO.getAttrs().add(attrTO);
-                    if (item.isConnObjectKey()) {
-                        keyValue = userInfo.getProfile();
-                    }
-                    break;
-
-                case UserInfo.EMAIL_CLAIM:
-                    attrTO.getValues().add(userInfo.getEmail());
-                    responseTO.getAttrs().add(attrTO);
-                    if (item.isConnObjectKey()) {
-                        keyValue = userInfo.getEmail();
-                    }
-                    break;
-
-                case UserInfo.NAME_CLAIM:
-                    attrTO.getValues().add(userInfo.getName());
-                    responseTO.getAttrs().add(attrTO);
-                    if (item.isConnObjectKey()) {
-                        keyValue = userInfo.getName();
-                    }
-                    break;
-
-                case UserInfo.FAMILY_NAME_CLAIM:
-                    attrTO.getValues().add(userInfo.getFamilyName());
-                    responseTO.getAttrs().add(attrTO);
-                    if (item.isConnObjectKey()) {
-                        keyValue = userInfo.getFamilyName();
-                    }
-                    break;
-
-                case UserInfo.MIDDLE_NAME_CLAIM:
-                    attrTO.getValues().add(userInfo.getMiddleName());
-                    responseTO.getAttrs().add(attrTO);
-                    if (item.isConnObjectKey()) {
-                        keyValue = userInfo.getMiddleName();
-                    }
-                    break;
-
-                case UserInfo.GIVEN_NAME_CLAIM:
-                    attrTO.getValues().add(userInfo.getGivenName());
-                    responseTO.getAttrs().add(attrTO);
-                    if (item.isConnObjectKey()) {
-                        keyValue = userInfo.getGivenName();
-                    }
-                    break;
-
-                case UserInfo.NICKNAME_CLAIM:
-                    attrTO.getValues().add(userInfo.getNickName());
-                    responseTO.getAttrs().add(attrTO);
-                    if (item.isConnObjectKey()) {
-                        keyValue = userInfo.getNickName();
-                    }
-                    break;
-
-                case UserInfo.GENDER_CLAIM:
-                    attrTO.getValues().add(userInfo.getGender());
-                    responseTO.getAttrs().add(attrTO);
-                    if (item.isConnObjectKey()) {
-                        keyValue = userInfo.getGender();
-                    }
-                    break;
-
-                case UserInfo.LOCALE_CLAIM:
-                    attrTO.getValues().add(userInfo.getLocale());
-                    responseTO.getAttrs().add(attrTO);
-                    if (item.isConnObjectKey()) {
-                        keyValue = userInfo.getLocale();
-                    }
-                    break;
-
-                case UserInfo.ZONEINFO_CLAIM:
-                    attrTO.getValues().add(userInfo.getZoneInfo());
-                    responseTO.getAttrs().add(attrTO);
-                    if (item.isConnObjectKey()) {
-                        keyValue = userInfo.getZoneInfo();
-                    }
-                    break;
-
-                case UserInfo.BIRTHDATE_CLAIM:
-                    attrTO.getValues().add(userInfo.getBirthDate());
-                    responseTO.getAttrs().add(attrTO);
-                    if (item.isConnObjectKey()) {
-                        keyValue = userInfo.getBirthDate();
-                    }
-                    break;
-
-                case UserInfo.PHONE_CLAIM:
-                    attrTO.getValues().add(userInfo.getPhoneNumber());
-                    responseTO.getAttrs().add(attrTO);
-                    if (item.isConnObjectKey()) {
-                        keyValue = userInfo.getPhoneNumber();
-                    }
-                    break;
-
-                case UserInfo.ADDRESS_CLAIM:
-                    attrTO.getValues().add(userInfo.getUserAddress().getFormatted());
-                    responseTO.getAttrs().add(attrTO);
-                    if (item.isConnObjectKey()) {
-                        keyValue = userInfo.getUserAddress().getFormatted();
-                    }
-                    break;
-
-                case UserInfo.UPDATED_AT_CLAIM:
-                    attrTO.getValues().add(Long.toString(userInfo.getUpdatedAt()));
-                    responseTO.getAttrs().add(attrTO);
-                    if (item.isConnObjectKey()) {
-                        keyValue = Long.toString(userInfo.getUpdatedAt());
-                    }
-                    break;
-
-                default:
-                    String value = userInfo.getClaim(item.getExtAttrName()) == null
-                            ? null
-                            : userInfo.getClaim(item.getExtAttrName()).toString();
-                    attrTO.getValues().add(value);
-                    responseTO.getAttrs().add(attrTO);
-                    if (item.isConnObjectKey()) {
-                        keyValue = value;
-                    }
-            }
-        }
-
-        final List<String> matchingUsers = keyValue == null
-                ? List.of()
-                : userManager.findMatchingUser(keyValue, op.getConnObjectKeyItem().get());
-        LOG.debug("Found {} matching users for {}", matchingUsers.size(), keyValue);
-
-        String username;
-        if (matchingUsers.isEmpty()) {
-            if (op.isCreateUnmatching()) {
-                LOG.debug("No user matching {}, about to create", keyValue);
-
-                final String emailValue = userInfo.getEmail();
-                username = AuthContextUtils.callAsAdmin(AuthContextUtils.getDomain(),
-                        () -> userManager.create(op, responseTO, emailValue));
-            } else if (op.isSelfRegUnmatching()) {
-                UserTO userTO = new UserTO();
-
-                userManager.fill(op, responseTO, userTO);
-
-                responseTO.getAttrs().clear();
-                responseTO.getAttrs().addAll(userTO.getPlainAttrs());
-                responseTO.getAttrs().addAll(userTO.getVirAttrs());
-                if (StringUtils.isNotBlank(userTO.getUsername())) {
-                    responseTO.setUsername(userTO.getUsername());
-                }
-
-                responseTO.setSelfReg(true);
-
-                return responseTO;
-            } else {
-                throw new NotFoundException(Optional.ofNullable(keyValue)
-                    .map(value -> "User matching the provided value " + value)
-                    .orElse("User marching the provided claims"));
-            }
-        } else if (matchingUsers.size() > 1) {
-            throw new IllegalArgumentException("Several users match the provided value " + keyValue);
-        } else {
-            if (op.isUpdateMatching()) {
-                LOG.debug("About to update {} for {}", matchingUsers.get(0), keyValue);
-
-                username = AuthContextUtils.callAsAdmin(AuthContextUtils.getDomain(),
-                        () -> userManager.update(matchingUsers.get(0), op, responseTO));
-            } else {
-                username = matchingUsers.get(0);
-            }
-
-        }
-
-        responseTO.setUsername(username);
-
-        // 4. generate JWT for further access
-        Map<String, Object> claims = new HashMap<>();
-        claims.put(JWT_CLAIM_OP_ENTITYID, idToken.getIssuer());
-        claims.put(JWT_CLAIM_USERID, idToken.getSubject());
-
-        byte[] authorities = null;
-        try {
-            authorities = ENCRYPTOR.encode(POJOHelper.serialize(
-                    authDataAccessor.getAuthorities(responseTO.getUsername())), CipherAlgorithm.AES).
-                    getBytes();
-        } catch (Exception e) {
-            LOG.error("Could not fetch authorities", e);
-        }
-
-        Pair<String, Date> accessTokenInfo =
-                accessTokenDataBinder.create(responseTO.getUsername(), claims, authorities, true);
-        responseTO.setAccessToken(accessTokenInfo.getLeft());
-        responseTO.setAccessTokenExpiryTime(accessTokenInfo.getRight());
-
-        return responseTO;
-    }
-
-    private static TokenEndpointResponse getOIDCTokens(final String url, final String body) throws IOException {
-        Response response = WebClient.create(url, List.of(new JacksonJsonProvider())).
-                type(MediaType.APPLICATION_FORM_URLENCODED).accept(MediaType.APPLICATION_JSON).
-                post(body);
-        if (response.getStatus() != Response.Status.OK.getStatusCode()) {
-            LOG.error("Unexpected response from OIDC Provider: {}\n{}\n{}",
-                    response.getStatus(), response.getHeaders(),
-                    IOUtils.toString((InputStream) response.getEntity()));
-
-            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unknown);
-            sce.getElements().add("Unexpected response from OIDC Provider");
-            throw sce;
-        }
-
-        return response.readEntity(TokenEndpointResponse.class);
-    }
-
-    private static IdToken getValidatedIdToken(final OIDCProvider op, final Consumer consumer,
-                                               final String jwtIdToken) {
-        IdTokenReader idTokenReader = new IdTokenReader();
-        idTokenReader.setClockOffset(10);
-        idTokenReader.setIssuerId(op.getIssuer());
-        idTokenReader.setJwkSetClient(WebClient.create(op.getJwksUri(), List.of(new JsonWebKeysProvider())).
-                accept(MediaType.APPLICATION_JSON));
-        IdToken idToken;
-        try {
-            idToken = idTokenReader.getIdToken(jwtIdToken, consumer);
-        } catch (Exception e) {
-            LOG.error("While validating the id_token", e);
-            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unknown);
-            sce.getElements().add(e.getMessage());
-            throw sce;
-        }
-        return idToken;
-    }
-
-    private static UserInfo getUserInfo(
-        final String endpoint,
-        final String accessToken,
-        final IdToken idToken,
-        final Consumer consumer) {
-
-        WebClient userInfoServiceClient = WebClient.create(endpoint, List.of(new JsonMapObjectProvider())).
-                accept(MediaType.APPLICATION_JSON);
-        ClientAccessToken clientAccessToken =
-                new ClientAccessToken(OAuthConstants.BEARER_AUTHORIZATION_SCHEME, accessToken);
-        UserInfoClient userInfoClient = new UserInfoClient();
-        userInfoClient.setUserInfoServiceClient(userInfoServiceClient);
-        UserInfo userInfo = null;
-        try {
-            userInfo = userInfoClient.getUserInfo(clientAccessToken, idToken, consumer);
-        } catch (Exception e) {
-            LOG.error("While getting the userInfo", e);
-            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unknown);
-            sce.getElements().add(e.getMessage());
-            throw sce;
-        }
-        return userInfo;
-    }
-
-    @PreAuthorize("isAuthenticated() and not(hasRole('" + IdRepoEntitlement.ANONYMOUS + "'))")
-    public OIDCLogoutRequestTO createLogoutRequest(final String op) {
-        OIDCLogoutRequestTO logoutRequest = new OIDCLogoutRequestTO();
-        logoutRequest.setEndSessionEndpoint(getOIDCProvider(op).getEndSessionEndpoint());
-        return logoutRequest;
-    }
-
-    @Override
-    protected EntityTO resolveReference(
-            final Method method, final Object... args) throws UnresolvedReferenceException {
-
-        throw new UnresolvedReferenceException();
-    }
-}
diff --git a/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/OIDCProviderLogic.java b/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/OIDCProviderLogic.java
deleted file mode 100644
index f093e78..0000000
--- a/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/OIDCProviderLogic.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * 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.core.logic;
-
-import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.stream.Collectors;
-import javax.ws.rs.ClientErrorException;
-import javax.ws.rs.core.MediaType;
-import org.apache.commons.lang3.ArrayUtils;
-import org.apache.cxf.jaxrs.client.WebClient;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.ItemTO;
-import org.apache.syncope.common.lib.to.OIDCProviderTO;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.OIDCClientEntitlement;
-import org.apache.syncope.core.logic.model.OIDCProviderDiscoveryDocument;
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.dao.OIDCProviderDAO;
-import org.apache.syncope.core.persistence.api.entity.OIDCProvider;
-import org.apache.syncope.core.provisioning.api.data.OIDCProviderDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-@Component
-public class OIDCProviderLogic extends AbstractTransactionalLogic<OIDCProviderTO> {
-
-    @Autowired
-    private OIDCProviderDAO opDAO;
-
-    @Autowired
-    private OIDCProviderDataBinder binder;
-
-    private static OIDCProviderDiscoveryDocument getDiscoveryDocument(final String issuer) {
-        String discoveryDocumentURL = issuer + "/.well-known/openid-configuration";
-        WebClient client = WebClient.create(discoveryDocumentURL, List.of(new JacksonJsonProvider())).
-                accept(MediaType.APPLICATION_JSON);
-        try {
-            return client.get(OIDCProviderDiscoveryDocument.class);
-        } catch (ClientErrorException e) {
-            LOG.error("While getting the Discovery Document at {}", discoveryDocumentURL, e);
-
-            if (e instanceof javax.ws.rs.NotFoundException) {
-                throw new NotFoundException("Discovery Document cannot be found at " + discoveryDocumentURL);
-            } else {
-                SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unknown);
-                sce.getElements().add(e.getMessage());
-                throw sce;
-            }
-        }
-    }
-
-    @PreAuthorize("hasRole('" + OIDCClientEntitlement.OP_CREATE + "')")
-    public String createFromDiscovery(final OIDCProviderTO opTO) {
-        OIDCProviderDiscoveryDocument discoveryDocument = getDiscoveryDocument(opTO.getIssuer());
-
-        opTO.setAuthorizationEndpoint(discoveryDocument.getAuthorizationEndpoint());
-        opTO.setIssuer(discoveryDocument.getIssuer());
-        opTO.setJwksUri(discoveryDocument.getJwksUri());
-        opTO.setTokenEndpoint(discoveryDocument.getTokenEndpoint());
-        opTO.setUserinfoEndpoint(discoveryDocument.getUserinfoEndpoint());
-        opTO.setEndSessionEndpoint(discoveryDocument.getEndSessionEndpoint());
-
-        return create(opTO);
-    }
-
-    @PreAuthorize("hasRole('" + OIDCClientEntitlement.OP_CREATE + "')")
-    public String create(final OIDCProviderTO opTO) {
-        if (opTO.getConnObjectKeyItem() == null) {
-            ItemTO connObjectKeyItem = new ItemTO();
-            connObjectKeyItem.setIntAttrName("username");
-            connObjectKeyItem.setExtAttrName("email");
-            opTO.setConnObjectKeyItem(connObjectKeyItem);
-        }
-
-        OIDCProvider provider = opDAO.save(binder.create(opTO));
-
-        return provider.getKey();
-    }
-
-    @PreAuthorize("isAuthenticated()")
-    @Transactional(readOnly = true)
-    public List<OIDCProviderTO> list() {
-        return opDAO.findAll().stream().map(binder::getOIDCProviderTO).collect(Collectors.toList());
-    }
-
-    @PreAuthorize("hasRole('" + OIDCClientEntitlement.OP_READ + "')")
-    @Transactional(readOnly = true)
-    public OIDCProviderTO read(final String key) {
-        OIDCProvider op = opDAO.find(key);
-        if (op == null) {
-            throw new NotFoundException("OIDC Provider '" + key + '\'');
-        }
-        return binder.getOIDCProviderTO(op);
-    }
-
-    @PreAuthorize("hasRole('" + OIDCClientEntitlement.OP_UPDATE + "')")
-    public void update(final OIDCProviderTO oidcProviderTO) {
-        OIDCProvider oidcProvider = opDAO.find(oidcProviderTO.getKey());
-        if (oidcProvider == null) {
-            throw new NotFoundException("OIDC Provider '" + oidcProviderTO.getKey() + '\'');
-        }
-
-        if (!oidcProvider.getIssuer().equals(oidcProviderTO.getIssuer())) {
-            LOG.error("Issuers do not match: expected {}, found {}",
-                    oidcProvider.getIssuer(), oidcProviderTO.getIssuer());
-            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidEntity);
-            sce.getElements().add("Issuers do not match");
-            throw sce;
-        }
-
-        opDAO.save(binder.update(oidcProvider, oidcProviderTO));
-    }
-
-    @PreAuthorize("hasRole('" + OIDCClientEntitlement.OP_DELETE + "')")
-    public void delete(final String key) {
-        OIDCProvider op = opDAO.find(key);
-        if (op == null) {
-            throw new NotFoundException("OIDC Provider '" + key + '\'');
-        }
-        opDAO.delete(key);
-    }
-
-    @Override
-    protected OIDCProviderTO resolveReference(
-            final Method method, final Object... args) throws UnresolvedReferenceException {
-
-        String key = null;
-
-        if (ArrayUtils.isNotEmpty(args)) {
-            for (int i = 0; key == null && i < args.length; i++) {
-                if (args[i] instanceof String) {
-                    key = (String) args[i];
-                } else if (args[i] instanceof OIDCProviderTO) {
-                    key = ((OIDCProviderTO) args[i]).getKey();
-                }
-            }
-        }
-
-        if (key != null) {
-            try {
-                return binder.getOIDCProviderTO(opDAO.find(key));
-            } catch (Throwable ignore) {
-                LOG.debug("Unresolved reference", ignore);
-                throw new UnresolvedReferenceException(ignore);
-            }
-        }
-
-        throw new UnresolvedReferenceException();
-    }
-}
diff --git a/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/model/OIDCProviderDiscoveryDocument.java b/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/model/OIDCProviderDiscoveryDocument.java
deleted file mode 100644
index aae3f0c..0000000
--- a/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/model/OIDCProviderDiscoveryDocument.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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.core.logic.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonPropertyOrder;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-@JsonPropertyOrder({
-    "issuer",
-    "authorization_endpoint",
-    "token_endpoint",
-    "userinfo_endpoint",
-    "end_session_endpoint",
-    "jwks_uri",
-    "registration_endpoint"
-})
-public class OIDCProviderDiscoveryDocument {
-
-    @JsonProperty("issuer")
-    private String issuer;
-
-    @JsonProperty("authorization_endpoint")
-    private String authorizationEndpoint;
-
-    @JsonProperty("token_endpoint")
-    private String tokenEndpoint;
-
-    @JsonProperty("userinfo_endpoint")
-    private String userinfoEndpoint;
-
-    @JsonProperty("end_session_endpoint")
-    private String endSessionEndpoint;
-
-    @JsonProperty("jwks_uri")
-    private String jwksUri;
-
-    @JsonProperty("registration_endpoint")
-    private String registrationEndpoint;
-
-    @JsonProperty("issuer")
-    public String getIssuer() {
-        return issuer;
-    }
-
-    @JsonProperty("issuer")
-    public void setIssuer(final String issuer) {
-        this.issuer = issuer;
-    }
-
-    @JsonProperty("authorization_endpoint")
-    public String getAuthorizationEndpoint() {
-        return authorizationEndpoint;
-    }
-
-    @JsonProperty("authorization_endpoint")
-    public void setAuthorizationEndpoint(final String authorizationEndpoint) {
-        this.authorizationEndpoint = authorizationEndpoint;
-    }
-
-    @JsonProperty("token_endpoint")
-    public String getTokenEndpoint() {
-        return tokenEndpoint;
-    }
-
-    @JsonProperty("token_endpoint")
-    public void setTokenEndpoint(final String tokenEndpoint) {
-        this.tokenEndpoint = tokenEndpoint;
-    }
-
-    @JsonProperty("userinfo_endpoint")
-    public String getUserinfoEndpoint() {
-        return userinfoEndpoint;
-    }
-
-    @JsonProperty("userinfo_endpoint")
-    public void setUserinfoEndpoint(final String userinfoEndpoint) {
-        this.userinfoEndpoint = userinfoEndpoint;
-    }
-
-    @JsonProperty("end_session_endpoint")
-    public String getEndSessionEndpoint() {
-        return endSessionEndpoint;
-    }
-
-    @JsonProperty("end_session_endpoint")
-    public void setEndSessionEndpoint(final String endSessionEndpoint) {
-        this.endSessionEndpoint = endSessionEndpoint;
-    }
-
-    @JsonProperty("jwks_uri")
-    public String getJwksUri() {
-        return jwksUri;
-    }
-
-    @JsonProperty("jwks_uri")
-    public void setJwksUri(final String jwksUri) {
-        this.jwksUri = jwksUri;
-    }
-
-    @JsonProperty("registration_endpoint")
-    public String getRegistrationEndpoint() {
-        return registrationEndpoint;
-    }
-
-    @JsonProperty("registration_endpoint")
-    public void setRegistrationEndpoint(final String registrationEndpoint) {
-        this.registrationEndpoint = registrationEndpoint;
-    }
-
-}
diff --git a/ext/pom.xml b/ext/pom.xml
index be9e73f..67cc21e 100644
--- a/ext/pom.xml
+++ b/ext/pom.xml
@@ -80,9 +80,9 @@ under the License.
     <module>flowable</module>
     <module>camel</module>
     <module>saml2sp4ui</module>
+    <module>oidcc4ui</module>
     <module>elasticsearch</module>
     <module>scimv2</module>
-    <module>oidcclient</module>
     <module>self-keymaster</module>
   </modules>
 
diff --git a/ext/saml2sp4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/AbstractSAMLSSOLoginFormPanel.java b/ext/saml2sp4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/AbstractSAMLSSOLoginFormPanel.java
index 7938110..01866e1 100644
--- a/ext/saml2sp4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/AbstractSAMLSSOLoginFormPanel.java
+++ b/ext/saml2sp4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/AbstractSAMLSSOLoginFormPanel.java
@@ -23,8 +23,9 @@ import java.nio.charset.StandardCharsets;
 import java.util.List;
 import org.apache.syncope.client.ui.commons.BaseSession;
 import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.ui.commons.SAML2SP4UIConstants;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
-import org.apache.syncope.common.lib.to.SAML24UIIdPTO;
+import org.apache.syncope.common.lib.to.SAML2SP4UIIdPTO;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
 import org.apache.wicket.markup.html.form.IChoiceRenderer;
@@ -46,29 +47,29 @@ public abstract class AbstractSAMLSSOLoginFormPanel extends BaseSSOLoginFormPane
     public AbstractSAMLSSOLoginFormPanel(final String id, final BaseSession session) {
         super(id);
 
-        List<SAML24UIIdPTO> available = session.getAnonymousService(SAML2SP4UIIdPService.class).list();
+        List<SAML2SP4UIIdPTO> available = session.getAnonymousService(SAML2SP4UIIdPService.class).list();
 
-        final Model<SAML24UIIdPTO> model = new Model<>();
-        AjaxDropDownChoicePanel<SAML24UIIdPTO> idps =
+        final Model<SAML2SP4UIIdPTO> model = new Model<>();
+        AjaxDropDownChoicePanel<SAML2SP4UIIdPTO> idps =
                 new AjaxDropDownChoicePanel<>("idps", "SAML 2.0", model, false);
         idps.setChoices(available);
-        idps.setChoiceRenderer(new IChoiceRenderer<SAML24UIIdPTO>() {
+        idps.setChoiceRenderer(new IChoiceRenderer<SAML2SP4UIIdPTO>() {
 
             private static final long serialVersionUID = 1814750973898916102L;
 
             @Override
-            public Object getDisplayValue(final SAML24UIIdPTO object) {
+            public Object getDisplayValue(final SAML2SP4UIIdPTO object) {
                 return object.getName();
             }
 
             @Override
-            public String getIdValue(final SAML24UIIdPTO object, final int index) {
+            public String getIdValue(final SAML2SP4UIIdPTO object, final int index) {
                 return object.getEntityID();
             }
 
             @Override
-            public SAML24UIIdPTO getObject(
-                    final String id, final IModel<? extends List<? extends SAML24UIIdPTO>> choices) {
+            public SAML2SP4UIIdPTO getObject(
+                    final String id, final IModel<? extends List<? extends SAML2SP4UIIdPTO>> choices) {
 
                 return choices.getObject().stream().
                         filter(idp -> idp.getEntityID().equals(id)).findFirst().orElse(null);
@@ -83,7 +84,7 @@ public abstract class AbstractSAMLSSOLoginFormPanel extends BaseSSOLoginFormPane
                 if (model.getObject() != null) {
                     try {
                         RequestCycle.get().scheduleRequestHandlerAfterCurrent(new RedirectRequestHandler(
-                                UrlUtils.rewriteToContextRelative("saml2sp4ui/login?idp="
+                                UrlUtils.rewriteToContextRelative(SAML2SP4UIConstants.URL_CONTEXT + "/login?idp="
                                         + URLEncoder.encode(
                                                 model.getObject().getEntityID(), StandardCharsets.UTF_8),
                                         RequestCycle.get())));
diff --git a/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java b/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
index cb3649f..bc98630 100644
--- a/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
+++ b/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
@@ -50,7 +50,7 @@ import org.apache.syncope.client.ui.commons.panels.WizardModalPanel;
 import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
 import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.SAML24UIIdPTO;
+import org.apache.syncope.common.lib.to.SAML2SP4UIIdPTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.SAML2SP4UIEntitlement;
@@ -70,7 +70,7 @@ import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.model.StringResourceModel;
 
 public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
-        SAML24UIIdPTO, SAML24UIIdPTO, SAML2IdPsProvider, SAML2IdPsRestClient> {
+        SAML2SP4UIIdPTO, SAML2SP4UIIdPTO, SAML2IdPsProvider, SAML2IdPsRestClient> {
 
     private static final long serialVersionUID = 4792356089584116041L;
 
@@ -81,16 +81,17 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
     private final BaseModal<Serializable> templateModal;
 
     public SAML2IdPsDirectoryPanel(final String id, final PageReference pageRef) {
-        super(id, new Builder<SAML24UIIdPTO, SAML24UIIdPTO, SAML2IdPsRestClient>(new SAML2IdPsRestClient(), pageRef) {
+        super(id, new Builder<SAML2SP4UIIdPTO, SAML2SP4UIIdPTO, SAML2IdPsRestClient>(
+                new SAML2IdPsRestClient(), pageRef) {
 
             private static final long serialVersionUID = 8517982765290075155L;
 
             @Override
-            protected WizardMgtPanel<SAML24UIIdPTO> newInstance(final String id, final boolean wizardInModal) {
+            protected WizardMgtPanel<SAML2SP4UIIdPTO> newInstance(final String id, final boolean wizardInModal) {
                 throw new UnsupportedOperationException();
             }
         }.disableCheckBoxes());
-        this.addNewItemPanelBuilder(new SAML2IdPWizardBuilder(this, new SAML24UIIdPTO(), pageRef), false);
+        this.addNewItemPanelBuilder(new SAML2IdPWizardBuilder(this, new SAML2SP4UIIdPTO(), pageRef), false);
 
         modal.addSubmitButton();
         modal.size(Modal.Size.Large);
@@ -153,16 +154,16 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
     }
 
     @Override
-    protected ActionLinksTogglePanel<SAML24UIIdPTO> actionTogglePanel() {
-        return new ActionLinksTogglePanel<SAML24UIIdPTO>(Constants.OUTER, pageRef) {
+    protected ActionLinksTogglePanel<SAML2SP4UIIdPTO> actionTogglePanel() {
+        return new ActionLinksTogglePanel<SAML2SP4UIIdPTO>(Constants.OUTER, pageRef) {
 
             private static final long serialVersionUID = -7688359318035249200L;
 
             @Override
             public void updateHeader(final AjaxRequestTarget target, final Serializable modelObject) {
-                if (modelObject instanceof SAML24UIIdPTO) {
-                    setHeader(target,
-                            StringUtils.abbreviate(((SAML24UIIdPTO) modelObject).getName(), HEADER_FIRST_ABBREVIATION));
+                if (modelObject instanceof SAML2SP4UIIdPTO) {
+                    setHeader(target, StringUtils.abbreviate(
+                            ((SAML2SP4UIIdPTO) modelObject).getName(), HEADER_FIRST_ABBREVIATION));
                 } else {
                     super.updateHeader(target, modelObject);
                 }
@@ -181,8 +182,8 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
     }
 
     @Override
-    protected List<IColumn<SAML24UIIdPTO, String>> getColumns() {
-        List<IColumn<SAML24UIIdPTO, String>> columns = new ArrayList<>();
+    protected List<IColumn<SAML2SP4UIIdPTO, String>> getColumns() {
+        List<IColumn<SAML2SP4UIIdPTO, String>> columns = new ArrayList<>();
 
         columns.add(new KeyPropertyColumn<>(new ResourceModel("key"), "key", "key"));
         columns.add(new PropertyColumn<>(new ResourceModel("name"), "name", "name"));
@@ -196,16 +197,16 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
     }
 
     @Override
-    public ActionsPanel<SAML24UIIdPTO> getActions(final IModel<SAML24UIIdPTO> model) {
-        final ActionsPanel<SAML24UIIdPTO> panel = super.getActions(model);
+    public ActionsPanel<SAML2SP4UIIdPTO> getActions(final IModel<SAML2SP4UIIdPTO> model) {
+        final ActionsPanel<SAML2SP4UIIdPTO> panel = super.getActions(model);
 
-        panel.add(new ActionLink<SAML24UIIdPTO>() {
+        panel.add(new ActionLink<SAML2SP4UIIdPTO>() {
 
             private static final long serialVersionUID = -7978723352517770645L;
 
             @Override
-            public void onClick(final AjaxRequestTarget target, final SAML24UIIdPTO ignore) {
-                SAML24UIIdPTO object = SAML2IdPsRestClient.read(model.getObject().getKey());
+            public void onClick(final AjaxRequestTarget target, final SAML2SP4UIIdPTO ignore) {
+                SAML2SP4UIIdPTO object = SAML2IdPsRestClient.read(model.getObject().getKey());
                 metadataModal.header(Model.of(object.getName() + " - Metadata"));
                 metadataModal.setContent(new XMLEditorPanel(
                         metadataModal,
@@ -216,24 +217,24 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
                 target.add(metadataModal);
             }
         }, ActionLink.ActionType.HTML, SAML2SP4UIEntitlement.IDP_READ);
-        panel.add(new ActionLink<SAML24UIIdPTO>() {
+        panel.add(new ActionLink<SAML2SP4UIIdPTO>() {
 
             private static final long serialVersionUID = -3722207913631435501L;
 
             @Override
-            public void onClick(final AjaxRequestTarget target, final SAML24UIIdPTO ignore) {
-                SAML24UIIdPTO object = SAML2IdPsRestClient.read(model.getObject().getKey());
+            public void onClick(final AjaxRequestTarget target, final SAML2SP4UIIdPTO ignore) {
+                SAML2SP4UIIdPTO object = SAML2IdPsRestClient.read(model.getObject().getKey());
                 send(SAML2IdPsDirectoryPanel.this, Broadcast.EXACT,
                         new AjaxWizard.EditItemActionEvent<>(object, target));
             }
         }, ActionLink.ActionType.EDIT, SAML2SP4UIEntitlement.IDP_UPDATE);
-        panel.add(new ActionLink<SAML24UIIdPTO>() {
+        panel.add(new ActionLink<SAML2SP4UIIdPTO>() {
 
             private static final long serialVersionUID = -3722207913631435501L;
 
             @Override
-            public void onClick(final AjaxRequestTarget target, final SAML24UIIdPTO ignore) {
-                final SAML24UIIdPTO object = SAML2IdPsRestClient.read(model.getObject().getKey());
+            public void onClick(final AjaxRequestTarget target, final SAML2SP4UIIdPTO ignore) {
+                final SAML2SP4UIIdPTO object = SAML2IdPsRestClient.read(model.getObject().getKey());
 
                 UserTemplateWizardBuilder builder = new UserTemplateWizardBuilder(
                         object.getUserTemplate(),
@@ -259,12 +260,12 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
 
             }
         }, ActionLink.ActionType.TEMPLATE, SAML2SP4UIEntitlement.IDP_UPDATE);
-        panel.add(new ActionLink<SAML24UIIdPTO>() {
+        panel.add(new ActionLink<SAML2SP4UIIdPTO>() {
 
             private static final long serialVersionUID = -5467832321897812767L;
 
             @Override
-            public void onClick(final AjaxRequestTarget target, final SAML24UIIdPTO ignore) {
+            public void onClick(final AjaxRequestTarget target, final SAML2SP4UIIdPTO ignore) {
                 try {
                     SAML2IdPsRestClient.delete(model.getObject().getKey());
                     SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
@@ -302,11 +303,11 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
         }
     }
 
-    protected static final class SAML2IdPsProvider extends DirectoryDataProvider<SAML24UIIdPTO> {
+    protected static final class SAML2IdPsProvider extends DirectoryDataProvider<SAML2SP4UIIdPTO> {
 
         private static final long serialVersionUID = -185944053385660794L;
 
-        private final SortableDataProviderComparator<SAML24UIIdPTO> comparator;
+        private final SortableDataProviderComparator<SAML2SP4UIIdPTO> comparator;
 
         private SAML2IdPsProvider(final int paginatorRows) {
             super(paginatorRows);
@@ -316,8 +317,8 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
         }
 
         @Override
-        public Iterator<SAML24UIIdPTO> iterator(final long first, final long count) {
-            List<SAML24UIIdPTO> list = SAML2IdPsRestClient.list();
+        public Iterator<SAML2SP4UIIdPTO> iterator(final long first, final long count) {
+            List<SAML2SP4UIIdPTO> list = SAML2IdPsRestClient.list();
             list.sort(comparator);
             return list.subList((int) first, (int) first + (int) count).iterator();
         }
@@ -328,7 +329,7 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
         }
 
         @Override
-        public IModel<SAML24UIIdPTO> model(final SAML24UIIdPTO object) {
+        public IModel<SAML2SP4UIIdPTO> model(final SAML2SP4UIIdPTO object) {
             return new CompoundPropertyModel<>(object);
         }
     }
diff --git a/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/panels/SAMLSSOLoginFormPanel.java b/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/panels/SAMLSSOLoginFormPanel.java
index b748dfb..5fa2e93 100644
--- a/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/panels/SAMLSSOLoginFormPanel.java
+++ b/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/panels/SAMLSSOLoginFormPanel.java
@@ -28,5 +28,4 @@ public class SAMLSSOLoginFormPanel extends AbstractSAMLSSOLoginFormPanel {
     public SAMLSSOLoginFormPanel(final String id, final BaseSession session) {
         super(id, session);
     }
-
 }
diff --git a/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPsRestClient.java b/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPsRestClient.java
index dab8c09..ed627c5 100644
--- a/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPsRestClient.java
+++ b/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPsRestClient.java
@@ -24,14 +24,14 @@ import javax.ws.rs.core.MediaType;
 import org.apache.cxf.jaxrs.client.Client;
 import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.common.lib.to.SAML24UIIdPTO;
+import org.apache.syncope.common.lib.to.SAML2SP4UIIdPTO;
 import org.apache.syncope.common.rest.api.service.SAML2SP4UIIdPService;
 
 public class SAML2IdPsRestClient extends BaseRestClient {
 
     private static final long serialVersionUID = -5084300184764037527L;
 
-    public static List<SAML24UIIdPTO> list() {
+    public static List<SAML2SP4UIIdPTO> list() {
         return getService(SAML2SP4UIIdPService.class).list();
     }
 
@@ -45,11 +45,11 @@ public class SAML2IdPsRestClient extends BaseRestClient {
         SyncopeConsoleSession.get().resetClient(SAML2SP4UIIdPService.class);
     }
 
-    public static SAML24UIIdPTO read(final String key) {
+    public static SAML2SP4UIIdPTO read(final String key) {
         return getService(SAML2SP4UIIdPService.class).read(key);
     }
 
-    public static void update(final SAML24UIIdPTO idp) {
+    public static void update(final SAML2SP4UIIdPTO idp) {
         getService(SAML2SP4UIIdPService.class).update(idp);
     }
 
diff --git a/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java b/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
index 27c2be2..91dda17 100644
--- a/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
+++ b/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
@@ -42,7 +42,7 @@ import org.apache.syncope.client.ui.commons.markup.html.form.FieldPanel;
 import org.apache.syncope.client.ui.commons.wizards.AjaxWizardBuilder;
 import org.apache.syncope.common.lib.to.EntityTO;
 import org.apache.syncope.common.lib.to.ItemTO;
-import org.apache.syncope.common.lib.to.SAML24UIIdPTO;
+import org.apache.syncope.common.lib.to.SAML2SP4UIIdPTO;
 import org.apache.syncope.common.lib.types.SAML2BindingType;
 import org.apache.syncope.common.lib.types.SAML2SP4UIImplementationType;
 import org.apache.wicket.Component;
@@ -58,7 +58,7 @@ import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.model.StringResourceModel;
 import org.apache.wicket.model.util.ListModel;
 
-public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML24UIIdPTO> {
+public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2SP4UIIdPTO> {
 
     private static final long serialVersionUID = 5952696913893950460L;
 
@@ -87,14 +87,14 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML24UIIdPTO> {
     };
 
     public SAML2IdPWizardBuilder(
-            final SAML2IdPsDirectoryPanel directoryPanel, final SAML24UIIdPTO idpTO, final PageReference pageRef) {
+            final SAML2IdPsDirectoryPanel directoryPanel, final SAML2SP4UIIdPTO idpTO, final PageReference pageRef) {
 
         super(idpTO, pageRef);
         this.directoryPanel = directoryPanel;
     }
 
     @Override
-    protected WizardModel buildModelSteps(final SAML24UIIdPTO modelObject, final WizardModel wizardModel) {
+    protected WizardModel buildModelSteps(final SAML2SP4UIIdPTO modelObject, final WizardModel wizardModel) {
         wizardModel.add(new IdP(modelObject));
 
         Mapping mapping = new Mapping(modelObject);
@@ -137,7 +137,7 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML24UIIdPTO> {
 
         private static final long serialVersionUID = 854012593185195024L;
 
-        IdP(final SAML24UIIdPTO idpTO) {
+        IdP(final SAML2SP4UIIdPTO idpTO) {
             super(StringUtils.EMPTY, StringUtils.EMPTY);
 
             List<Component> fields = new ArrayList<>();
@@ -200,14 +200,14 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML24UIIdPTO> {
 
         private static final long serialVersionUID = 3454904947720856253L;
 
-        Mapping(final SAML24UIIdPTO item) {
+        Mapping(final SAML2SP4UIIdPTO item) {
             setTitleModel(Model.of("Mapping"));
             setSummaryModel(Model.of(StringUtils.EMPTY));
         }
     }
 
     @Override
-    protected Serializable onApplyInternal(final SAML24UIIdPTO modelObject) {
+    protected Serializable onApplyInternal(final SAML2SP4UIIdPTO modelObject) {
         long connObjectKeyCount = modelObject.getItems().stream().filter(ItemTO::isConnObjectKey).count();
         if (connObjectKeyCount != 1) {
             throw new IllegalArgumentException(
diff --git a/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/SAML2IdPMappingPanel.java b/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/SAML2IdPMappingPanel.java
index b4bdf9e..1b9fba8 100644
--- a/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/SAML2IdPMappingPanel.java
+++ b/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/SAML2IdPMappingPanel.java
@@ -26,7 +26,7 @@ import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.common.lib.to.ItemTO;
-import org.apache.syncope.common.lib.to.SAML24UIIdPTO;
+import org.apache.syncope.common.lib.to.SAML2SP4UIIdPTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.wicket.model.IModel;
@@ -39,7 +39,7 @@ public class SAML2IdPMappingPanel extends AbstractMappingPanel {
 
     public SAML2IdPMappingPanel(
             final String id,
-            final SAML24UIIdPTO idpTO,
+            final SAML2SP4UIIdPTO idpTO,
             final ItemTransformersTogglePanel mapItemTransformers,
             final JEXLTransformersTogglePanel jexlTransformers) {
 
diff --git a/ext/saml2sp4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/panels/SAMLSSOLoginFormPanel.java b/ext/saml2sp4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/panels/SAMLSSOLoginFormPanel.java
index 922dba7..b94e979 100644
--- a/ext/saml2sp4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/panels/SAMLSSOLoginFormPanel.java
+++ b/ext/saml2sp4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/panels/SAMLSSOLoginFormPanel.java
@@ -28,5 +28,4 @@ public class SAMLSSOLoginFormPanel extends AbstractSAMLSSOLoginFormPanel {
     public SAMLSSOLoginFormPanel(final String id, final BaseSession session) {
         super(id, session);
     }
-
 }
diff --git a/ext/saml2sp4ui/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML24UIIdPTO.java b/ext/saml2sp4ui/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2SP4UIIdPTO.java
similarity index 98%
rename from ext/saml2sp4ui/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML24UIIdPTO.java
rename to ext/saml2sp4ui/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2SP4UIIdPTO.java
index 6216b17..06ec975 100644
--- a/ext/saml2sp4ui/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML24UIIdPTO.java
+++ b/ext/saml2sp4ui/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2SP4UIIdPTO.java
@@ -26,7 +26,7 @@ import java.util.Optional;
 import javax.ws.rs.PathParam;
 import org.apache.syncope.common.lib.types.SAML2BindingType;
 
-public class SAML24UIIdPTO implements EntityTO, ItemContainerTO {
+public class SAML2SP4UIIdPTO implements EntityTO, ItemContainerTO {
 
     private static final long serialVersionUID = 4426527052873779881L;
 
diff --git a/ext/saml2sp4ui/common-lib/src/main/java/org/apache/syncope/common/lib/types/SAML2SP4UIImplementationType.java b/ext/saml2sp4ui/common-lib/src/main/java/org/apache/syncope/common/lib/types/SAML2SP4UIImplementationType.java
index f54f230..01133c5 100644
--- a/ext/saml2sp4ui/common-lib/src/main/java/org/apache/syncope/common/lib/types/SAML2SP4UIImplementationType.java
+++ b/ext/saml2sp4ui/common-lib/src/main/java/org/apache/syncope/common/lib/types/SAML2SP4UIImplementationType.java
@@ -29,7 +29,7 @@ public final class SAML2SP4UIImplementationType {
 
     private static final Map<String, String> VALUES = Map.ofEntries(
             Pair.of(IDP_ACTIONS,
-                    "org.apache.syncope.core.provisioning.api.SAML2IdPActions"),
+                    "org.apache.syncope.core.provisioning.api.SAML2SP4UIIdPActions"),
             Pair.of(REQUESTED_AUTHN_CONTEXT_PROVIDER,
                     "org.apache.syncope.core.provisioning.api.RequestedAuthnContextProvider"));
 
diff --git a/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/SAML2SP4UIIdPLogic.java b/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/SAML2SP4UIIdPLogic.java
index a52a57c..73e7f2d 100644
--- a/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/SAML2SP4UIIdPLogic.java
+++ b/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/SAML2SP4UIIdPLogic.java
@@ -24,14 +24,12 @@ import java.util.List;
 import java.util.stream.Collectors;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.SAML24UIIdPTO;
+import org.apache.syncope.common.lib.to.SAML2SP4UIIdPTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.SAML2BindingType;
 import org.apache.syncope.common.lib.types.SAML2SP4UIEntitlement;
 import org.apache.syncope.core.logic.init.SAML2SP4UILoader;
 import org.apache.syncope.core.logic.saml2.SAML2ClientCache;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.pac4j.saml.config.SAML2Configuration;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
@@ -41,7 +39,7 @@ import org.apache.syncope.core.persistence.api.dao.SAML2SP4UIIdPDAO;
 import org.apache.syncope.core.provisioning.api.data.SAML2SP4UIIdPDataBinder;
 
 @Component
-public class SAML2SP4UIIdPLogic extends AbstractTransactionalLogic<SAML24UIIdPTO> {
+public class SAML2SP4UIIdPLogic extends AbstractTransactionalLogic<SAML2SP4UIIdPTO> {
 
     @Autowired
     private SAML2SP4UILoader loader;
@@ -57,13 +55,13 @@ public class SAML2SP4UIIdPLogic extends AbstractTransactionalLogic<SAML24UIIdPTO
 
     @PreAuthorize("isAuthenticated()")
     @Transactional(readOnly = true)
-    public List<SAML24UIIdPTO> list() {
+    public List<SAML2SP4UIIdPTO> list() {
         return idpDAO.findAll().stream().map(binder::getIdPTO).collect(Collectors.toList());
     }
 
     @PreAuthorize("hasRole('" + SAML2SP4UIEntitlement.IDP_READ + "')")
     @Transactional(readOnly = true)
-    public SAML24UIIdPTO read(final String key) {
+    public SAML2SP4UIIdPTO read(final String key) {
         SAML2SP4UIIdP idp = idpDAO.find(key);
         if (idp == null) {
             throw new NotFoundException("SAML 2.0 IdP '" + key + '\'');
@@ -75,7 +73,7 @@ public class SAML2SP4UIIdPLogic extends AbstractTransactionalLogic<SAML24UIIdPTO
     @PreAuthorize("hasRole('" + SAML2SP4UIEntitlement.IDP_IMPORT + "')")
     public String importFromMetadata(final InputStream input) {
         try {
-            SAML24UIIdPTO idpTO = saml2ClientCache.importMetadata(input, loader.newSAML2Configuration());
+            SAML2SP4UIIdPTO idpTO = SAML2ClientCache.importMetadata(input, loader.newSAML2Configuration());
             SAML2SP4UIIdP idp = idpDAO.save(binder.create(idpTO));
 
             return idp.getKey();
@@ -89,15 +87,8 @@ public class SAML2SP4UIIdPLogic extends AbstractTransactionalLogic<SAML24UIIdPTO
         }
     }
 
-    private static void setBindingType(final SAML2Configuration cfg, final SAML2BindingType type) {
-        cfg.setAuthnRequestBindingType(type.getUri());
-        cfg.setResponseBindingType(SAML2BindingType.POST.getUri());
-        cfg.setSpLogoutRequestBindingType(type.getUri());
-        cfg.setSpLogoutResponseBindingType(type.getUri());
-    }
-
     @PreAuthorize("hasRole('" + SAML2SP4UIEntitlement.IDP_UPDATE + "')")
-    public void update(final SAML24UIIdPTO saml2IdpTO) {
+    public void update(final SAML2SP4UIIdPTO saml2IdpTO) {
         SAML2SP4UIIdP idp = idpDAO.find(saml2IdpTO.getKey());
         if (idp == null) {
             throw new NotFoundException("SAML 2.0 IdP '" + saml2IdpTO.getKey() + '\'');
@@ -119,7 +110,7 @@ public class SAML2SP4UIIdPLogic extends AbstractTransactionalLogic<SAML24UIIdPTO
     }
 
     @Override
-    protected SAML24UIIdPTO resolveReference(final Method method, final Object... args)
+    protected SAML2SP4UIIdPTO resolveReference(final Method method, final Object... args)
             throws UnresolvedReferenceException {
 
         String key = null;
@@ -128,8 +119,8 @@ public class SAML2SP4UIIdPLogic extends AbstractTransactionalLogic<SAML24UIIdPTO
             for (int i = 0; key == null && i < args.length; i++) {
                 if (args[i] instanceof String) {
                     key = (String) args[i];
-                } else if (args[i] instanceof SAML24UIIdPTO) {
-                    key = ((SAML24UIIdPTO) args[i]).getKey();
+                } else if (args[i] instanceof SAML2SP4UIIdPTO) {
+                    key = ((SAML2SP4UIIdPTO) args[i]).getKey();
                 }
             }
         }
diff --git a/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/SAML2SP4UILogic.java b/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/SAML2SP4UILogic.java
index 59978ad..54d39c8 100644
--- a/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/SAML2SP4UILogic.java
+++ b/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/SAML2SP4UILogic.java
@@ -364,11 +364,10 @@ public class SAML2SP4UILogic extends AbstractTransactionalLogic<EntityTO> {
 
                 loginResp.getAttrs().clear();
                 loginResp.getAttrs().addAll(userTO.getPlainAttrs());
-                loginResp.getAttrs().addAll(userTO.getVirAttrs());
                 if (StringUtils.isNotBlank(userTO.getUsername())) {
                     loginResp.setUsername(userTO.getUsername());
                 } else {
-                    loginResp.setUsername(loginResp.getNameID());
+                    loginResp.setUsername(keyValue);
                 }
 
                 loginResp.setSelfReg(true);
diff --git a/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ClientCache.java b/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ClientCache.java
index 4d81694..8575f0c 100644
--- a/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ClientCache.java
+++ b/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ClientCache.java
@@ -27,7 +27,7 @@ import java.util.List;
 import java.util.Optional;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.syncope.common.lib.to.ItemTO;
-import org.apache.syncope.common.lib.to.SAML24UIIdPTO;
+import org.apache.syncope.common.lib.to.SAML2SP4UIIdPTO;
 import org.apache.syncope.common.lib.types.SAML2BindingType;
 import org.opensaml.saml.common.xml.SAMLConstants;
 import org.opensaml.saml.saml2.core.NameID;
@@ -53,7 +53,7 @@ public class SAML2ClientCache {
                 && spEntityID.equals(c.getConfiguration().getServiceProviderEntityId())).findFirst();
     }
 
-    private SAML2Client newSAML2Client(final Resource metadata, final SAML2Configuration cfg) {
+    private static SAML2Client newSAML2Client(final Resource metadata, final SAML2Configuration cfg) {
         cfg.setIdentityProviderMetadataResource(metadata);
 
         SAML2Client saml2Client = new SAML2Client(cfg);
@@ -62,11 +62,13 @@ public class SAML2ClientCache {
         return saml2Client;
     }
 
-    public SAML24UIIdPTO importMetadata(final InputStream metadata, final SAML2Configuration cfg) throws IOException {
+    public static SAML2SP4UIIdPTO importMetadata(
+            final InputStream metadata, final SAML2Configuration cfg) throws IOException {
+
         SAML2Client saml2Client = newSAML2Client(new ByteArrayResource(IOUtils.readBytesFromStream(metadata)), cfg);
         String entityId = saml2Client.getConfiguration().getIdentityProviderMetadataResolver().getEntityId();
 
-        SAML24UIIdPTO idpTO = new SAML24UIIdPTO();
+        SAML2SP4UIIdPTO idpTO = new SAML2SP4UIIdPTO();
         idpTO.setEntityID(entityId);
         idpTO.setName(entityId);
 
@@ -120,10 +122,6 @@ public class SAML2ClientCache {
         return saml2Client;
     }
 
-    public boolean remove(final SAML2Client saml2Client) {
-        return cache.remove(saml2Client);
-    }
-
     public boolean removeAll(final String idpEntityID) {
         return cache.removeIf(c -> idpEntityID.equals(c.getIdentityProviderResolvedEntityId()));
     }
diff --git a/ext/saml2sp4ui/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SAML2SP4UIIdPDataBinder.java b/ext/saml2sp4ui/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SAML2SP4UIIdPDataBinder.java
index 2571bb5..3d1ab5b 100644
--- a/ext/saml2sp4ui/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SAML2SP4UIIdPDataBinder.java
+++ b/ext/saml2sp4ui/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SAML2SP4UIIdPDataBinder.java
@@ -18,15 +18,15 @@
  */
 package org.apache.syncope.core.provisioning.api.data;
 
-import org.apache.syncope.common.lib.to.SAML24UIIdPTO;
+import org.apache.syncope.common.lib.to.SAML2SP4UIIdPTO;
 import org.apache.syncope.core.persistence.api.entity.SAML2SP4UIIdP;
 
 public interface SAML2SP4UIIdPDataBinder {
 
-    SAML24UIIdPTO getIdPTO(SAML2SP4UIIdP idp);
+    SAML2SP4UIIdPTO getIdPTO(SAML2SP4UIIdP idp);
 
-    SAML2SP4UIIdP create(SAML24UIIdPTO idpTO);
+    SAML2SP4UIIdP create(SAML2SP4UIIdPTO idpTO);
 
-    SAML2SP4UIIdP update(SAML2SP4UIIdP idp, SAML24UIIdPTO idpTO);
+    SAML2SP4UIIdP update(SAML2SP4UIIdP idp, SAML2SP4UIIdPTO idpTO);
 
 }
diff --git a/ext/saml2sp4ui/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2SP4UIIdPDataBinderImpl.java b/ext/saml2sp4ui/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2SP4UIIdPDataBinderImpl.java
index 579d06e..0efa2b3 100644
--- a/ext/saml2sp4ui/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2SP4UIIdPDataBinderImpl.java
+++ b/ext/saml2sp4ui/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2SP4UIIdPDataBinderImpl.java
@@ -24,7 +24,7 @@ import java.util.stream.Collectors;
 import org.apache.syncope.common.lib.SyncopeClientCompositeException;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.ItemTO;
-import org.apache.syncope.common.lib.to.SAML24UIIdPTO;
+import org.apache.syncope.common.lib.to.SAML2SP4UIIdPTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
@@ -69,11 +69,11 @@ public class SAML2SP4UIIdPDataBinderImpl implements SAML2SP4UIIdPDataBinder {
     private IntAttrNameParser intAttrNameParser;
 
     @Override
-    public SAML2SP4UIIdP create(final SAML24UIIdPTO idpTO) {
+    public SAML2SP4UIIdP create(final SAML2SP4UIIdPTO idpTO) {
         return update(entityFactory.newEntity(SAML2SP4UIIdP.class), idpTO);
     }
 
-    private void populateItems(final SAML24UIIdPTO idpTO, final SAML2SP4UIIdP idp) {
+    private void populateItems(final SAML2SP4UIIdPTO idpTO, final SAML2SP4UIIdP idp) {
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
         SyncopeClientException invalidMapping =
                 SyncopeClientException.build(ClientExceptionType.InvalidMapping);
@@ -146,7 +146,7 @@ public class SAML2SP4UIIdPDataBinderImpl implements SAML2SP4UIIdPDataBinder {
     }
 
     @Override
-    public SAML2SP4UIIdP update(final SAML2SP4UIIdP idp, final SAML24UIIdPTO idpTO) {
+    public SAML2SP4UIIdP update(final SAML2SP4UIIdP idp, final SAML2SP4UIIdPTO idpTO) {
         idp.setEntityID(idpTO.getEntityID());
         idp.setName(idpTO.getName());
         idp.setMetadata(Base64.getMimeDecoder().decode(idpTO.getMetadata()));
@@ -198,7 +198,7 @@ public class SAML2SP4UIIdPDataBinderImpl implements SAML2SP4UIIdPDataBinder {
         return idapDAO.save(idp);
     }
 
-    private static void populateItems(final SAML2SP4UIIdP idp, final SAML24UIIdPTO idpTO) {
+    private static void populateItems(final SAML2SP4UIIdP idp, final SAML2SP4UIIdPTO idpTO) {
         idp.getItems().forEach(item -> {
             ItemTO itemTO = new ItemTO();
             itemTO.setKey(item.getKey());
@@ -220,8 +220,8 @@ public class SAML2SP4UIIdPDataBinderImpl implements SAML2SP4UIIdPDataBinder {
     }
 
     @Override
-    public SAML24UIIdPTO getIdPTO(final SAML2SP4UIIdP idp) {
-        SAML24UIIdPTO idpTO = new SAML24UIIdPTO();
+    public SAML2SP4UIIdPTO getIdPTO(final SAML2SP4UIIdP idp) {
+        SAML2SP4UIIdPTO idpTO = new SAML2SP4UIIdPTO();
 
         idpTO.setKey(idp.getKey());
         idpTO.setEntityID(idp.getEntityID());
diff --git a/ext/saml2sp4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2SP4UIIdPService.java b/ext/saml2sp4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2SP4UIIdPService.java
index adecce9..dd5e987 100644
--- a/ext/saml2sp4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2SP4UIIdPService.java
+++ b/ext/saml2sp4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2SP4UIIdPService.java
@@ -39,7 +39,7 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.to.SAML24UIIdPTO;
+import org.apache.syncope.common.lib.to.SAML2SP4UIIdPTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 
 /**
@@ -59,7 +59,7 @@ public interface SAML2SP4UIIdPService extends JAXRSService {
      */
     @GET
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
-    List<SAML24UIIdPTO> list();
+    List<SAML2SP4UIIdPTO> list();
 
     /**
      * Returns the SAML 2.0 Identity Provider with matching entityID, if available.
@@ -70,7 +70,7 @@ public interface SAML2SP4UIIdPService extends JAXRSService {
     @GET
     @Path("{key}")
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
-    SAML24UIIdPTO read(@PathParam("key") String key);
+    SAML2SP4UIIdPTO read(@PathParam("key") String key);
 
     /**
      * Imports the SAML 2.0 Identity Provider definitions available in the provided XML metadata.
@@ -96,7 +96,7 @@ public interface SAML2SP4UIIdPService extends JAXRSService {
     @Path("{key}")
     @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
-    void update(@NotNull SAML24UIIdPTO saml2IdpTO);
+    void update(@NotNull SAML2SP4UIIdPTO saml2IdpTO);
 
     /**
      * Deletes the SAML 2.0 Identity Provider with matching entityID.
diff --git a/ext/saml2sp4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SP4UIIdPServiceImpl.java b/ext/saml2sp4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SP4UIIdPServiceImpl.java
index 620affc..620242d 100644
--- a/ext/saml2sp4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SP4UIIdPServiceImpl.java
+++ b/ext/saml2sp4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SP4UIIdPServiceImpl.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.rest.cxf.service;
 import java.io.InputStream;
 import java.util.List;
 import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.to.SAML24UIIdPTO;
+import org.apache.syncope.common.lib.to.SAML2SP4UIIdPTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.core.logic.SAML2SP4UIIdPLogic;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -35,12 +35,12 @@ public class SAML2SP4UIIdPServiceImpl extends AbstractServiceImpl implements SAM
     private SAML2SP4UIIdPLogic logic;
 
     @Override
-    public List<SAML24UIIdPTO> list() {
+    public List<SAML2SP4UIIdPTO> list() {
         return logic.list();
     }
 
     @Override
-    public SAML24UIIdPTO read(final String key) {
+    public SAML2SP4UIIdPTO read(final String key) {
         return logic.read(key);
     }
 
@@ -50,7 +50,7 @@ public class SAML2SP4UIIdPServiceImpl extends AbstractServiceImpl implements SAM
     }
 
     @Override
-    public void update(final SAML24UIIdPTO saml2IdpTO) {
+    public void update(final SAML2SP4UIIdPTO saml2IdpTO) {
         logic.update(saml2IdpTO);
     }
 
diff --git a/ext/saml2sp4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SP4UIServiceImpl.java b/ext/saml2sp4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SP4UIServiceImpl.java
index 2fe2a8f..f72104b 100644
--- a/ext/saml2sp4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SP4UIServiceImpl.java
+++ b/ext/saml2sp4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SP4UIServiceImpl.java
@@ -65,7 +65,7 @@ public class SAML2SP4UIServiceImpl extends AbstractServiceImpl implements SAML2S
     @Override
     public SAML2Request createLogoutRequest(final String spEntityID, final String urlContext) {
         return logic.createLogoutRequest(
-                getJWTToken(),
+                getAccessToken(),
                 StringUtils.appendIfMissing(spEntityID, "/"),
                 urlContext);
     }
@@ -75,7 +75,7 @@ public class SAML2SP4UIServiceImpl extends AbstractServiceImpl implements SAML2S
         logic.validateLogoutResponse(response);
     }
 
-    private String getJWTToken() {
+    private String getAccessToken() {
         String auth = messageContext.getHttpHeaders().getHeaderString(HttpHeaders.AUTHORIZATION);
         String[] parts = Optional.ofNullable(auth).map(s -> s.split(" ")).orElse(null);
         if (parts == null || parts.length != 2 || !"Bearer".equals(parts[0])) {
diff --git a/fit/console-reference/pom.xml b/fit/console-reference/pom.xml
index e96ca5d..1aec226 100644
--- a/fit/console-reference/pom.xml
+++ b/fit/console-reference/pom.xml
@@ -82,8 +82,8 @@ under the License.
     </dependency>
 
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-client-console</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-client-console</artifactId>
       <version>${project.version}</version>
     </dependency>
     
diff --git a/fit/console-reference/src/main/resources/oidcclient-agent.properties b/fit/console-reference/src/main/resources/oidcclient-agent.properties
deleted file mode 100644
index 7e5b0d5..0000000
--- a/fit/console-reference/src/main/resources/oidcclient-agent.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-# 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.
-conf.directory=${conf.directory}
-
-anonymousUser=${anonymousUser}
-anonymousKey=${anonymousKey}
-
-useGZIPCompression=true
diff --git a/fit/console-reference/src/main/webapp/WEB-INF/web.xml b/fit/console-reference/src/main/webapp/WEB-INF/web.xml
index 4aef871..f29a909 100644
--- a/fit/console-reference/src/main/webapp/WEB-INF/web.xml
+++ b/fit/console-reference/src/main/webapp/WEB-INF/web.xml
@@ -26,30 +26,6 @@ under the License.
 
   <display-name>Apache Syncope ${syncope.version} Console</display-name>
 
-  <!-- OIDC Client Parameters -->
-  <context-param>
-    <param-name>oidcclient.login.success.url</param-name>
-    <param-value>../wicket/bookmarkable/org.apache.syncope.client.console.pages.OIDCClientLogin</param-value>
-  </context-param>
-  <context-param>
-    <param-name>oidcclient.login.error.url</param-name>
-    <param-value>../wicket/bookmarkable/org.apache.syncope.client.console.pages.Login</param-value>
-  </context-param>
-  
-  <context-param>
-    <param-name>oidcclient.logout.success.url</param-name>
-    <param-value>../wicket/bookmarkable/org.apache.syncope.client.console.pages.OIDCClientLogout</param-value>
-  </context-param>
-  <context-param>
-    <param-name>oidcclient.logout.error.url</param-name>
-    <param-value>../wicket/bookmarkable/org.apache.syncope.client.console.pages.Login</param-value>
-  </context-param>
-  
-  <context-param>
-    <param-name>oidcclient.redirect.selfreg</param-name>
-    <param-value>../wicket/bookmarkable/org.apache.syncope.client.console.pages.OIDCClientSelfReg</param-value>
-  </context-param>
-
   <!-- SESSION TIMEOUT (MINUTES)-->
   <session-config>
     <session-timeout>30</session-timeout>
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 97a1791..cf71c55 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -197,14 +197,14 @@ under the License.
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-rest-cxf</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-rest-cxf</artifactId>
       <version>${project.version}</version>
       <scope>test</scope>          
     </dependency>
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-client-console</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-client-console</artifactId>
       <version>${project.version}</version>
       <scope>test</scope>
     </dependency>
@@ -1841,13 +1841,13 @@ under the License.
         </dependency>
         
         <dependency>
-          <groupId>org.apache.syncope.ext.oidcclient</groupId>
-          <artifactId>syncope-ext-oidcclient-rest-cxf</artifactId>
+          <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+          <artifactId>syncope-ext-oidcc4ui-rest-cxf</artifactId>
           <version>${project.version}</version>
         </dependency>
         <dependency>
-          <groupId>org.apache.syncope.ext.oidcclient</groupId>
-          <artifactId>syncope-ext-oidcclient-persistence-jpa</artifactId>
+          <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+          <artifactId>syncope-ext-oidcc4ui-persistence-jpa</artifactId>
           <version>${project.version}</version>
         </dependency>
         
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
index 7f2202e..726bb25 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
@@ -120,8 +120,6 @@ import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.apache.syncope.common.rest.api.service.GroupService;
 import org.apache.syncope.common.rest.api.service.ImplementationService;
 import org.apache.syncope.common.rest.api.service.MailTemplateService;
-import org.apache.syncope.common.rest.api.service.OIDCClientService;
-import org.apache.syncope.common.rest.api.service.OIDCProviderService;
 import org.apache.syncope.common.rest.api.service.RealmService;
 import org.apache.syncope.common.rest.api.service.ReconciliationService;
 import org.apache.syncope.common.rest.api.service.RelationshipTypeService;
@@ -155,6 +153,8 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+import org.apache.syncope.common.rest.api.service.OIDCC4UIService;
+import org.apache.syncope.common.rest.api.service.OIDCC4UIProviderService;
 
 @SpringJUnitConfig({ CoreITContext.class, SelfKeymasterClientContext.class, ZookeeperKeymasterClientContext.class })
 public abstract class AbstractITCase {
@@ -317,9 +317,9 @@ public abstract class AbstractITCase {
 
     protected static SAML2SP4UIIdPService saml2SP4UIIdPService;
 
-    protected static OIDCClientService oidcClientService;
+    protected static OIDCC4UIService oidcClientService;
 
-    protected static OIDCProviderService oidcProviderService;
+    protected static OIDCC4UIProviderService oidcProviderService;
 
     protected static SCIMConfService scimConfService;
 
@@ -409,8 +409,8 @@ public abstract class AbstractITCase {
         camelRouteService = adminClient.getService(CamelRouteService.class);
         saml2SP4UIService = adminClient.getService(SAML2SP4UIService.class);
         saml2SP4UIIdPService = adminClient.getService(SAML2SP4UIIdPService.class);
-        oidcClientService = adminClient.getService(OIDCClientService.class);
-        oidcProviderService = adminClient.getService(OIDCProviderService.class);
+        oidcClientService = adminClient.getService(OIDCC4UIService.class);
+        oidcProviderService = adminClient.getService(OIDCC4UIProviderService.class);
         scimConfService = adminClient.getService(SCIMConfService.class);
         clientAppService = adminClient.getService(ClientAppService.class);
         authModuleService = adminClient.getService(AuthModuleService.class);
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/OIDCClientDetector.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/OIDCClientDetector.java
index b32682a..75fc772 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/OIDCClientDetector.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/OIDCClientDetector.java
@@ -20,9 +20,9 @@ package org.apache.syncope.fit;
 
 import org.apache.syncope.client.lib.AnonymousAuthenticationHandler;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
-import org.apache.syncope.common.rest.api.service.OIDCProviderService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.apache.syncope.common.rest.api.service.OIDCC4UIProviderService;
 
 public class OIDCClientDetector {
 
@@ -39,7 +39,7 @@ public class OIDCClientDetector {
                             setContentType(SyncopeClientFactoryBean.ContentType.JSON).
                             create(new AnonymousAuthenticationHandler(
                                     AbstractITCase.ANONYMOUS_UNAME, AbstractITCase.ANONYMOUS_KEY)).
-                            getService(OIDCProviderService.class).list();
+                            getService(OIDCC4UIProviderService.class).list();
                     ENABLED = true;
                 } catch (Exception e) {
                     // ignore
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/OIDCClientITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/OIDCClientITCase.java
deleted file mode 100644
index 2fb16c7..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/OIDCClientITCase.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * 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.core;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNotEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assumptions.assumeTrue;
-
-import org.apache.syncope.client.lib.AnonymousAuthenticationHandler;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.to.ItemTO;
-import org.apache.syncope.common.lib.to.OIDCLoginRequestTO;
-import org.apache.syncope.common.lib.to.OIDCProviderTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.rest.api.service.OIDCClientService;
-import org.apache.syncope.fit.AbstractITCase;
-import org.apache.syncope.fit.OIDCClientDetector;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-public class OIDCClientITCase extends AbstractITCase {
-
-    @BeforeAll
-    public static void createOIDCProviderWithoutDiscovery() throws Exception {
-        if (!OIDCClientDetector.isOIDCClientAvailable()) {
-            return;
-        }
-
-        assertTrue(oidcProviderService.list().isEmpty());
-
-        OIDCProviderTO google = new OIDCProviderTO();
-        google.setAuthorizationEndpoint("AuthorizationEndpoint");
-        google.setClientID("ClientID");
-        google.setClientSecret("ClientSecret");
-        google.setIssuer("https://accounts.google.com");
-        google.setJwksUri("JwksUri");
-        google.setName("Google");
-        google.setTokenEndpoint("TokenEndpoint");
-        google.setUserinfoEndpoint("UserinfoEndpoint");
-
-        oidcProviderService.create(google);
-    }
-
-    @AfterAll
-    public static void clearProviders() throws Exception {
-        if (!OIDCClientDetector.isOIDCClientAvailable()) {
-            return;
-        }
-
-        oidcProviderService.list().forEach(op -> oidcProviderService.delete(op.getKey()));
-    }
-
-    @Test
-    public void createLoginRequest() {
-        assumeTrue(OIDCClientDetector.isOIDCClientAvailable());
-
-        SyncopeClient anonymous = clientFactory.create(
-                new AnonymousAuthenticationHandler(ANONYMOUS_UNAME, ANONYMOUS_KEY));
-        OIDCLoginRequestTO loginRequest = anonymous.getService(OIDCClientService.class).
-                createLoginRequest("http://localhost:9080/syncope-console/oidcclient/code-consumer", "Google");
-
-        assertNotNull(loginRequest);
-        assertEquals("http://localhost:9080/syncope-console/oidcclient/code-consumer", loginRequest.getRedirectURI());
-        assertNotNull(loginRequest.getProviderAddress());
-        assertNotNull(loginRequest.getClientId());
-        assertNotNull(loginRequest.getResponseType());
-        assertNotNull(loginRequest.getScope());
-        assertNotNull(loginRequest.getState());
-    }
-
-    @Test
-    public void setProviderMapping() {
-        assumeTrue(OIDCClientDetector.isOIDCClientAvailable());
-
-        OIDCProviderTO google = oidcProviderService.list().stream().
-                filter(object -> "Google".equals(object.getName())).findFirst().orElse(null);
-        assertNotNull(google);
-        assertFalse(google.isCreateUnmatching());
-        assertNull(google.getUserTemplate());
-        assertFalse(google.getItems().isEmpty());
-        assertNotEquals("fullname", google.getConnObjectKeyItem().getIntAttrName());
-        assertNotEquals("given_name", google.getConnObjectKeyItem().getExtAttrName());
-
-        google.setCreateUnmatching(true);
-
-        UserTO userTemplate = new UserTO();
-        userTemplate.setRealm("'/'");
-        google.setUserTemplate(userTemplate);
-
-        google.getItems().clear();
-        ItemTO keyMapping = new ItemTO();
-        keyMapping.setIntAttrName("fullname");
-        keyMapping.setExtAttrName("given_name");
-        google.setConnObjectKeyItem(keyMapping);
-
-        oidcProviderService.update(google);
-
-        google = oidcProviderService.read(google.getKey());
-        assertTrue(google.isCreateUnmatching());
-        assertEquals(userTemplate, google.getUserTemplate());
-        assertEquals("fullname", google.getConnObjectKeyItem().getIntAttrName());
-        assertEquals("given_name", google.getConnObjectKeyItem().getExtAttrName());
-    }
-}
diff --git a/fit/enduser-reference/pom.xml b/fit/enduser-reference/pom.xml
index 8e73bc0..58ccf44 100644
--- a/fit/enduser-reference/pom.xml
+++ b/fit/enduser-reference/pom.xml
@@ -64,8 +64,8 @@ under the License.
       <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-client-enduser</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-client-enduser</artifactId>
       <version>${project.version}</version>
     </dependency>
     
diff --git a/fit/enduser-reference/src/main/resources/oidcclient-agent.properties b/fit/enduser-reference/src/main/resources/oidcclient-agent.properties
deleted file mode 100644
index 7e5b0d5..0000000
--- a/fit/enduser-reference/src/main/resources/oidcclient-agent.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-# 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.
-conf.directory=${conf.directory}
-
-anonymousUser=${anonymousUser}
-anonymousKey=${anonymousKey}
-
-useGZIPCompression=true
diff --git a/fit/enduser-reference/src/main/webapp/WEB-INF/web.xml b/fit/enduser-reference/src/main/webapp/WEB-INF/web.xml
index 821eab4..545f1dc 100644
--- a/fit/enduser-reference/src/main/webapp/WEB-INF/web.xml
+++ b/fit/enduser-reference/src/main/webapp/WEB-INF/web.xml
@@ -26,29 +26,6 @@ under the License.
 
   <display-name>Apache Syncope ${syncope.version} Enduser</display-name>
 
-  <context-param>
-    <param-name>oidcclient.login.success.url</param-name>
-    <param-value>../wicket/bookmarkable/org.apache.syncope.client.enduser.pages.OIDCClientLogin</param-value>
-  </context-param>
-  <context-param>
-    <param-name>oidcclient.login.error.url</param-name>
-    <param-value>../wicket/bookmarkable/org.apache.syncope.client.enduser.pages.Login</param-value>
-  </context-param>
-  
-  <context-param>
-    <param-name>oidcclient.logout.success.url</param-name>
-    <param-value>../wicket/bookmarkable/org.apache.syncope.client.enduser.pages.OIDCClientLogout</param-value>
-  </context-param>
-  <context-param>
-    <param-name>oidcclient.logout.error.url</param-name>
-    <param-value>../wicket/bookmarkable/org.apache.syncope.client.enduser.pages.Login</param-value>
-  </context-param>
-
-  <context-param>
-    <param-name>oidcclient.redirect.selfreg</param-name>
-    <param-value>../wicket/bookmarkable/org.apache.syncope.client.enduser.pages.OIDCClientSelfReg</param-value>
-  </context-param>
-  
   <!-- SESSION TIMEOUT (MINUTES)-->
   <session-config>
     <session-timeout>30</session-timeout>
diff --git a/fit/wa-reference/pom.xml b/fit/wa-reference/pom.xml
index 456d006..3b04d0b 100644
--- a/fit/wa-reference/pom.xml
+++ b/fit/wa-reference/pom.xml
@@ -60,8 +60,8 @@ under the License.
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.apache.syncope.ext.oidcclient</groupId>
-      <artifactId>syncope-ext-oidcclient-client-enduser</artifactId>
+      <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+      <artifactId>syncope-ext-oidcc4ui-client-enduser</artifactId>
       <version>${project.version}</version>
       <scope>test</scope>
     </dependency>
diff --git a/fit/wa-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java b/fit/wa-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
index 4a2d11f..ddfa2a4 100644
--- a/fit/wa-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
+++ b/fit/wa-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
@@ -41,7 +41,6 @@ import org.apache.http.message.BasicNameValuePair;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
 import org.apache.syncope.common.rest.api.service.ClientAppService;
-import org.apache.syncope.common.rest.api.service.OIDCProviderService;
 import org.apache.syncope.common.rest.api.service.PolicyService;
 import org.apache.syncope.common.rest.api.service.SRARouteService;
 import org.apache.syncope.common.rest.api.service.wa.WASAML2IdPMetadataService;
@@ -51,6 +50,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.syncope.common.rest.api.service.SAML2SP4UIIdPService;
 import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.syncope.common.rest.api.service.OIDCC4UIProviderService;
 
 public class AbstractITCase {
 
@@ -84,7 +84,7 @@ public class AbstractITCase {
 
     protected static SAML2SP4UIIdPService saml2sp4UIIdPService;
 
-    protected static OIDCProviderService oidcProviderService;
+    protected static OIDCC4UIProviderService oidcProviderService;
 
     @BeforeAll
     public static void restSetup() {
@@ -96,7 +96,7 @@ public class AbstractITCase {
         clientAppService = adminClient.getService(ClientAppService.class);
         sraRouteService = adminClient.getService(SRARouteService.class);
         saml2sp4UIIdPService = adminClient.getService(SAML2SP4UIIdPService.class);
-        oidcProviderService = adminClient.getService(OIDCProviderService.class);
+        oidcProviderService = adminClient.getService(OIDCC4UIProviderService.class);
     }
 
     @BeforeAll
diff --git a/fit/wa-reference/src/test/java/org/apache/syncope/fit/sra/AbstractSRAITCase.java b/fit/wa-reference/src/test/java/org/apache/syncope/fit/sra/AbstractSRAITCase.java
index 25fbea5..998b41c 100644
--- a/fit/wa-reference/src/test/java/org/apache/syncope/fit/sra/AbstractSRAITCase.java
+++ b/fit/wa-reference/src/test/java/org/apache/syncope/fit/sra/AbstractSRAITCase.java
@@ -216,7 +216,7 @@ public abstract class AbstractSRAITCase extends AbstractITCase {
                     policyConf.getAuthModules().add(authModule);
 
                     AuthPolicyTO policy = new AuthPolicyTO();
-                    policy.setDescription("SRA auth policy");
+                    policy.setDescription(description);
                     policy.setConf(policyConf);
 
                     Response response = policyService.create(PolicyType.AUTH, policy);
diff --git a/fit/wa-reference/src/test/java/org/apache/syncope/fit/sra/OIDCSRAITCase.java b/fit/wa-reference/src/test/java/org/apache/syncope/fit/sra/OIDCSRAITCase.java
index d170205..fd519db 100644
--- a/fit/wa-reference/src/test/java/org/apache/syncope/fit/sra/OIDCSRAITCase.java
+++ b/fit/wa-reference/src/test/java/org/apache/syncope/fit/sra/OIDCSRAITCase.java
@@ -109,6 +109,7 @@ public class OIDCSRAITCase extends AbstractSRAITCase {
         clientApp.setClientId(clientId);
         clientApp.setClientSecret(clientSecret);
         clientApp.setSubjectType(OIDCSubjectType.PUBLIC);
+        clientApp.getRedirectUris().clear();
         clientApp.getRedirectUris().add(SRA_ADDRESS + "/login/oauth2/code/" + sraRegistrationId);
         clientApp.setAuthPolicy(getAuthPolicy().getKey());
         clientApp.setSignIdToken(true);
diff --git a/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/AbstractUIITCase.java b/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/AbstractUIITCase.java
index 67539e1..be1a899 100644
--- a/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/AbstractUIITCase.java
+++ b/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/AbstractUIITCase.java
@@ -23,12 +23,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
-import java.util.List;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.policy.AuthPolicyTO;
 import org.apache.syncope.common.lib.policy.DefaultAuthPolicyConf;
-import org.apache.syncope.common.lib.to.SAML24UIIdPTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
@@ -55,7 +53,7 @@ public abstract class AbstractUIITCase extends AbstractITCase {
                     policyConf.getAuthModules().add(ldapAuthModule);
 
                     AuthPolicyTO policy = new AuthPolicyTO();
-                    policy.setDescription("Test authentication");
+                    policy.setDescription(description);
                     policy.setConf(policyConf);
 
                     Response response = policyService.create(PolicyType.AUTH, policy);
@@ -92,6 +90,8 @@ public abstract class AbstractUIITCase extends AbstractITCase {
         assertNotNull(userService.read("pullFromLDAP"));
     }
 
+    protected abstract void doSelfReg(Runnable runnable);
+
     @Test
     public void selfRegUnmatching() throws IOException {
         try {
@@ -100,21 +100,13 @@ public abstract class AbstractUIITCase extends AbstractITCase {
             assertEquals(ClientExceptionType.NotFound, e.getType());
         }
 
-        List<SAML24UIIdPTO> idps = saml2sp4UIIdPService.list();
-        assertEquals(1, idps.size());
-
-        SAML24UIIdPTO cas = idps.get(0);
-        cas.setCreateUnmatching(false);
-        cas.setSelfRegUnmatching(true);
-        saml2sp4UIIdPService.update(cas);
-
-        try {
-            sso(ENDUSER_ADDRESS, "pullFromLDAP", "Password123");
-        } finally {
-            cas.setCreateUnmatching(true);
-            cas.setSelfRegUnmatching(false);
-            saml2sp4UIIdPService.update(cas);
-        }
+        doSelfReg(() -> {
+            try {
+                sso(ENDUSER_ADDRESS, "pullFromLDAP", "Password123");
+            } catch (IOException e) {
+                fail(e);
+            }
+        });
 
         try {
             userService.read("pullFromLDAP");
diff --git a/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/OIDC4UIITCase.java b/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/OIDC4UIITCase.java
index ac57095..05b7713 100644
--- a/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/OIDC4UIITCase.java
+++ b/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/OIDC4UIITCase.java
@@ -23,11 +23,11 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
-import static org.junit.jupiter.api.Assumptions.assumeTrue;
 
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import org.apache.http.Consts;
@@ -44,22 +44,17 @@ import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.util.EntityUtils;
+import org.apache.syncope.client.ui.commons.panels.OIDCC4UIConstants;
 import org.apache.syncope.common.lib.to.ItemTO;
-import org.apache.syncope.common.lib.to.OIDCProviderTO;
+import org.apache.syncope.common.lib.to.OIDCC4UIProviderTO;
 import org.apache.syncope.common.lib.to.client.OIDCRPTO;
 import org.apache.syncope.common.lib.types.ClientAppType;
 import org.apache.syncope.common.lib.types.OIDCSubjectType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.ext.oidcclient.agent.Constants;
 import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
 
 public class OIDC4UIITCase extends AbstractUIITCase {
 
-    private static final String CLIENT_ID = OIDC4UIITCase.class.getSimpleName();
-
-    private static final String CLIENT_SECRET = OIDC4UIITCase.class.getSimpleName();
-
     private static void clientAppSetup(final String appName, final String baseAddress, final long appId) {
         OIDCRPTO clientApp = clientAppService.list(ClientAppType.OIDCRP).stream().
                 filter(app -> appName.equals(app.getName())).
@@ -69,8 +64,8 @@ public class OIDC4UIITCase extends AbstractUIITCase {
                     OIDCRPTO app = new OIDCRPTO();
                     app.setName(appName);
                     app.setClientAppId(appId);
-                    app.setClientId(CLIENT_ID);
-                    app.setClientSecret(CLIENT_SECRET);
+                    app.setClientId(appName);
+                    app.setClientSecret(appName);
 
                     Response response = clientAppService.create(ClientAppType.OIDCRP, app);
                     if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
@@ -81,37 +76,48 @@ public class OIDC4UIITCase extends AbstractUIITCase {
                             ClientAppType.OIDCRP, response.getHeaderString(RESTHeaders.RESOURCE_KEY));
                 });
 
-        clientApp.setClientId(CLIENT_ID);
-        clientApp.setClientSecret(CLIENT_SECRET);
+        clientApp.setClientId(appName);
+        clientApp.setClientSecret(appName);
         clientApp.setSubjectType(OIDCSubjectType.PUBLIC);
-        clientApp.getRedirectUris().add(baseAddress + Constants.URL_CONTEXT + "/code-consumer");
+        clientApp.getRedirectUris().clear();
+        clientApp.getRedirectUris().add(baseAddress + OIDCC4UIConstants.URL_CONTEXT + "/code-consumer");
         clientApp.setAuthPolicy(getAuthPolicy().getKey());
         clientApp.setSignIdToken(true);
-        clientApp.setLogoutUri(baseAddress + Constants.URL_CONTEXT + "/logout");
+        clientApp.setLogoutUri(baseAddress + OIDCC4UIConstants.URL_CONTEXT + "/logout");
 
         clientAppService.update(ClientAppType.OIDCRP, clientApp);
         clientAppService.pushToWA();
     }
 
+    private static String getAppName(final String address) {
+        return CONSOLE_ADDRESS.equals(address)
+                ? OIDC4UIITCase.class.getName() + "_Console"
+                : OIDC4UIITCase.class.getName() + "_Enduser";
+    }
+
     @BeforeAll
     public static void consoleClientAppSetup() {
-        clientAppSetup(OIDC4UIITCase.class.getName() + "_Console", CONSOLE_ADDRESS, 7L);
+        clientAppSetup(getAppName(CONSOLE_ADDRESS), CONSOLE_ADDRESS, 7L);
     }
 
     @BeforeAll
     public static void enduserClientAppSetup() {
-        clientAppSetup(OIDC4UIITCase.class.getName() + "_Enduser", ENDUSER_ADDRESS, 8L);
+        clientAppSetup(getAppName(ENDUSER_ADDRESS), ENDUSER_ADDRESS, 8L);
     }
 
-    @BeforeAll
-    public static void oidcSetup() {
-        List<OIDCProviderTO> ops = oidcProviderService.list();
+    private static void oidcSetup(
+            final String appName,
+            final boolean createUnmatching,
+            final boolean selfRegUnmatching) {
+
+        Optional<OIDCC4UIProviderTO> ops = oidcProviderService.list().stream().
+                filter(op -> op.getName().equals(appName)).findFirst();
         if (ops.isEmpty()) {
-            OIDCProviderTO cas = new OIDCProviderTO();
-            cas.setName("CAS");
+            OIDCC4UIProviderTO cas = new OIDCC4UIProviderTO();
+            cas.setName(appName);
 
-            cas.setClientID(CLIENT_ID);
-            cas.setClientSecret(CLIENT_SECRET);
+            cas.setClientID(appName);
+            cas.setClientSecret(appName);
 
             cas.setIssuer(WA_ADDRESS + "/oidc/");
             cas.setAuthorizationEndpoint(WA_ADDRESS + "/oidc/authorize");
@@ -120,12 +126,12 @@ public class OIDC4UIITCase extends AbstractUIITCase {
             cas.setUserinfoEndpoint(WA_ADDRESS + "/oidc/profile");
             cas.setEndSessionEndpoint(WA_ADDRESS + "/oidc/logout");
 
-            cas.setCreateUnmatching(true);
-            cas.setSelfRegUnmatching(false);
+            cas.setCreateUnmatching(createUnmatching);
+            cas.setSelfRegUnmatching(selfRegUnmatching);
 
             ItemTO item = new ItemTO();
             item.setIntAttrName("username");
-            item.setExtAttrName("NameID");
+            item.setExtAttrName("preferred_username");
             item.setConnObjectKey(true);
             cas.setConnObjectKeyItem(item);
 
@@ -158,6 +164,16 @@ public class OIDC4UIITCase extends AbstractUIITCase {
         }
     }
 
+    @BeforeAll
+    public static void consoleOIDCSetup() {
+        oidcSetup(getAppName(CONSOLE_ADDRESS), true, false);
+    }
+
+    @BeforeAll
+    public static void enduserOIDCSetup() {
+        oidcSetup(getAppName(ENDUSER_ADDRESS), false, true);
+    }
+
     @Override
     protected void sso(final String baseURL, final String username, final String password) throws IOException {
         CloseableHttpClient httpclient = HttpClients.createDefault();
@@ -170,7 +186,7 @@ public class OIDC4UIITCase extends AbstractUIITCase {
         assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
 
         // 2. click on the OpenID Connect Provider
-        get = new HttpGet(baseURL + Constants.URL_CONTEXT + "/login?op=CAS");
+        get = new HttpGet(baseURL + OIDCC4UIConstants.URL_CONTEXT + "/login?op=" + getAppName(baseURL));
         get.addHeader(HttpHeaders.ACCEPT, MediaType.TEXT_HTML);
         get.addHeader(HttpHeaders.ACCEPT_LANGUAGE, EN_LANGUAGE);
         response = httpclient.execute(get, context);
@@ -226,35 +242,12 @@ public class OIDC4UIITCase extends AbstractUIITCase {
         response = httpclient.execute(get, context);
 
         // 3. verify that user is now authenticated
-        get = new HttpGet(response.getFirstHeader(HttpHeaders.LOCATION).getValue());
-        response = httpclient.execute(get, context);
         assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
         assertTrue(EntityUtils.toString(response.getEntity()).contains(username));
     }
 
-    @Test
-    @Override
-    public void sso2Console() throws IOException {
-        assumeTrue(false);
-        super.sso2Console();
-    }
-
-    @Test
-    @Override
-    public void sso2Enduser() throws IOException {
-        assumeTrue(false);
-        super.sso2Enduser();
-    }
-
-    @Override
-    public void createUnmatching() throws IOException {
-        assumeTrue(false);
-        super.createUnmatching();
-    }
-
     @Override
-    public void selfRegUnmatching() throws IOException {
-        assumeTrue(false);
-        super.selfRegUnmatching();
+    protected void doSelfReg(final Runnable runnable) {
+        runnable.run();
     }
 }
diff --git a/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/SAML2SP4UIITCase.java b/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/SAML2SP4UIITCase.java
index 87bc9bf..f7c2454 100644
--- a/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/SAML2SP4UIITCase.java
+++ b/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/SAML2SP4UIITCase.java
@@ -48,7 +48,7 @@ import org.apache.http.util.EntityUtils;
 import org.apache.syncope.client.ui.commons.SAML2SP4UIConstants;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.ItemTO;
-import org.apache.syncope.common.lib.to.SAML24UIIdPTO;
+import org.apache.syncope.common.lib.to.SAML2SP4UIIdPTO;
 import org.apache.syncope.common.lib.to.client.SAML2SPTO;
 import org.apache.syncope.common.lib.types.ClientAppType;
 import org.apache.syncope.common.lib.types.SAML2SPNameId;
@@ -113,10 +113,10 @@ public class SAML2SP4UIITCase extends AbstractUIITCase {
                     type(clientFactory.getContentType().getMediaType());
         }
 
-        List<SAML24UIIdPTO> idps = saml2sp4UIIdPService.list();
+        List<SAML2SP4UIIdPTO> idps = saml2sp4UIIdPService.list();
         assertEquals(1, idps.size());
 
-        SAML24UIIdPTO cas = idps.get(0);
+        SAML2SP4UIIdPTO cas = idps.get(0);
         cas.setName("CAS");
         cas.setCreateUnmatching(true);
         cas.setSelfRegUnmatching(false);
@@ -240,4 +240,23 @@ public class SAML2SP4UIITCase extends AbstractUIITCase {
         assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
         assertTrue(EntityUtils.toString(response.getEntity()).contains(username));
     }
+
+    @Override
+    protected void doSelfReg(final Runnable runnable) {
+        List<SAML2SP4UIIdPTO> idps = saml2sp4UIIdPService.list();
+        assertEquals(1, idps.size());
+
+        SAML2SP4UIIdPTO cas = idps.get(0);
+        cas.setCreateUnmatching(false);
+        cas.setSelfRegUnmatching(true);
+        saml2sp4UIIdPService.update(cas);
+
+        try {
+            runnable.run();
+        } finally {
+            cas.setCreateUnmatching(true);
+            cas.setSelfRegUnmatching(false);
+            saml2sp4UIIdPService.update(cas);
+        }
+    }
 }
diff --git a/pom.xml b/pom.xml
index f4ce4b4..9b6d98a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -636,16 +636,6 @@ under the License.
         <artifactId>cxf-rt-features-logging</artifactId>
         <version>${cxf.version}</version>
       </dependency>
-      <dependency>
-        <groupId>org.apache.cxf</groupId>
-        <artifactId>cxf-rt-rs-security-sso-oidc</artifactId>
-        <version>${cxf.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.cxf</groupId>
-        <artifactId>cxf-rt-rs-extension-providers</artifactId>
-        <version>${cxf.version}</version>
-      </dependency>
       <!-- /CXF -->
 
       <!-- Swagger -->
diff --git a/sra/src/test/resources/debug/application-debug.properties b/sra/src/test/resources/debug/application-debug.properties
index c029337..79a2950 100644
--- a/sra/src/test/resources/debug/application-debug.properties
+++ b/sra/src/test/resources/debug/application-debug.properties
@@ -14,10 +14,10 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-#am.type=OIDC
-#am.oidc.configuration=http://localhost:9080/syncope-wa/oidc/
-#am.oidc.client.id=oidcTestClientId
-#am.oidc.client.secret=oidcTestClientSecret
+am.type=OIDC
+am.oidc.configuration=http://localhost:9080/syncope-wa/oidc/
+am.oidc.client.id=oidcTestClientId
+am.oidc.client.secret=oidcTestClientSecret
 
 #am.type=OAUTH2
 #am.oauth2.tokenUri=http://localhost:9080/syncope-wa/oauth2.0/accessToken
@@ -30,20 +30,20 @@
 #am.oauth2.client.id=oauth2TestClientId
 #am.oauth2.client.secret=oauth2TestClientSecret
 
-am.type=SAML2
-am.saml2.sp.authnrequest.binding=POST
-am.saml2.sp.logout.request.binding=POST
-am.saml2.sp.logout.response.binding=REDIRECT
-am.saml2.sp.entityId=http://localhost:8080
-am.saml2.sp.skew=300
-am.saml2.idp=http://localhost:9080/syncope-wa/idp/metadata
-am.saml2.keystore=classpath:/saml.keystore.jks
-am.saml2.keystore.type=jks
-am.saml2.keystore.storepass=changeit
-am.saml2.keystore.keypass=changeit
+#am.type=SAML2
+#am.saml2.sp.authnrequest.binding=POST
+#am.saml2.sp.logout.request.binding=POST
+#am.saml2.sp.logout.response.binding=REDIRECT
+#am.saml2.sp.entityId=http://localhost:8080
+#am.saml2.sp.skew=300
+#am.saml2.idp=http://localhost:9080/syncope-wa/idp/metadata
+#am.saml2.keystore=classpath:/saml.keystore.jks
+#am.saml2.keystore.type=jks
+#am.saml2.keystore.storepass=changeit
+#am.saml2.keystore.keypass=changeit
 
 #am.type=CAS
-#am.cas.server.name=http://localhost:80
+#am.cas.server.name=http://localhost:9080
 #am.cas.url.prefix=http://localhost:9080/syncope-wa/
 
 global.postLogout=http://localhost:8080/logout
diff --git a/src/main/asciidoc/reference-guide/concepts/extensions.adoc b/src/main/asciidoc/reference-guide/concepts/extensions.adoc
index b6d51c2..345fde1 100644
--- a/src/main/asciidoc/reference-guide/concepts/extensions.adoc
+++ b/src/main/asciidoc/reference-guide/concepts/extensions.adoc
@@ -109,10 +109,10 @@ is going to be implemented in order to reach the user information to be used by
 ====
 The source code of this extension is available from the Apache Syncope
 ifeval::["{snapshotOrRelease}" == "release"]
-https://github.com/apache/syncope/tree/syncope-{docVersion}/ext/oidcclient[source tree^]
+https://github.com/apache/syncope/tree/syncope-{docVersion}/ext/oidcc4ui[source tree^]
 endif::[]
 ifeval::["{snapshotOrRelease}" == "snapshot"]
-https://github.com/apache/syncope/tree/master/ext/oidcclient[source tree^]
+https://github.com/apache/syncope/tree/master/ext/oidcc4ui[source tree^]
 endif::[]
 .
 ====
diff --git a/src/main/asciidoc/reference-guide/workingwithapachesyncope/customization.adoc b/src/main/asciidoc/reference-guide/workingwithapachesyncope/customization.adoc
index 907169a..53b87ac 100644
--- a/src/main/asciidoc/reference-guide/workingwithapachesyncope/customization.adoc
+++ b/src/main/asciidoc/reference-guide/workingwithapachesyncope/customization.adoc
@@ -385,13 +385,13 @@ Add the following dependencies to `core/pom.xml`:
 [source,xml,subs="verbatim,attributes"]
 ----
 <dependency>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-rest-cxf</artifactId>
+  <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+  <artifactId>syncope-ext-oidcc4ui-rest-cxf</artifactId>
   <version>${syncope.version}</version>
 </dependency>
 <dependency>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-persistence-jpa</artifactId>
+  <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+  <artifactId>syncope-ext-oidcc4ui-persistence-jpa</artifactId>
   <version>${syncope.version}</version>
 </dependency>
 ----
@@ -583,13 +583,13 @@ Add the following dependencies to `console/pom.xml`:
 [source,xml,subs="verbatim,attributes"]
 ----
 <dependency>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-client-console</artifactId>
+  <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+  <artifactId>syncope-ext-oidcc4ui-client-console</artifactId>
   <version>${syncope.version}</version>
 </dependency>
 ----
 
-Copy `console/src/main/resources/all/oidcclient-agent.properties` to `console/src/main/resources/oidcclient-agent.properties`.
+Copy `console/src/main/resources/all/oidcc4ui-agent.properties` to `console/src/main/resources/oidcc4ui-agent.properties`.
 
 
 [discrete]
@@ -651,14 +651,12 @@ Add the following dependencies to `enduser/pom.xml`:
 [source,xml,subs="verbatim,attributes"]
 ----
 <dependency>
-  <groupId>org.apache.syncope.ext.oidcclient</groupId>
-  <artifactId>syncope-ext-oidcclient-client-enduser</artifactId>
+  <groupId>org.apache.syncope.ext.oidcc4ui</groupId>
+  <artifactId>syncope-ext-oidcc4ui-client-enduser</artifactId>
   <version>${syncope.version}</version>
 </dependency>
 ----
 
-Copy `enduser/src/main/resources/all/oidcclient-agent.properties` to `enduser/src/main/resources/oidcclient-agent.properties`.
-
 [[customization-enduser-i18n]]
 ===== i18n