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 fb3794e  [SYNCOPE-1585] cxf-rt-rs-security-jose -> nimbus-jose-jwt
fb3794e is described below

commit fb3794e3446b61c452ab452705243ec5a693bda0
Author: Francesco Chicchiriccò <[email protected]>
AuthorDate: Tue Aug 18 16:48:04 2020 +0200

    [SYNCOPE-1585] cxf-rt-rs-security-jose -> nimbus-jose-jwt
---
 client/idrepo/console/pom.xml                      |  10 +-
 .../console/panels/AccessTokenDirectoryPanel.java  |  19 +-
 .../panels/AccessTokenDirectoryPanel.properties    |   2 +-
 .../AccessTokenDirectoryPanel_fr_CA.properties     |  10 +-
 .../panels/AccessTokenDirectoryPanel_it.properties |   2 +-
 .../panels/AccessTokenDirectoryPanel_ja.properties |   2 +-
 .../AccessTokenDirectoryPanel_pt_BR.properties     |   2 +-
 .../panels/AccessTokenDirectoryPanel_ru.properties |   2 +-
 .../client/lib/JWTAuthenticationHandler.java       |   1 -
 .../syncope/common/lib/to/AccessTokenTO.java       |  14 +-
 .../common/lib/types/ClientExceptionType.java      |   1 +
 core/idrepo/logic/pom.xml                          |   5 -
 .../core/persistence/api/entity/AccessToken.java   |   4 +-
 core/persistence-jpa-json/pom.xml                  |   5 -
 core/persistence-jpa/pom.xml                       |   5 -
 .../persistence/jpa/dao/JPAAccessTokenDAO.java     |   2 +-
 .../persistence/jpa/entity/JPAAccessToken.java     |  10 +-
 .../persistence/jpa/outer/AccessTokenTest.java     |   2 +-
 core/provisioning-java/pom.xml                     |   5 -
 .../java/data/AccessTokenDataBinderImpl.java       | 105 +++--
 core/spring/pom.xml                                |  12 +-
 .../core/spring/security/AuthDataAccessor.java     |   8 +-
 .../core/spring/security/JWTAuthentication.java    |   8 +-
 .../spring/security/JWTAuthenticationFilter.java   |  15 +-
 .../spring/security/JWTAuthenticationProvider.java |  15 +-
 .../core/spring/security/JWTSSOProvider.java       |   8 +-
 .../core/spring/security/SecurityContext.java      |  32 +-
 .../spring/security/SyncopeJWTSSOProvider.java     |  35 +-
 ...tureProvider.java => AccessTokenJWSSigner.java} |  71 ++-
 .../security/jws/AccessTokenJWSVerifier.java       |  87 ++++
 .../jws/AccessTokenJwsSignatureVerifier.java       |  91 ----
 .../apache/syncope/core/logic/SAML2SP4UILogic.java |  30 +-
 .../fit/core/reference/CustomJWTSSOProvider.java   |  45 +-
 .../org/apache/syncope/fit/AbstractITCase.java     |   6 +-
 .../org/apache/syncope/fit/core/JWTITCase.java     | 498 +++++++++------------
 pom.xml                                            |   5 -
 36 files changed, 559 insertions(+), 615 deletions(-)

diff --git a/client/idrepo/console/pom.xml b/client/idrepo/console/pom.xml
index d1faf21..0b757a7 100644
--- a/client/idrepo/console/pom.xml
+++ b/client/idrepo/console/pom.xml
@@ -64,12 +64,12 @@ under the License.
       <version>${project.version}</version>
     </dependency>
 
-    <dependency>
-      <groupId>org.apache.cxf</groupId>
-      <artifactId>cxf-rt-rs-security-jose</artifactId>
-    </dependency>
+      <dependency>
+        <groupId>com.nimbusds</groupId>
+        <artifactId>nimbus-jose-jwt</artifactId>
+      </dependency>
 
-    <dependency>
+      <dependency>
       <groupId>org.apache.pdfbox</groupId>
       <artifactId>pdfbox</artifactId>
     </dependency>
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.java
index 6d499b1..16e2ef7 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.java
@@ -18,13 +18,14 @@
  */
 package org.apache.syncope.client.console.panels;
 
+import com.nimbusds.jwt.SignedJWT;
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
-import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer;
+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.DirectoryDataProvider;
@@ -98,14 +99,18 @@ public class AccessTokenDirectoryPanel
                     final String componentId,
                     final IModel<AccessTokenTO> model) {
 
-                JwsJwtCompactConsumer consumer = new 
JwsJwtCompactConsumer(model.getObject().getBody());
-                cellItem.add(new Label(componentId,
-                        SyncopeConsoleSession.get().getDateFormat().format(
-                                new Date(consumer.getJwtClaims().getIssuedAt() 
* 1000))));
+                try {
+                    SignedJWT jwt = 
SignedJWT.parse(model.getObject().getBody());
+                    cellItem.add(new Label(componentId,
+                            
SyncopeConsoleSession.get().getDateFormat().format(jwt.getJWTClaimsSet().getIssueTime())));
+                } catch (ParseException e) {
+                    LOG.error("Could not parse JWT {}", 
model.getObject().getBody(), e);
+                    cellItem.add(new Label(componentId, StringUtils.EMPTY));
+                }
             }
         });
 
-        columns.add(new DatePropertyColumn<>(new ResourceModel("expiryTime"), 
"expiryTime", "expiryTime"));
+        columns.add(new DatePropertyColumn<>(new 
ResourceModel("expirationTime"), "expirationTime", "expirationTime"));
 
         return columns;
     }
diff --git 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.properties
 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.properties
index b55a13f..a46b957 100644
--- 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.properties
+++ 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.properties
@@ -17,5 +17,5 @@
 any.edit=Edit access token ${accessTokenTO.owner}
 any.new=New access token
 owner=Owner
-expiryTime=Expiry
+expirationTime=Expiry
 issuedAt=Start
diff --git 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_fr_CA.properties
 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_fr_CA.properties
index 0479992..e03de3d 100644
--- 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_fr_CA.properties
+++ 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_fr_CA.properties
@@ -14,8 +14,8 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-any.edit=Jeton modification acc�s ${accessTokenTO.owner}
-any.new=Jeton nouvel acc�s
-owner=Propri�taire
-expiryTime=Expiration
-issuedAt=D�but
+any.edit=Jeton modification acc\u00e8s ${accessTokenTO.owner}
+any.new=Jeton nouvel acc\u00e8s
+owner=Propri\u00e9taire
+expirationTime=Expiration
+issuedAt=D\u00e9but
diff --git 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_it.properties
 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_it.properties
index c5b59ae..abd2ed8 100644
--- 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_it.properties
+++ 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_it.properties
@@ -17,5 +17,5 @@
 any.edit=Modifica ruolo ${roleTO.key}
 any.new=Nuovo token di accesso
 owner=Proprietario
-expiryTime=Termine
+expirationTime=Termine
 issuedAt=Inizio
diff --git 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_ja.properties
 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_ja.properties
index 9026cb7..ea5b73e 100644
--- 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_ja.properties
+++ 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_ja.properties
@@ -17,5 +17,5 @@
 any.edit=\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3 
${accessTokenTO.owner} \u3092\u7de8\u96c6
 any.new=\u65b0\u3057\u3044\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3
 owner=\u30aa\u30fc\u30ca\u30fc
-expiryTime=\u671f\u9650
+expirationTime=\u671f\u9650
 issuedAt=\u958b\u59cb
diff --git 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_pt_BR.properties
 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_pt_BR.properties
index 125ba73..3424513 100644
--- 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_pt_BR.properties
+++ 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_pt_BR.properties
@@ -17,5 +17,5 @@
 any.edit=Alterar fun\u00e7\u00e3o ${roleTO.key}
 any.new=Novo token de acesso
 owner=Propriet\u00e1rio
-expiryTime=Termo
+expirationTime=Termo
 issuedAt=Iniciar
diff --git 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_ru.properties
 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_ru.properties
index 33830e1..d6ff9be 100644
--- 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_ru.properties
+++ 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel_ru.properties
@@ -18,5 +18,5 @@
 any.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c 
\u0440\u043e\u043b\u044c ${roleTO.key}
 any.new=\u041d\u043e\u0432\u044b\u0439 \u043c\u0430\u0440\u043a\u0435\u0440 
\u0434\u043e\u0441\u0442\u0443\u043f\u0430
 owner=\u0412\u043b\u0430\u0434\u0435\u043b\u0435\u0446
-expiryTime=\u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u0435 
\u0441\u0440\u043e\u043a\u0430
+expirationTime=\u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u0435 
\u0441\u0440\u043e\u043a\u0430
 issuedAt=\u041d\u0430\u0447\u0430\u043b\u043e
diff --git 
a/client/idrepo/lib/src/main/java/org/apache/syncope/client/lib/JWTAuthenticationHandler.java
 
b/client/idrepo/lib/src/main/java/org/apache/syncope/client/lib/JWTAuthenticationHandler.java
index 1a3af4c..c6ebf18 100644
--- 
a/client/idrepo/lib/src/main/java/org/apache/syncope/client/lib/JWTAuthenticationHandler.java
+++ 
b/client/idrepo/lib/src/main/java/org/apache/syncope/client/lib/JWTAuthenticationHandler.java
@@ -32,5 +32,4 @@ public class JWTAuthenticationHandler implements 
AuthenticationHandler {
     public String getJwt() {
         return jwt;
     }
-
 }
diff --git 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AccessTokenTO.java
 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AccessTokenTO.java
index c8e0784..2080c87 100644
--- 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AccessTokenTO.java
+++ 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AccessTokenTO.java
@@ -31,7 +31,7 @@ public class AccessTokenTO implements EntityTO {
 
     private String body;
 
-    private Date expiryTime;
+    private Date expirationTime;
 
     private String owner;
 
@@ -53,12 +53,12 @@ public class AccessTokenTO implements EntityTO {
         this.body = body;
     }
 
-    public Date getExpiryTime() {
-        return Optional.ofNullable(expiryTime).map(time -> new 
Date(time.getTime())).orElse(null);
+    public Date getExpirationTime() {
+        return Optional.ofNullable(expirationTime).map(time -> new 
Date(time.getTime())).orElse(null);
     }
 
-    public void setExpiryTime(final Date expiryTime) {
-        this.expiryTime = Optional.ofNullable(expiryTime).map(time -> new 
Date(time.getTime())).orElse(null);
+    public void setExpirationTime(final Date expiryTime) {
+        this.expirationTime = Optional.ofNullable(expiryTime).map(time -> new 
Date(time.getTime())).orElse(null);
     }
 
     public String getOwner() {
@@ -84,7 +84,7 @@ public class AccessTokenTO implements EntityTO {
         return new EqualsBuilder().
                 append(key, other.key).
                 append(body, other.body).
-                append(expiryTime, other.expiryTime).
+                append(expirationTime, other.expirationTime).
                 append(owner, other.owner).
                 build();
     }
@@ -94,7 +94,7 @@ public class AccessTokenTO implements EntityTO {
         return new HashCodeBuilder().
                 append(key).
                 append(body).
-                append(expiryTime).
+                append(expirationTime).
                 append(owner).
                 build();
     }
diff --git 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
index 8933913..0e170dc 100644
--- 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
+++ 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
@@ -31,6 +31,7 @@ public enum ClientExceptionType {
     EntityExists(Response.Status.CONFLICT),
     GenericPersistence(Response.Status.BAD_REQUEST),
     HasChildren(Response.Status.BAD_REQUEST),
+    InvalidAccessToken(Response.Status.INTERNAL_SERVER_ERROR),
     InvalidPrivilege(Response.Status.BAD_REQUEST),
     InvalidImplementation(Response.Status.BAD_REQUEST),
     InvalidImplementationType(Response.Status.NOT_FOUND),
diff --git a/core/idrepo/logic/pom.xml b/core/idrepo/logic/pom.xml
index cfc1aac..3c2feee 100644
--- a/core/idrepo/logic/pom.xml
+++ b/core/idrepo/logic/pom.xml
@@ -39,11 +39,6 @@ under the License.
 
   <dependencies>
     <dependency>
-      <groupId>org.apache.cxf</groupId>
-      <artifactId>cxf-rt-rs-security-jose</artifactId>
-    </dependency>
-
-    <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-context</artifactId>
     </dependency>
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccessToken.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccessToken.java
index ee68d6c..d956385 100644
--- 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccessToken.java
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccessToken.java
@@ -26,9 +26,9 @@ public interface AccessToken extends ProvidedKeyEntity {
 
     void setBody(String body);
 
-    Date getExpiryTime();
+    Date getExpirationTime();
 
-    void setExpiryTime(Date expiryTime);
+    void setExpirationTime(Date expirationTime);
 
     String getOwner();
 
diff --git a/core/persistence-jpa-json/pom.xml 
b/core/persistence-jpa-json/pom.xml
index e71f5ae..83db64d 100644
--- a/core/persistence-jpa-json/pom.xml
+++ b/core/persistence-jpa-json/pom.xml
@@ -86,11 +86,6 @@ under the License.
       <artifactId>junit-jupiter</artifactId>
       <scope>test</scope>
     </dependency>
-    <dependency>
-      <groupId>com.nimbusds</groupId>
-      <artifactId>nimbus-jose-jwt</artifactId>
-      <scope>test</scope>
-    </dependency>
   </dependencies>
 
   <build>
diff --git a/core/persistence-jpa/pom.xml b/core/persistence-jpa/pom.xml
index 8019673..0d6b810 100644
--- a/core/persistence-jpa/pom.xml
+++ b/core/persistence-jpa/pom.xml
@@ -138,11 +138,6 @@ under the License.
       <artifactId>bcprov-jdk15on</artifactId>
       <scope>test</scope>
     </dependency>
-    <dependency>
-      <groupId>com.nimbusds</groupId>
-      <artifactId>nimbus-jose-jwt</artifactId>
-      <scope>test</scope>
-    </dependency>
   </dependencies>
 
   <build>
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java
index e7fb7d8..fbe3852 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java
@@ -135,7 +135,7 @@ public class JPAAccessTokenDAO extends 
AbstractDAO<AccessToken> implements Acces
     public int deleteExpired() {
         Query query = entityManager().createQuery(
                 "DELETE FROM " + JPAAccessToken.class.getSimpleName() + " e "
-                + "WHERE e.expiryTime < :now");
+                + "WHERE e.expirationTime < :now");
         query.setParameter("now", new Date());
         return query.executeUpdate();
     }
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccessToken.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccessToken.java
index 514cf12..326c702 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccessToken.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccessToken.java
@@ -44,7 +44,7 @@ public class JPAAccessToken extends AbstractProvidedKeyEntity 
implements AccessT
     private String body;
 
     @Temporal(TemporalType.TIMESTAMP)
-    private Date expiryTime;
+    private Date expirationTime;
 
     @Column(unique = true)
     private String owner;
@@ -63,13 +63,13 @@ public class JPAAccessToken extends 
AbstractProvidedKeyEntity implements AccessT
     }
 
     @Override
-    public Date getExpiryTime() {
-        return Optional.ofNullable(expiryTime).map(time -> new 
Date(time.getTime())).orElse(null);
+    public Date getExpirationTime() {
+        return Optional.ofNullable(expirationTime).map(time -> new 
Date(time.getTime())).orElse(null);
     }
 
     @Override
-    public void setExpiryTime(final Date expiryTime) {
-        this.expiryTime = Optional.ofNullable(expiryTime).map(time -> new 
Date(time.getTime())).orElse(null);
+    public void setExpirationTime(final Date expirationTime) {
+        this.expirationTime = Optional.ofNullable(expirationTime).map(time -> 
new Date(time.getTime())).orElse(null);
     }
 
     @Override
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AccessTokenTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AccessTokenTest.java
index 9272302..f36906f 100644
--- 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AccessTokenTest.java
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AccessTokenTest.java
@@ -42,7 +42,7 @@ public class AccessTokenTest extends AbstractTest {
         AccessToken accessToken = entityFactory.newEntity(AccessToken.class);
         accessToken.setKey(UUID.randomUUID().toString());
         accessToken.setBody("pointless body");
-        accessToken.setExpiryTime(new Date());
+        accessToken.setExpirationTime(new Date());
         accessToken.setOwner("bellini");
 
         accessToken = accessTokenDAO.save(accessToken);
diff --git a/core/provisioning-java/pom.xml b/core/provisioning-java/pom.xml
index 9ac7db6..5a2211e 100644
--- a/core/provisioning-java/pom.xml
+++ b/core/provisioning-java/pom.xml
@@ -97,11 +97,6 @@ under the License.
     </dependency>
 
     <dependency>
-      <groupId>com.nimbusds</groupId>
-      <artifactId>nimbus-jose-jwt</artifactId>
-    </dependency>
-
-    <dependency>
       <groupId>org.apache.syncope.core</groupId>
       <artifactId>syncope-core-workflow-api</artifactId>
       <version>${project.version}</version>
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
index 343dd84..cb9ff1f 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
@@ -18,18 +18,20 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.SignedJWT;
+import java.text.ParseException;
+import java.util.Calendar;
 import java.util.Date;
 import java.util.Map;
 import javax.annotation.Resource;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.cxf.rs.security.jose.common.JoseType;
-import org.apache.cxf.rs.security.jose.jws.JwsHeaders;
-import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer;
-import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactProducer;
-import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
-import org.apache.cxf.rs.security.jose.jwt.JwtToken;
 import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
+import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AccessTokenTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
 import org.apache.syncope.core.persistence.api.entity.AccessToken;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
@@ -37,7 +39,7 @@ import 
org.apache.syncope.core.provisioning.api.data.AccessTokenDataBinder;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.security.DefaultCredentialChecker;
 import org.apache.syncope.core.spring.security.SecureRandomUtils;
-import 
org.apache.syncope.core.spring.security.jws.AccessTokenJwsSignatureProvider;
+import org.apache.syncope.core.spring.security.jws.AccessTokenJWSSigner;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -51,7 +53,7 @@ public class AccessTokenDataBinderImpl implements 
AccessTokenDataBinder {
     private String jwtIssuer;
 
     @Autowired
-    private AccessTokenJwsSignatureProvider jwsSignatureProvider;
+    private AccessTokenJWSSigner jwsSigner;
 
     @Autowired
     private AccessTokenDAO accessTokenDAO;
@@ -74,25 +76,30 @@ public class AccessTokenDataBinderImpl implements 
AccessTokenDataBinder {
 
         credentialChecker.checkIsDefaultJWSKeyInUse();
 
-        long currentTime = new Date().getTime() / 1000L;
-        long expiryTime = currentTime + 60L * duration;
-
-        JwtClaims jwtClaims = new JwtClaims();
-        jwtClaims.setTokenId(tokenId);
-        jwtClaims.setSubject(subject);
-        jwtClaims.setIssuedAt(currentTime);
-        jwtClaims.setIssuer(jwtIssuer);
-        jwtClaims.setExpiryTime(expiryTime);
-        jwtClaims.setNotBefore(currentTime);
-        claims.forEach(jwtClaims::setClaim);
-
-        JwsHeaders jwsHeaders = new JwsHeaders(JoseType.JWT, 
jwsSignatureProvider.getAlgorithm());
-        JwtToken token = new JwtToken(jwsHeaders, jwtClaims);
-        JwsJwtCompactProducer producer = new JwsJwtCompactProducer(token);
-
-        String signed = producer.signWith(jwsSignatureProvider);
-
-        return Pair.of(signed, new Date(expiryTime * 1000L));
+        Date currentTime = new Date();
+
+        Calendar expiration = Calendar.getInstance();
+        expiration.setTime(currentTime);
+        expiration.add(Calendar.MINUTE, (int) duration);
+
+        JWTClaimsSet.Builder claimsSet = new JWTClaimsSet.Builder().
+                jwtID(tokenId).
+                subject(subject).
+                issueTime(currentTime).
+                issuer(jwtIssuer).
+                expirationTime(expiration.getTime()).
+                notBeforeTime(currentTime);
+        claims.forEach(claimsSet::claim);
+
+        SignedJWT jwt = new SignedJWT(new 
JWSHeader(jwsSigner.getJwsAlgorithm()), claimsSet.build());
+        try {
+            jwt.sign(jwsSigner);
+        } catch (JOSEException e) {
+            SyncopeClientException sce = 
SyncopeClientException.build(ClientExceptionType.InvalidAccessToken);
+            sce.getElements().add(e.getMessage());
+            throw sce;
+        }
+        return Pair.of(jwt.serialize(), expiration.getTime());
     }
 
     private AccessToken replace(
@@ -108,7 +115,7 @@ public class AccessTokenDataBinderImpl implements 
AccessTokenDataBinder {
                 claims);
 
         accessToken.setBody(generated.getLeft());
-        accessToken.setExpiryTime(generated.getRight());
+        accessToken.setExpirationTime(generated.getRight());
         accessToken.setOwner(subject);
 
         if (!adminUser.equals(accessToken.getOwner())) {
@@ -132,35 +139,45 @@ public class AccessTokenDataBinderImpl implements 
AccessTokenDataBinder {
             
accessToken.setKey(SecureRandomUtils.generateRandomUUID().toString());
 
             accessToken = replace(subject, claims, authorities, accessToken);
-        } else if (replace || accessToken.getExpiryTime() == null || 
accessToken.getExpiryTime().before(new Date())) {
+        } else if (replace || accessToken.getExpirationTime() == null
+                || accessToken.getExpirationTime().before(new Date())) {
+
             // AccessToken found, but either replace was requested or it is 
expired: update existing
             accessToken = replace(subject, claims, authorities, accessToken);
         }
 
-        return Pair.of(accessToken.getBody(), accessToken.getExpiryTime());
+        return Pair.of(accessToken.getBody(), accessToken.getExpirationTime());
     }
 
     @Override
     public Pair<String, Date> update(final AccessToken accessToken, final 
byte[] authorities) {
-        JwsJwtCompactConsumer consumer = new 
JwsJwtCompactConsumer(accessToken.getBody());
-
         credentialChecker.checkIsDefaultJWSKeyInUse();
 
         long duration = confParamOps.get(AuthContextUtils.getDomain(), 
"jwt.lifetime.minutes", 120L, Long.class);
-        long currentTime = new Date().getTime() / 1000L;
-        long expiry = currentTime + 60L * duration;
-        consumer.getJwtClaims().setExpiryTime(expiry);
-        Date expiryDate = new Date(expiry * 1000L);
 
-        JwsHeaders jwsHeaders = new JwsHeaders(JoseType.JWT, 
jwsSignatureProvider.getAlgorithm());
-        JwtToken token = new JwtToken(jwsHeaders, consumer.getJwtClaims());
-        JwsJwtCompactProducer producer = new JwsJwtCompactProducer(token);
+        Date currentTime = new Date();
+
+        Calendar expiration = Calendar.getInstance();
+        expiration.setTime(currentTime);
+        expiration.add(Calendar.MINUTE, (int) duration);
 
-        String body = producer.signWith(jwsSignatureProvider);
+        SignedJWT jwt;
+        try {
+            JWTClaimsSet.Builder claimsSet =
+                    new 
JWTClaimsSet.Builder(SignedJWT.parse(accessToken.getBody()).getJWTClaimsSet()).
+                            expirationTime(expiration.getTime());
+
+            jwt = new SignedJWT(new JWSHeader(jwsSigner.getJwsAlgorithm()), 
claimsSet.build());
+            jwt.sign(jwsSigner);
+        } catch (ParseException | JOSEException e) {
+            SyncopeClientException sce = 
SyncopeClientException.build(ClientExceptionType.InvalidAccessToken);
+            sce.getElements().add(e.getMessage());
+            throw sce;
+        }
+        String body = jwt.serialize();
 
         accessToken.setBody(body);
-        // AccessToken stores expiry time in milliseconds, as opposed to 
seconds for the JWT tokens.
-        accessToken.setExpiryTime(expiryDate);
+        accessToken.setExpirationTime(expiration.getTime());
 
         if (!adminUser.equals(accessToken.getOwner())) {
             accessToken.setAuthorities(authorities);
@@ -168,7 +185,7 @@ public class AccessTokenDataBinderImpl implements 
AccessTokenDataBinder {
 
         accessTokenDAO.save(accessToken);
 
-        return Pair.of(body, expiryDate);
+        return Pair.of(body, expiration.getTime());
     }
 
     @Override
@@ -176,7 +193,7 @@ public class AccessTokenDataBinderImpl implements 
AccessTokenDataBinder {
         AccessTokenTO accessTokenTO = new AccessTokenTO();
         accessTokenTO.setKey(accessToken.getKey());
         accessTokenTO.setBody(accessToken.getBody());
-        accessTokenTO.setExpiryTime(accessToken.getExpiryTime());
+        accessTokenTO.setExpirationTime(accessToken.getExpirationTime());
         accessTokenTO.setOwner(accessToken.getOwner());
 
         return accessTokenTO;
diff --git a/core/spring/pom.xml b/core/spring/pom.xml
index 0d9f953..80dcd6b 100644
--- a/core/spring/pom.xml
+++ b/core/spring/pom.xml
@@ -53,13 +53,13 @@ under the License.
       <groupId>org.jasypt</groupId>
       <artifactId>jasypt</artifactId>
     </dependency>
-    
-    <dependency>
-      <groupId>org.apache.cxf</groupId>
-      <artifactId>cxf-rt-rs-security-jose</artifactId>
-    </dependency>
 
-    <dependency>
+      <dependency>
+        <groupId>com.nimbusds</groupId>
+        <artifactId>nimbus-jose-jwt</artifactId>
+      </dependency>
+
+      <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-autoconfigure</artifactId>
     </dependency>
diff --git 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
index 125b5f6..43957ad 100644
--- 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
+++ 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
@@ -368,10 +368,10 @@ public class AuthDataAccessor {
         Set<SyncopeGrantedAuthority> authorities;
 
         if (adminUser.equals(authentication.getClaims().getSubject())) {
-            AccessToken accessToken = 
accessTokenDAO.find(authentication.getClaims().getTokenId());
+            AccessToken accessToken = 
accessTokenDAO.find(authentication.getClaims().getJWTID());
             if (accessToken == null) {
                 throw new AuthenticationCredentialsNotFoundException(
-                        "Could not find an Access Token for JWT " + 
authentication.getClaims().getTokenId());
+                        "Could not find an Access Token for JWT " + 
authentication.getClaims().getJWTID());
             }
 
             username = adminUser;
@@ -382,14 +382,14 @@ public class AuthDataAccessor {
             if (resolved == null || resolved.getLeft() == null) {
                 throw new AuthenticationCredentialsNotFoundException(
                         "Could not find User " + 
authentication.getClaims().getSubject()
-                        + " for JWT " + 
authentication.getClaims().getTokenId());
+                        + " for JWT " + authentication.getClaims().getJWTID());
             }
 
             User user = resolved.getLeft();
             username = user.getUsername();
             authorities = resolved.getRight() == null ? Set.of() : 
resolved.getRight();
             LOG.debug("JWT {} issued by {} resolved to User {} with 
authorities {}",
-                    authentication.getClaims().getTokenId(),
+                    authentication.getClaims().getJWTID(),
                     authentication.getClaims().getIssuer(),
                     username, authorities);
 
diff --git 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthentication.java
 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthentication.java
index 846693c..314d2b5 100644
--- 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthentication.java
+++ 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthentication.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.spring.security;
 
+import com.nimbusds.jwt.JWTClaimsSet;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Optional;
@@ -26,7 +27,6 @@ import java.util.stream.Collectors;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
 import org.springframework.security.core.Authentication;
 
 /**
@@ -38,7 +38,7 @@ public class JWTAuthentication implements Authentication {
 
     private static final long serialVersionUID = -2013733709281305394L;
 
-    private final JwtClaims claims;
+    private final JWTClaimsSet claims;
 
     private final SyncopeAuthenticationDetails details;
 
@@ -48,12 +48,12 @@ public class JWTAuthentication implements Authentication {
 
     private boolean authenticated = false;
 
-    public JWTAuthentication(final JwtClaims claims, final 
SyncopeAuthenticationDetails details) {
+    public JWTAuthentication(final JWTClaimsSet claims, final 
SyncopeAuthenticationDetails details) {
         this.claims = claims;
         this.details = details;
     }
 
-    public JwtClaims getClaims() {
+    public JWTClaimsSet getClaims() {
         return claims;
     }
 
diff --git 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthenticationFilter.java
 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthenticationFilter.java
index e78c494..9a6eef9 100644
--- 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthenticationFilter.java
+++ 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthenticationFilter.java
@@ -18,7 +18,10 @@
  */
 package org.apache.syncope.core.spring.security;
 
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jwt.SignedJWT;
 import java.io.IOException;
+import java.text.ParseException;
 import java.util.Optional;
 import java.util.Set;
 import javax.servlet.FilterChain;
@@ -27,8 +30,6 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.ws.rs.core.HttpHeaders;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.cxf.rs.security.jose.jws.JwsException;
-import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.security.authentication.AuthenticationManager;
@@ -88,14 +89,14 @@ public class JWTAuthenticationFilter extends 
BasicAuthenticationFilter {
         try {
             credentialChecker.checkIsDefaultJWSKeyInUse();
 
-            JwsJwtCompactConsumer consumer = new 
JwsJwtCompactConsumer(stringToken);
-            JWTSSOProvider jwtSSOProvider = 
dataAccessor.getJWTSSOProvider(consumer.getJwtClaims().getIssuer());
-            if (!consumer.verifySignatureWith(jwtSSOProvider)) {
+            SignedJWT jwt = SignedJWT.parse(stringToken);
+            JWTSSOProvider jwtSSOProvider = 
dataAccessor.getJWTSSOProvider(jwt.getJWTClaimsSet().getIssuer());
+            if (!jwt.verify(jwtSSOProvider)) {
                 throw new BadCredentialsException("Invalid signature found in 
JWT");
             }
 
             JWTAuthentication jwtAuthentication =
-                    new JWTAuthentication(consumer.getJwtClaims(), 
authenticationDetailsSource.buildDetails(request));
+                    new JWTAuthentication(jwt.getJWTClaimsSet(), 
authenticationDetailsSource.buildDetails(request));
             
AuthContextUtils.callAsAdmin(jwtAuthentication.getDetails().getDomain(), () -> {
                 Pair<String, Set<SyncopeGrantedAuthority>> authenticated = 
dataAccessor.authenticate(jwtAuthentication);
                 jwtAuthentication.setUsername(authenticated.getLeft());
@@ -105,7 +106,7 @@ public class JWTAuthenticationFilter extends 
BasicAuthenticationFilter {
             
SecurityContextHolder.getContext().setAuthentication(jwtAuthentication);
 
             chain.doFilter(request, response);
-        } catch (JwsException e) {
+        } catch (ParseException | JOSEException e) {
             SecurityContextHolder.clearContext();
             this.authenticationEntryPoint.commence(
                     request, response, new BadCredentialsException("Invalid 
JWT: " + stringToken, e));
diff --git 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthenticationProvider.java
 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthenticationProvider.java
index 9580070..2a5865d 100644
--- 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthenticationProvider.java
+++ 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTAuthenticationProvider.java
@@ -18,7 +18,8 @@
  */
 package org.apache.syncope.core.spring.security;
 
-import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
+import com.nimbusds.jwt.JWTClaimsSet;
+import java.util.Date;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.AuthenticationProvider;
 import org.springframework.security.authentication.CredentialsExpiredException;
@@ -38,17 +39,17 @@ public class JWTAuthenticationProvider implements 
AuthenticationProvider {
     public Authentication authenticate(final Authentication authentication) 
throws AuthenticationException {
         JWTAuthentication jwtAuthentication = (JWTAuthentication) 
authentication;
 
-        JwtClaims claims = jwtAuthentication.getClaims();
+        JWTClaimsSet claims = jwtAuthentication.getClaims();
         Long referenceTime = System.currentTimeMillis();
 
-        Long expiryTime = claims.getExpiryTime();
-        if (expiryTime == null || (expiryTime * 1000L) < referenceTime) {
-            dataAccessor.removeExpired(claims.getTokenId());
+        Date expiryTime = claims.getExpirationTime();
+        if (expiryTime == null || expiryTime.getTime() < referenceTime) {
+            dataAccessor.removeExpired(claims.getJWTID());
             throw new CredentialsExpiredException("JWT is expired");
         }
 
-        Long notBefore = claims.getNotBefore();
-        if (notBefore == null || (notBefore * 1000L) > referenceTime) {
+        Date notBefore = claims.getNotBeforeTime();
+        if (notBefore == null || notBefore.getTime() > referenceTime) {
             throw new CredentialsExpiredException("JWT not valid yet");
         }
 
diff --git 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTSSOProvider.java
 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTSSOProvider.java
index 9bcdf44..900aabb 100644
--- 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTSSOProvider.java
+++ 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTSSOProvider.java
@@ -18,17 +18,17 @@
  */
 package org.apache.syncope.core.spring.security;
 
+import com.nimbusds.jose.JWSVerifier;
+import com.nimbusds.jwt.JWTClaimsSet;
 import java.util.Set;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
-import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 
 /**
  * Enables a generic mechanism for JWT validation and subject resolution which 
allows to plug in implementations
  * recognizing JWT produced by third parties.
  */
-public interface JWTSSOProvider extends JwsSignatureVerifier {
+public interface JWTSSOProvider extends JWSVerifier {
 
     /**
      * Gives the identifier for the JWT issuer verified by this instance.
@@ -44,5 +44,5 @@ public interface JWTSSOProvider extends JwsSignatureVerifier {
      * @param jwtClaims JWT claims
      * @return internal User, with authorities, matching the provided JWT 
claims, if found; otherwise null
      */
-    Pair<User, Set<SyncopeGrantedAuthority>> resolve(JwtClaims jwtClaims);
+    Pair<User, Set<SyncopeGrantedAuthority>> resolve(JWTClaimsSet jwtClaims);
 }
diff --git 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecurityContext.java
 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecurityContext.java
index e8c5779..1c71c05 100644
--- 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecurityContext.java
+++ 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecurityContext.java
@@ -18,10 +18,14 @@
  */
 package org.apache.syncope.core.spring.security;
 
-import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.KeyLengthException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
-import 
org.apache.syncope.core.spring.security.jws.AccessTokenJwsSignatureProvider;
-import 
org.apache.syncope.core.spring.security.jws.AccessTokenJwsSignatureVerifier;
+import org.apache.syncope.core.spring.security.jws.AccessTokenJWSSigner;
+import org.apache.syncope.core.spring.security.jws.AccessTokenJWSVerifier;
 import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.context.EnvironmentAware;
 import org.springframework.context.annotation.Bean;
@@ -85,20 +89,22 @@ public class SecurityContext implements EnvironmentAware {
 
     @ConditionalOnMissingBean
     @Bean
-    public AccessTokenJwsSignatureVerifier accessTokenJwsSignatureVerifier() {
-        AccessTokenJwsSignatureVerifier verifier = new 
AccessTokenJwsSignatureVerifier();
-        verifier.setJwsAlgorithm(env.getProperty("jwsAlgorithm", 
SignatureAlgorithm.class));
-        verifier.setJwsKey(jwsKey());
-        return verifier;
+    public AccessTokenJWSVerifier accessTokenJWSVerifier()
+            throws JOSEException, NoSuchAlgorithmException, 
InvalidKeySpecException {
+
+        return new AccessTokenJWSVerifier(
+                JWSAlgorithm.parse(env.getProperty("jwsAlgorithm")),
+                jwsKey());
     }
 
     @ConditionalOnMissingBean
     @Bean
-    public AccessTokenJwsSignatureProvider accessTokenJwsSignatureProvider() {
-        AccessTokenJwsSignatureProvider provider = new 
AccessTokenJwsSignatureProvider();
-        provider.setJwsAlgorithm(env.getProperty("jwsAlgorithm", 
SignatureAlgorithm.class));
-        provider.setJwsKey(jwsKey());
-        return provider;
+    public AccessTokenJWSSigner accessTokenJWSSigner()
+            throws KeyLengthException, NoSuchAlgorithmException, 
InvalidKeySpecException {
+
+        return new AccessTokenJWSSigner(
+                JWSAlgorithm.parse(env.getProperty("jwsAlgorithm")),
+                jwsKey());
     }
 
     @ConditionalOnMissingBean
diff --git 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeJWTSSOProvider.java
 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeJWTSSOProvider.java
index d813370..2253b4a 100644
--- 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeJWTSSOProvider.java
+++ 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeJWTSSOProvider.java
@@ -19,21 +19,22 @@
 package org.apache.syncope.core.spring.security;
 
 import com.fasterxml.jackson.core.type.TypeReference;
-
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jose.jca.JCAContext;
+import com.nimbusds.jose.util.Base64URL;
+import com.nimbusds.jwt.JWTClaimsSet;
 import java.util.Set;
 import javax.annotation.Resource;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
-import org.apache.cxf.rs.security.jose.jws.JwsHeaders;
-import org.apache.cxf.rs.security.jose.jws.JwsVerificationSignature;
-import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.AccessToken;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
-import 
org.apache.syncope.core.spring.security.jws.AccessTokenJwsSignatureVerifier;
+import org.apache.syncope.core.spring.security.jws.AccessTokenJWSVerifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -52,7 +53,7 @@ public class SyncopeJWTSSOProvider implements JWTSSOProvider {
     private String jwtIssuer;
 
     @Autowired
-    private AccessTokenJwsSignatureVerifier delegate;
+    private AccessTokenJWSVerifier delegate;
 
     @Autowired
     private UserDAO userDAO;
@@ -66,27 +67,31 @@ public class SyncopeJWTSSOProvider implements 
JWTSSOProvider {
     }
 
     @Override
-    public SignatureAlgorithm getAlgorithm() {
-        return delegate.getAlgorithm();
+    public Set<JWSAlgorithm> supportedJWSAlgorithms() {
+        return delegate.supportedJWSAlgorithms();
     }
 
     @Override
-    public boolean verify(final JwsHeaders headers, final String unsignedText, 
final byte[] signature) {
-        return delegate.verify(headers, unsignedText, signature);
+    public JCAContext getJCAContext() {
+        return delegate.getJCAContext();
     }
 
     @Override
-    public JwsVerificationSignature createJwsVerificationSignature(final 
JwsHeaders headers) {
-        return delegate.createJwsVerificationSignature(headers);
+    public boolean verify(
+            final JWSHeader header,
+            final byte[] signingInput,
+            final Base64URL signature) throws JOSEException {
+
+        return delegate.verify(header, signingInput, signature);
     }
 
     @Transactional(readOnly = true)
     @Override
-    public Pair<User, Set<SyncopeGrantedAuthority>> resolve(final JwtClaims 
jwtClaims) {
+    public Pair<User, Set<SyncopeGrantedAuthority>> resolve(final JWTClaimsSet 
jwtClaims) {
         User user = userDAO.findByUsername(jwtClaims.getSubject());
         Set<SyncopeGrantedAuthority> authorities = Set.of();
         if (user != null) {
-            AccessToken accessToken = 
accessTokenDAO.find(jwtClaims.getTokenId());
+            AccessToken accessToken = 
accessTokenDAO.find(jwtClaims.getJWTID());
             if (accessToken != null && accessToken.getAuthorities() != null) {
                 try {
                     authorities = POJOHelper.deserialize(
diff --git 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/jws/AccessTokenJwsSignatureProvider.java
 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/jws/AccessTokenJWSSigner.java
similarity index 51%
rename from 
core/spring/src/main/java/org/apache/syncope/core/spring/security/jws/AccessTokenJwsSignatureProvider.java
rename to 
core/spring/src/main/java/org/apache/syncope/core/spring/security/jws/AccessTokenJWSSigner.java
index 8bdedf9..b6f7da7 100644
--- 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/jws/AccessTokenJwsSignatureProvider.java
+++ 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/jws/AccessTokenJWSSigner.java
@@ -18,45 +18,38 @@
  */
 package org.apache.syncope.core.spring.security.jws;
 
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jose.JWSSigner;
+import com.nimbusds.jose.KeyLengthException;
+import com.nimbusds.jose.crypto.MACSigner;
+import com.nimbusds.jose.crypto.RSASSASigner;
+import com.nimbusds.jose.jca.JCAContext;
+import com.nimbusds.jose.util.Base64URL;
 import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
 import java.security.spec.PKCS8EncodedKeySpec;
 import java.util.Base64;
+import java.util.Set;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
-import org.apache.cxf.rs.security.jose.jws.HmacJwsSignatureProvider;
-import org.apache.cxf.rs.security.jose.jws.JwsHeaders;
-import org.apache.cxf.rs.security.jose.jws.JwsSignature;
-import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider;
-import org.apache.cxf.rs.security.jose.jws.PrivateKeyJwsSignatureProvider;
-import org.springframework.beans.factory.InitializingBean;
 
-public class AccessTokenJwsSignatureProvider implements JwsSignatureProvider, 
InitializingBean {
+public class AccessTokenJWSSigner implements JWSSigner {
 
-    private SignatureAlgorithm jwsAlgorithm;
+    private final JWSAlgorithm jwsAlgorithm;
 
-    private String jwsKey;
+    private final JWSSigner delegate;
 
-    private JwsSignatureProvider delegate;
+    public AccessTokenJWSSigner(final JWSAlgorithm jwsAlgorithm, final String 
jwsKey)
+            throws KeyLengthException, NoSuchAlgorithmException, 
InvalidKeySpecException {
 
-    public void setJwsAlgorithm(final SignatureAlgorithm jwsAlgorithm) {
-        this.jwsAlgorithm = jwsAlgorithm;
-    }
-
-    public void setJwsKey(final String jwsKey) {
-        this.jwsKey = jwsKey;
-    }
-
-    @Override
-    public void afterPropertiesSet() throws Exception {
         if (jwsAlgorithm == null) {
-            throw new IllegalArgumentException("An instance of " + 
SignatureAlgorithm.class + " is required");
+            throw new IllegalArgumentException("An instance of " + 
JWSAlgorithm.class + " is required");
         }
+        this.jwsAlgorithm = jwsAlgorithm;
 
-        if (SignatureAlgorithm.isPublicKeyAlgorithm(jwsAlgorithm)) {
-            if (!jwsAlgorithm.getJwaName().startsWith("RS")) {
-                throw new IllegalArgumentException(jwsAlgorithm.getJavaName() 
+ " not supported.");
-            }
-
+        if (JWSAlgorithm.Family.RSA.contains(jwsAlgorithm)) {
             if (jwsKey == null || jwsKey.indexOf(':') == -1) {
                 throw new IllegalArgumentException("A key pair is required, in 
the 'private:public' format");
             }
@@ -64,28 +57,34 @@ public class AccessTokenJwsSignatureProvider implements 
JwsSignatureProvider, In
             KeyFactory kf = KeyFactory.getInstance("RSA");
             PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(
                     
Base64.getDecoder().decode(StringUtils.substringBefore(jwsKey, 
":").getBytes()));
-            delegate = new 
PrivateKeyJwsSignatureProvider(kf.generatePrivate(keySpecPKCS8), jwsAlgorithm);
-        } else {
+            delegate = new RSASSASigner(kf.generatePrivate(keySpecPKCS8));
+        } else if (JWSAlgorithm.Family.HMAC_SHA.contains(jwsAlgorithm)) {
             if (jwsKey == null) {
                 throw new IllegalArgumentException("A shared key is required");
             }
 
-            delegate = new HmacJwsSignatureProvider(jwsKey.getBytes(), 
jwsAlgorithm);
+            delegate = new MACSigner(jwsKey);
+        } else {
+            throw new IllegalArgumentException("Unsupported JWS algorithm: " + 
jwsAlgorithm.getName());
         }
     }
 
+    public JWSAlgorithm getJwsAlgorithm() {
+        return jwsAlgorithm;
+    }
+
     @Override
-    public SignatureAlgorithm getAlgorithm() {
-        return delegate.getAlgorithm();
+    public Set<JWSAlgorithm> supportedJWSAlgorithms() {
+        return delegate.supportedJWSAlgorithms();
     }
 
     @Override
-    public byte[] sign(final JwsHeaders headers, final byte[] content) {
-        return delegate.sign(headers, content);
+    public JCAContext getJCAContext() {
+        return delegate.getJCAContext();
     }
 
     @Override
-    public JwsSignature createJwsSignature(final JwsHeaders headers) {
-        return delegate.createJwsSignature(headers);
+    public Base64URL sign(final JWSHeader header, final byte[] signingInput) 
throws JOSEException {
+        return delegate.sign(header, signingInput);
     }
 }
diff --git 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/jws/AccessTokenJWSVerifier.java
 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/jws/AccessTokenJWSVerifier.java
new file mode 100644
index 0000000..6fa2275
--- /dev/null
+++ 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/jws/AccessTokenJWSVerifier.java
@@ -0,0 +1,87 @@
+/*
+ * 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.spring.security.jws;
+
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jose.JWSVerifier;
+import com.nimbusds.jose.crypto.MACVerifier;
+import com.nimbusds.jose.crypto.RSASSAVerifier;
+import com.nimbusds.jose.jca.JCAContext;
+import com.nimbusds.jose.util.Base64URL;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
+import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
+
+public class AccessTokenJWSVerifier implements JWSVerifier {
+
+    private final JWSVerifier delegate;
+
+    public AccessTokenJWSVerifier(final JWSAlgorithm jwsAlgorithm, final 
String jwsKey)
+            throws JOSEException, NoSuchAlgorithmException, 
InvalidKeySpecException {
+
+        if (jwsAlgorithm == null) {
+            throw new IllegalArgumentException("An instance of " + 
JWSAlgorithm.class + " is required");
+        }
+
+        if (JWSAlgorithm.Family.RSA.contains(jwsAlgorithm)) {
+            if (jwsKey == null || jwsKey.indexOf(':') == -1) {
+                throw new IllegalArgumentException("A key pair is required, in 
the 'private:public' format");
+            }
+
+            KeyFactory kf = KeyFactory.getInstance("RSA");
+            X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(
+                    
Base64.getDecoder().decode(StringUtils.substringAfter(jwsKey, ":").getBytes()));
+            delegate = new RSASSAVerifier((RSAPublicKey) 
kf.generatePublic(keySpecX509));
+        } else if (JWSAlgorithm.Family.HMAC_SHA.contains(jwsAlgorithm)) {
+            if (jwsKey == null) {
+                throw new IllegalArgumentException("A shared key is required");
+            }
+
+            delegate = new MACVerifier(jwsKey);
+        } else {
+            throw new IllegalArgumentException("Unsupported JWS algorithm: " + 
jwsAlgorithm.getName());
+        }
+    }
+
+    @Override
+    public Set<JWSAlgorithm> supportedJWSAlgorithms() {
+        return delegate.supportedJWSAlgorithms();
+    }
+
+    @Override
+    public JCAContext getJCAContext() {
+        return delegate.getJCAContext();
+    }
+
+    @Override
+    public boolean verify(
+            final JWSHeader header,
+            final byte[] signingInput,
+            final Base64URL signature) throws JOSEException {
+
+        return delegate.verify(header, signingInput, signature);
+    }
+}
diff --git 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/jws/AccessTokenJwsSignatureVerifier.java
 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/jws/AccessTokenJwsSignatureVerifier.java
deleted file mode 100644
index 0a6f6b9..0000000
--- 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/jws/AccessTokenJwsSignatureVerifier.java
+++ /dev/null
@@ -1,91 +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.spring.security.jws;
-
-import java.security.KeyFactory;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Base64;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
-import org.apache.cxf.rs.security.jose.jws.HmacJwsSignatureVerifier;
-import org.apache.cxf.rs.security.jose.jws.JwsHeaders;
-import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
-import org.apache.cxf.rs.security.jose.jws.JwsVerificationSignature;
-import org.apache.cxf.rs.security.jose.jws.PublicKeyJwsSignatureVerifier;
-import org.springframework.beans.factory.InitializingBean;
-
-public class AccessTokenJwsSignatureVerifier implements JwsSignatureVerifier, 
InitializingBean {
-
-    private SignatureAlgorithm jwsAlgorithm;
-
-    private String jwsKey;
-
-    private JwsSignatureVerifier delegate;
-
-    public void setJwsAlgorithm(final SignatureAlgorithm jwsAlgorithm) {
-        this.jwsAlgorithm = jwsAlgorithm;
-    }
-
-    public void setJwsKey(final String jwsKey) {
-        this.jwsKey = jwsKey;
-    }
-
-    @Override
-    public void afterPropertiesSet() throws Exception {
-        if (jwsAlgorithm == null) {
-            throw new IllegalArgumentException("An instance of " + 
SignatureAlgorithm.class + " is required");
-        }
-
-        if (SignatureAlgorithm.isPublicKeyAlgorithm(jwsAlgorithm)) {
-            if (!jwsAlgorithm.getJwaName().startsWith("RS")) {
-                throw new IllegalArgumentException(jwsAlgorithm.getJavaName() 
+ " not supported.");
-            }
-
-            if (jwsKey == null || jwsKey.indexOf(':') == -1) {
-                throw new IllegalArgumentException("A key pair is required, in 
the 'private:public' format");
-            }
-
-            KeyFactory kf = KeyFactory.getInstance("RSA");
-            X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(
-                    
Base64.getDecoder().decode(StringUtils.substringAfter(jwsKey, ":").getBytes()));
-            delegate = new 
PublicKeyJwsSignatureVerifier(kf.generatePublic(keySpecX509), jwsAlgorithm);
-        } else {
-            if (jwsKey == null) {
-                throw new IllegalArgumentException("A shared key is required");
-            }
-
-            delegate = new HmacJwsSignatureVerifier(jwsKey.getBytes(), 
jwsAlgorithm);
-        }
-    }
-
-    @Override
-    public SignatureAlgorithm getAlgorithm() {
-        return delegate.getAlgorithm();
-    }
-
-    @Override
-    public boolean verify(final JwsHeaders headers, final String unsignedText, 
final byte[] signature) {
-        return delegate.verify(headers, unsignedText, signature);
-    }
-
-    @Override
-    public JwsVerificationSignature createJwsVerificationSignature(final 
JwsHeaders headers) {
-        return delegate.createJwsVerificationSignature(headers);
-    }
-}
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 135146a..59978ad 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
@@ -18,9 +18,12 @@
  */
 package org.apache.syncope.core.logic;
 
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.SignedJWT;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.lang.reflect.Method;
+import java.text.ParseException;
 import java.util.Base64;
 import java.util.Date;
 import java.util.HashMap;
@@ -28,11 +31,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
-import javax.annotation.Resource;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer;
-import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
 import org.apache.syncope.common.lib.Attr;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.EntityTO;
@@ -119,9 +119,6 @@ public class SAML2SP4UILogic extends 
AbstractTransactionalLogic<EntityTO> {
     @Autowired
     private AuthDataAccessor authDataAccessor;
 
-    @Resource(name = "accessTokenJwsSignatureVerifier")
-    private JwsSignatureVerifier jwsSignatureVerifier;
-
     private final Map<String, String> metadataCache = new 
ConcurrentHashMap<>();
 
     private static String validateUrl(final String url) {
@@ -425,14 +422,19 @@ public class SAML2SP4UILogic extends 
AbstractTransactionalLogic<EntityTO> {
             final String spEntityID,
             final String urlContext) {
 
-        // 1. fetch the current JWT used for Syncope authentication and 
destroy it
-        JwsJwtCompactConsumer consumer = new 
JwsJwtCompactConsumer(accessToken);
-        if (!consumer.verifySignatureWith(jwsSignatureVerifier)) {
-            throw new IllegalArgumentException("Invalid signature found in 
Access Token");
+        // 1. 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;
         }
 
         // 2. look for SAML2Client
-        String idpEntityID = (String) 
consumer.getJwtClaims().getClaim(JWT_CLAIM_IDP_ENTITYID);
+        String idpEntityID = (String) 
claimsSet.getClaim(JWT_CLAIM_IDP_ENTITYID);
         if (idpEntityID == null) {
             throw new NotFoundException("No SAML 2.0 IdP information found in 
the access token");
         }
@@ -444,13 +446,13 @@ public class SAML2SP4UILogic extends 
AbstractTransactionalLogic<EntityTO> {
 
         // 3. create LogoutRequest
         SAML2Profile saml2Profile = new SAML2Profile();
-        saml2Profile.setId((String) 
consumer.getJwtClaims().getClaim(JWT_CLAIM_NAMEID_VALUE));
+        saml2Profile.setId((String) 
claimsSet.getClaim(JWT_CLAIM_NAMEID_VALUE));
         saml2Profile.addAuthenticationAttribute(
                 SAML2Authenticator.SAML_NAME_ID_FORMAT,
-                consumer.getJwtClaims().getClaim(JWT_CLAIM_NAMEID_FORMAT));
+                claimsSet.getClaim(JWT_CLAIM_NAMEID_FORMAT));
         saml2Profile.addAuthenticationAttribute(
                 SAML2Authenticator.SESSION_INDEX,
-                consumer.getJwtClaims().getClaim(JWT_CLAIM_SESSIONINDEX));
+                claimsSet.getClaim(JWT_CLAIM_SESSIONINDEX));
 
         SAML2SP4UIContext ctx = new SAML2SP4UIContext(
                 
saml2Client.getConfiguration().getSpLogoutRequestBindingType(), null);
diff --git 
a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/CustomJWTSSOProvider.java
 
b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/CustomJWTSSOProvider.java
index 379d305..8b2137a 100644
--- 
a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/CustomJWTSSOProvider.java
+++ 
b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/CustomJWTSSOProvider.java
@@ -18,15 +18,17 @@
  */
 package org.apache.syncope.fit.core.reference;
 
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jose.JWSVerifier;
+import com.nimbusds.jose.crypto.MACVerifier;
+import com.nimbusds.jose.jca.JCAContext;
+import com.nimbusds.jose.util.Base64URL;
+import com.nimbusds.jwt.JWTClaimsSet;
 import java.util.List;
 import java.util.Set;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
-import org.apache.cxf.rs.security.jose.jws.HmacJwsSignatureVerifier;
-import org.apache.cxf.rs.security.jose.jws.JwsHeaders;
-import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
-import org.apache.cxf.rs.security.jose.jws.JwsVerificationSignature;
-import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.persistence.api.dao.search.AttrCond;
@@ -45,9 +47,14 @@ public class CustomJWTSSOProvider implements JWTSSOProvider {
 
     public static final String ISSUER = "custom-issuer";
 
-    public static final String CUSTOM_KEY = "12345678910987654321";
+    public static final String CUSTOM_KEY =
+            
"XW3eTdntLa9Zsz2t4Vm6TNUya8xJEezFS7NVD3ZIZKOMdmSPMfi40rIvyBzXdbqD7TTsp6grcVW3AvRhZnFzZNaLdp6kJ2HXU9X9t2arVK"
+            + 
"42bIAp7XOw6aZg8v4OOXReZ9YkuAKtGwKC1JvPMKCz0c28AhJWd3YX5MpG6prXExQpFFVuweA6xTPxf06nYEFSOmKJ9ddJAcIx4Z8qyY"
+            + 
"mDJyNscMU8eVVM7aCR9zrCAHnjRZI2i6OnStAEVuqfGL25tK9AUKPVvyWljHNZ6ugXkstF873QaYJTBst1U2Zl9XsZnyeKrFEwwVHipp"
+            + 
"vfHwo2xu6VKySyJpZtaqVrjXFqpgFGRwEm890tCm8JhEG6GgJPqcnFHrYC180LqBZSjnNQGvA7eCSFVrABWcWnXDJCIHWbn0Wv153Vf4"
+            + 
"ZH75XEEYY53KsOS2T2GAmoqV3Izz7RL8O5dntgNLevl5gZb6MbYFURnQt0vALeObxMmv459FsXinzpAVihriOZWAudpN6Q";
 
-    private final JwsSignatureVerifier delegate;
+    private final JWSVerifier delegate;
 
     @Autowired
     private AnySearchDAO searchDAO;
@@ -55,8 +62,8 @@ public class CustomJWTSSOProvider implements JWTSSOProvider {
     @Autowired
     private AuthDataAccessor authDataAccessor;
 
-    public CustomJWTSSOProvider() {
-        delegate = new HmacJwsSignatureVerifier(CUSTOM_KEY.getBytes(), 
SignatureAlgorithm.HS512);
+    public CustomJWTSSOProvider() throws JOSEException {
+        delegate = new MACVerifier(CUSTOM_KEY);
     }
 
     @Override
@@ -65,23 +72,27 @@ public class CustomJWTSSOProvider implements JWTSSOProvider 
{
     }
 
     @Override
-    public SignatureAlgorithm getAlgorithm() {
-        return delegate.getAlgorithm();
+    public Set<JWSAlgorithm> supportedJWSAlgorithms() {
+        return delegate.supportedJWSAlgorithms();
     }
 
     @Override
-    public boolean verify(final JwsHeaders headers, final String unsignedText, 
final byte[] signature) {
-        return delegate.verify(headers, unsignedText, signature);
+    public JCAContext getJCAContext() {
+        return delegate.getJCAContext();
     }
 
     @Override
-    public JwsVerificationSignature createJwsVerificationSignature(final 
JwsHeaders headers) {
-        return delegate.createJwsVerificationSignature(headers);
+    public boolean verify(
+            final JWSHeader header,
+            final byte[] signingInput,
+            final Base64URL signature) throws JOSEException {
+
+        return delegate.verify(header, signingInput, signature);
     }
 
     @Transactional(readOnly = true)
     @Override
-    public Pair<User, Set<SyncopeGrantedAuthority>> resolve(final JwtClaims 
jwtClaims) {
+    public Pair<User, Set<SyncopeGrantedAuthority>> resolve(final JWTClaimsSet 
jwtClaims) {
         AttrCond userIdCond = new AttrCond();
         userIdCond.setSchema("userId");
         userIdCond.setType(AttrCond.Type.EQ);
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 192cc9a..7f2202e 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
@@ -25,6 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.dataformat.xml.XmlMapper;
 import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
+import com.nimbusds.jose.JWSAlgorithm;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
@@ -50,7 +51,6 @@ import javax.ws.rs.core.Response;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.cxf.jaxrs.client.WebClient;
-import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
 import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
@@ -243,7 +243,7 @@ public abstract class AbstractITCase {
 
     protected static String JWT_ISSUER;
 
-    protected static SignatureAlgorithm JWS_ALGORITHM;
+    protected static JWSAlgorithm JWS_ALGORITHM;
 
     protected static SyncopeClientFactoryBean clientFactory;
 
@@ -352,7 +352,7 @@ public abstract class AbstractITCase {
             ANONYMOUS_UNAME = props.getProperty("anonymousUser");
             ANONYMOUS_KEY = props.getProperty("anonymousKey");
             JWT_ISSUER = props.getProperty("jwtIssuer");
-            JWS_ALGORITHM = 
SignatureAlgorithm.valueOf(props.getProperty("jwsAlgorithm"));
+            JWS_ALGORITHM = 
JWSAlgorithm.parse(props.getProperty("jwsAlgorithm"));
             JWS_KEY = props.getProperty("jwsKey");
         } catch (Exception e) {
             LOG.error("Could not read security.properties", e);
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/JWTITCase.java 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/JWTITCase.java
index cd2ecee..1ebefd7 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/JWTITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/JWTITCase.java
@@ -26,7 +26,18 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 import static org.junit.jupiter.api.Assumptions.assumeFalse;
 
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jose.KeyLengthException;
+import com.nimbusds.jose.crypto.MACSigner;
+import com.nimbusds.jwt.JWT;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.PlainJWT;
+import com.nimbusds.jwt.SignedJWT;
 import java.security.AccessControlException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
@@ -35,19 +46,8 @@ import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 import javax.ws.rs.core.Response;
-import javax.xml.ws.WebServiceException;
+import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.cxf.rs.security.jose.common.JoseType;
-import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
-import org.apache.cxf.rs.security.jose.jws.HmacJwsSignatureProvider;
-import org.apache.cxf.rs.security.jose.jws.JwsHeaders;
-import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer;
-import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactProducer;
-import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider;
-import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
-import org.apache.cxf.rs.security.jose.jws.NoneJwsSignatureProvider;
-import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
-import org.apache.cxf.rs.security.jose.jwt.JwtToken;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.request.UserCR;
@@ -55,11 +55,11 @@ import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.AccessTokenService;
 import org.apache.syncope.common.rest.api.service.UserSelfService;
-import 
org.apache.syncope.core.spring.security.jws.AccessTokenJwsSignatureProvider;
-import 
org.apache.syncope.core.spring.security.jws.AccessTokenJwsSignatureVerifier;
+import org.apache.syncope.core.spring.security.jws.AccessTokenJWSSigner;
+import org.apache.syncope.core.spring.security.jws.AccessTokenJWSVerifier;
 import org.apache.syncope.fit.AbstractITCase;
 import org.apache.syncope.fit.core.reference.CustomJWTSSOProvider;
-import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
 /**
@@ -67,27 +67,18 @@ import org.junit.jupiter.api.Test;
  */
 public class JWTITCase extends AbstractITCase {
 
-    private JwsSignatureProvider jwsSignatureProvider;
+    private static AccessTokenJWSSigner JWS_SIGNER;
 
-    private JwsSignatureVerifier jwsSignatureVerifier;
+    private static AccessTokenJWSVerifier JWS_VERIFIER;
 
-    @BeforeEach
-    public void setupVerifier() throws Exception {
-        AccessTokenJwsSignatureProvider atjsp = new 
AccessTokenJwsSignatureProvider();
-        atjsp.setJwsAlgorithm(JWS_ALGORITHM);
-        atjsp.setJwsKey(JWS_KEY);
-        atjsp.afterPropertiesSet();
-        this.jwsSignatureProvider = atjsp;
-
-        AccessTokenJwsSignatureVerifier atjsv = new 
AccessTokenJwsSignatureVerifier();
-        atjsv.setJwsAlgorithm(JWS_ALGORITHM);
-        atjsv.setJwsKey(JWS_KEY);
-        atjsv.afterPropertiesSet();
-        this.jwsSignatureVerifier = atjsv;
+    @BeforeAll
+    public static void setupVerifier() throws Exception {
+        JWS_SIGNER = new AccessTokenJWSSigner(JWS_ALGORITHM, JWS_KEY);
+        JWS_VERIFIER = new AccessTokenJWSVerifier(JWS_ALGORITHM, JWS_KEY);
     }
 
     @Test
-    public void getJWTToken() throws ParseException {
+    public void getJWTToken() throws ParseException, JOSEException {
         // Get the token
         SyncopeClient localClient = clientFactory.create(ADMIN_UNAME, 
ADMIN_PWD);
         AccessTokenService accessTokenService = 
localClient.getService(AccessTokenService.class);
@@ -95,39 +86,39 @@ public class JWTITCase extends AbstractITCase {
         Response response = accessTokenService.login();
         String token = response.getHeaderString(RESTHeaders.TOKEN);
         assertNotNull(token);
-        String expiry = response.getHeaderString(RESTHeaders.TOKEN_EXPIRE);
-        assertNotNull(expiry);
+        String expiration = response.getHeaderString(RESTHeaders.TOKEN_EXPIRE);
+        assertNotNull(expiration);
 
         // Validate the signature
-        JwsJwtCompactConsumer consumer = new JwsJwtCompactConsumer(token);
-        assertTrue(consumer.verifySignatureWith(jwsSignatureVerifier));
+        SignedJWT jwt = SignedJWT.parse(token);
+        jwt.verify(JWS_VERIFIER);
+        assertTrue(jwt.verify(JWS_VERIFIER));
 
         Date now = new Date();
 
         // Verify the expiry header matches that of the token
-        Long expiryTime = consumer.getJwtClaims().getExpiryTime();
-        assertNotNull(expiryTime);
+        Date tokenDate = jwt.getJWTClaimsSet().getExpirationTime();
+        assertNotNull(tokenDate);
 
         SimpleDateFormat dateFormat = new 
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
-        Date tokenDate = dateFormat.parse(dateFormat.format(new 
Date(expiryTime * 1000L)));
-        Date parsedDate = dateFormat.parse(expiry);
+        Date parsedDate = dateFormat.parse(expiration);
 
         assertEquals(tokenDate, parsedDate);
         assertTrue(parsedDate.after(now));
 
         // Verify issuedAt
-        Long issuedAt = consumer.getJwtClaims().getIssuedAt();
-        assertNotNull(issuedAt);
-        assertTrue(new Date(issuedAt).before(now));
+        Date issueTime = jwt.getJWTClaimsSet().getIssueTime();
+        assertNotNull(issueTime);
+        assertTrue(issueTime.before(now));
 
         // Validate subject + issuer
-        assertEquals(ADMIN_UNAME, consumer.getJwtClaims().getSubject());
-        assertEquals(JWT_ISSUER, consumer.getJwtClaims().getIssuer());
+        assertEquals(ADMIN_UNAME, jwt.getJWTClaimsSet().getSubject());
+        assertEquals(JWT_ISSUER, jwt.getJWTClaimsSet().getIssuer());
 
         // Verify NotBefore
-        Long notBefore = consumer.getJwtClaims().getNotBefore();
-        assertNotNull(notBefore);
-        assertTrue(new Date(notBefore).before(now));
+        Date notBeforeTime = jwt.getJWTClaimsSet().getNotBeforeTime();
+        assertNotNull(notBeforeTime);
+        assertTrue(notBeforeTime.before(now));
     }
 
     @Test
@@ -151,13 +142,13 @@ public class JWTITCase extends AbstractITCase {
         try {
             jwtUserSelfService.read();
             fail("Failure expected on a modified token");
-        } catch (WebServiceException ex) {
-            // expected
+        } catch (AccessControlException e) {
+            assertEquals("Invalid signature found in JWT", e.getMessage());
         }
     }
 
     @Test
-    public void tokenValidation() throws ParseException {
+    public void tokenValidation() throws ParseException, JOSEException {
         // Get an initial token
         SyncopeClient localClient = clientFactory.create(ADMIN_UNAME, 
ADMIN_PWD);
         AccessTokenService accessTokenService = 
localClient.getService(AccessTokenService.class);
@@ -165,30 +156,26 @@ public class JWTITCase extends AbstractITCase {
         Response response = accessTokenService.login();
         String token = response.getHeaderString(RESTHeaders.TOKEN);
         assertNotNull(token);
-        JwsJwtCompactConsumer consumer = new JwsJwtCompactConsumer(token);
-        String tokenId = consumer.getJwtClaims().getTokenId();
+        SignedJWT jwt = SignedJWT.parse(token);
+        String tokenId = jwt.getJWTClaimsSet().getJWTID();
 
         // Create a new token using the Id of the first token
-        Date now = new Date();
-        long currentTime = now.getTime() / 1000L;
-
-        Calendar expiry = Calendar.getInstance();
-        expiry.setTime(now);
-        expiry.add(Calendar.MINUTE, 5);
-
-        JwtClaims jwtClaims = new JwtClaims();
-        jwtClaims.setTokenId(tokenId);
-        jwtClaims.setSubject(ADMIN_UNAME);
-        jwtClaims.setIssuedAt(currentTime);
-        jwtClaims.setIssuer(JWT_ISSUER);
-        jwtClaims.setExpiryTime(expiry.getTime().getTime() / 1000L);
-        jwtClaims.setNotBefore(currentTime);
-
-        JwsHeaders jwsHeaders = new JwsHeaders(JoseType.JWT, JWS_ALGORITHM);
-        JwtToken jwtToken = new JwtToken(jwsHeaders, jwtClaims);
-        JwsJwtCompactProducer producer = new JwsJwtCompactProducer(jwtToken);
-
-        String signed = producer.signWith(jwsSignatureProvider);
+        Date currentTime = new Date();
+
+        Calendar expiration = Calendar.getInstance();
+        expiration.setTime(currentTime);
+        expiration.add(Calendar.MINUTE, 5);
+
+        JWTClaimsSet.Builder claimsSet = new JWTClaimsSet.Builder().
+                jwtID(tokenId).
+                subject(ADMIN_UNAME).
+                issueTime(currentTime).
+                issuer(JWT_ISSUER).
+                expirationTime(expiration.getTime()).
+                notBeforeTime(currentTime);
+        jwt = new SignedJWT(new JWSHeader(JWS_SIGNER.getJwsAlgorithm()), 
claimsSet.build());
+        jwt.sign(JWS_SIGNER);
+        String signed = jwt.serialize();
 
         SyncopeClient jwtClient = clientFactory.create(signed);
         UserSelfService jwtUserSelfService = 
jwtClient.getService(UserSelfService.class);
@@ -196,51 +183,46 @@ public class JWTITCase extends AbstractITCase {
     }
 
     @Test
-    public void invalidIssuer() throws ParseException {
+    public void invalidIssuer() throws ParseException, JOSEException {
         // Get an initial token
         SyncopeClient localClient = clientFactory.create(ADMIN_UNAME, 
ADMIN_PWD);
         AccessTokenService accessTokenService = 
localClient.getService(AccessTokenService.class);
 
         Response response = accessTokenService.login();
         String token = response.getHeaderString(RESTHeaders.TOKEN);
-        assertNotNull(token);
-        JwsJwtCompactConsumer consumer = new JwsJwtCompactConsumer(token);
-        String tokenId = consumer.getJwtClaims().getTokenId();
+        SignedJWT jwt = SignedJWT.parse(token);
+        String tokenId = jwt.getJWTClaimsSet().getJWTID();
 
         // Create a new token using the Id of the first token
-        Date now = new Date();
-        long currentTime = now.getTime() / 1000L;
-
-        Calendar expiry = Calendar.getInstance();
-        expiry.setTime(now);
-        expiry.add(Calendar.MINUTE, 5);
-
-        JwtClaims jwtClaims = new JwtClaims();
-        jwtClaims.setTokenId(tokenId);
-        jwtClaims.setSubject(ADMIN_UNAME);
-        jwtClaims.setIssuedAt(currentTime);
-        jwtClaims.setIssuer("UnknownIssuer");
-        jwtClaims.setExpiryTime(expiry.getTime().getTime() / 1000L);
-        jwtClaims.setNotBefore(currentTime);
-
-        JwsHeaders jwsHeaders = new JwsHeaders(JoseType.JWT, JWS_ALGORITHM);
-        JwtToken jwtToken = new JwtToken(jwsHeaders, jwtClaims);
-        JwsJwtCompactProducer producer = new JwsJwtCompactProducer(jwtToken);
-
-        String signed = producer.signWith(jwsSignatureProvider);
+        Date currentTime = new Date();
+
+        Calendar expiration = Calendar.getInstance();
+        expiration.setTime(currentTime);
+        expiration.add(Calendar.MINUTE, 5);
+
+        JWTClaimsSet.Builder claimsSet = new JWTClaimsSet.Builder().
+                jwtID(tokenId).
+                subject(ADMIN_UNAME).
+                issueTime(currentTime).
+                issuer("UnknownIssuer").
+                expirationTime(expiration.getTime()).
+                notBeforeTime(currentTime);
+        jwt = new SignedJWT(new JWSHeader(JWS_SIGNER.getJwsAlgorithm()), 
claimsSet.build());
+        jwt.sign(JWS_SIGNER);
+        String signed = jwt.serialize();
 
         SyncopeClient jwtClient = clientFactory.create(signed);
         UserSelfService jwtUserSelfService = 
jwtClient.getService(UserSelfService.class);
         try {
             jwtUserSelfService.read();
             fail("Failure expected on an invalid issuer");
-        } catch (AccessControlException ex) {
+        } catch (AccessControlException e) {
             // expected
         }
     }
 
     @Test
-    public void expiredToken() throws ParseException {
+    public void expiredToken() throws ParseException, JOSEException {
         // Get an initial token
         SyncopeClient localClient = clientFactory.create(ADMIN_UNAME, 
ADMIN_PWD);
         AccessTokenService accessTokenService = 
localClient.getService(AccessTokenService.class);
@@ -248,43 +230,35 @@ public class JWTITCase extends AbstractITCase {
         Response response = accessTokenService.login();
         String token = response.getHeaderString(RESTHeaders.TOKEN);
         assertNotNull(token);
-        JwsJwtCompactConsumer consumer = new JwsJwtCompactConsumer(token);
-        String tokenId = consumer.getJwtClaims().getTokenId();
+        SignedJWT jwt = SignedJWT.parse(token);
+        String tokenId = jwt.getJWTClaimsSet().getJWTID();
 
         // Create a new token using the Id of the first token
-        Date now = new Date();
-        long currentTime = now.getTime() / 1000L;
-
-        Calendar expiry = Calendar.getInstance();
-        expiry.setTime(now);
-        expiry.add(Calendar.MINUTE, 5);
-
-        JwtClaims jwtClaims = new JwtClaims();
-        jwtClaims.setTokenId(tokenId);
-        jwtClaims.setSubject(ADMIN_UNAME);
-        jwtClaims.setIssuedAt(currentTime);
-        jwtClaims.setIssuer(JWT_ISSUER);
-        jwtClaims.setExpiryTime((now.getTime() - 5000L) / 1000L);
-        jwtClaims.setNotBefore(currentTime);
-
-        JwsHeaders jwsHeaders = new JwsHeaders(JoseType.JWT, JWS_ALGORITHM);
-        JwtToken jwtToken = new JwtToken(jwsHeaders, jwtClaims);
-        JwsJwtCompactProducer producer = new JwsJwtCompactProducer(jwtToken);
-
-        String signed = producer.signWith(jwsSignatureProvider);
+        Date currentTime = new Date();
+
+        JWTClaimsSet.Builder claimsSet = new JWTClaimsSet.Builder().
+                jwtID(tokenId).
+                subject(ADMIN_UNAME).
+                issueTime(currentTime).
+                issuer(JWT_ISSUER).
+                expirationTime(new Date(currentTime.getTime() - 5000L)).
+                notBeforeTime(currentTime);
+        jwt = new SignedJWT(new JWSHeader(JWS_SIGNER.getJwsAlgorithm()), 
claimsSet.build());
+        jwt.sign(JWS_SIGNER);
+        String signed = jwt.serialize();
 
         SyncopeClient jwtClient = clientFactory.create(signed);
         UserSelfService jwtUserSelfService = 
jwtClient.getService(UserSelfService.class);
         try {
             jwtUserSelfService.read();
             fail("Failure expected on an expired token");
-        } catch (AccessControlException ex) {
+        } catch (AccessControlException e) {
             // expected
         }
     }
 
     @Test
-    public void notBefore() throws ParseException {
+    public void notBefore() throws ParseException, JOSEException {
         // Get an initial token
         SyncopeClient localClient = clientFactory.create(ADMIN_UNAME, 
ADMIN_PWD);
         AccessTokenService accessTokenService = 
localClient.getService(AccessTokenService.class);
@@ -292,43 +266,39 @@ public class JWTITCase extends AbstractITCase {
         Response response = accessTokenService.login();
         String token = response.getHeaderString(RESTHeaders.TOKEN);
         assertNotNull(token);
-        JwsJwtCompactConsumer consumer = new JwsJwtCompactConsumer(token);
-        String tokenId = consumer.getJwtClaims().getTokenId();
+        SignedJWT jwt = SignedJWT.parse(token);
+        String tokenId = jwt.getJWTClaimsSet().getJWTID();
 
         // Create a new token using the Id of the first token
-        Date now = new Date();
-        long currentTime = now.getTime() / 1000L;
-
-        Calendar expiry = Calendar.getInstance();
-        expiry.setTime(now);
-        expiry.add(Calendar.MINUTE, 5);
-
-        JwtClaims jwtClaims = new JwtClaims();
-        jwtClaims.setTokenId(tokenId);
-        jwtClaims.setSubject(ADMIN_UNAME);
-        jwtClaims.setIssuedAt(currentTime);
-        jwtClaims.setIssuer(JWT_ISSUER);
-        jwtClaims.setExpiryTime(expiry.getTime().getTime() / 1000L);
-        jwtClaims.setNotBefore(currentTime + 60L);
-
-        JwsHeaders jwsHeaders = new JwsHeaders(JoseType.JWT, JWS_ALGORITHM);
-        JwtToken jwtToken = new JwtToken(jwsHeaders, jwtClaims);
-        JwsJwtCompactProducer producer = new JwsJwtCompactProducer(jwtToken);
-
-        String signed = producer.signWith(jwsSignatureProvider);
+        Date currentTime = new Date();
+
+        Calendar expiration = Calendar.getInstance();
+        expiration.setTime(currentTime);
+        expiration.add(Calendar.MINUTE, 5);
+
+        JWTClaimsSet.Builder claimsSet = new JWTClaimsSet.Builder().
+                jwtID(tokenId).
+                subject(ADMIN_UNAME).
+                issueTime(currentTime).
+                issuer(JWT_ISSUER).
+                expirationTime(expiration.getTime()).
+                notBeforeTime(new Date(currentTime.getTime() + 60000L));
+        jwt = new SignedJWT(new JWSHeader(JWS_SIGNER.getJwsAlgorithm()), 
claimsSet.build());
+        jwt.sign(JWS_SIGNER);
+        String signed = jwt.serialize();
 
         SyncopeClient jwtClient = clientFactory.create(signed);
         UserSelfService jwtUserSelfService = 
jwtClient.getService(UserSelfService.class);
         try {
             jwtUserSelfService.read();
             fail("Failure expected on a token that is not valid yet");
-        } catch (AccessControlException ex) {
+        } catch (AccessControlException e) {
             // expected
         }
     }
 
     @Test
-    public void noneSignature() throws ParseException {
+    public void noSignature() throws ParseException {
         // Get an initial token
         SyncopeClient localClient = clientFactory.create(ADMIN_UNAME, 
ADMIN_PWD);
         AccessTokenService accessTokenService = 
localClient.getService(AccessTokenService.class);
@@ -336,37 +306,25 @@ public class JWTITCase extends AbstractITCase {
         Response response = accessTokenService.login();
         String token = response.getHeaderString(RESTHeaders.TOKEN);
         assertNotNull(token);
-        JwsJwtCompactConsumer consumer = new JwsJwtCompactConsumer(token);
-        String tokenId = consumer.getJwtClaims().getTokenId();
+        JWT jwt = SignedJWT.parse(token);
 
         // Create a new token using the Id of the first token
-        JwtClaims jwtClaims = new JwtClaims();
-        jwtClaims.setTokenId(tokenId);
-        jwtClaims.setSubject(consumer.getJwtClaims().getSubject());
-        jwtClaims.setIssuedAt(consumer.getJwtClaims().getIssuedAt());
-        jwtClaims.setIssuer(consumer.getJwtClaims().getIssuer());
-        jwtClaims.setExpiryTime(consumer.getJwtClaims().getExpiryTime());
-        jwtClaims.setNotBefore(consumer.getJwtClaims().getNotBefore());
-
-        JwsHeaders jwsHeaders = new JwsHeaders(JoseType.JWT, 
SignatureAlgorithm.NONE);
-        JwtToken jwtToken = new JwtToken(jwsHeaders, jwtClaims);
-        JwsJwtCompactProducer producer = new JwsJwtCompactProducer(jwtToken);
+        JWTClaimsSet.Builder claimsSet = new 
JWTClaimsSet.Builder(jwt.getJWTClaimsSet());
+        jwt = new PlainJWT(claimsSet.build());
+        String bearer = jwt.serialize();
 
-        JwsSignatureProvider noneJwsSignatureProvider = new 
NoneJwsSignatureProvider();
-        String signed = producer.signWith(noneJwsSignatureProvider);
-
-        SyncopeClient jwtClient = clientFactory.create(signed);
+        SyncopeClient jwtClient = clientFactory.create(bearer);
         UserSelfService jwtUserSelfService = 
jwtClient.getService(UserSelfService.class);
         try {
             jwtUserSelfService.read();
             fail("Failure expected on no signature");
-        } catch (AccessControlException ex) {
+        } catch (AccessControlException e) {
             // expected
         }
     }
 
     @Test
-    public void unknownId() throws ParseException {
+    public void unknownId() throws ParseException, JOSEException {
         // Get an initial token
         SyncopeClient localClient = clientFactory.create(ADMIN_UNAME, 
ADMIN_PWD);
         AccessTokenService accessTokenService = 
localClient.getService(AccessTokenService.class);
@@ -374,66 +332,46 @@ public class JWTITCase extends AbstractITCase {
         Response response = accessTokenService.login();
         String token = response.getHeaderString(RESTHeaders.TOKEN);
         assertNotNull(token);
+        SignedJWT jwt = SignedJWT.parse(token);
 
         // Create a new token using an unknown Id
-        Date now = new Date();
-        long currentTime = now.getTime() / 1000L;
-
-        Calendar expiry = Calendar.getInstance();
-        expiry.setTime(now);
-        expiry.add(Calendar.MINUTE, 5);
-
-        JwtClaims jwtClaims = new JwtClaims();
-        jwtClaims.setTokenId(UUID.randomUUID().toString());
-        jwtClaims.setSubject(ADMIN_UNAME);
-        jwtClaims.setIssuedAt(currentTime);
-        jwtClaims.setIssuer(JWT_ISSUER);
-        jwtClaims.setExpiryTime(expiry.getTime().getTime() / 1000L);
-        jwtClaims.setNotBefore(currentTime);
-
-        JwsHeaders jwsHeaders = new JwsHeaders(JoseType.JWT, JWS_ALGORITHM);
-        JwtToken jwtToken = new JwtToken(jwsHeaders, jwtClaims);
-        JwsJwtCompactProducer producer = new JwsJwtCompactProducer(jwtToken);
-
-        String signed = producer.signWith(jwsSignatureProvider);
+        JWTClaimsSet.Builder claimsSet = new 
JWTClaimsSet.Builder(jwt.getJWTClaimsSet()).
+                jwtID(UUID.randomUUID().toString());
+        jwt = new SignedJWT(new JWSHeader(JWS_SIGNER.getJwsAlgorithm()), 
claimsSet.build());
+        jwt.sign(JWS_SIGNER);
+        String signed = jwt.serialize();
 
         SyncopeClient jwtClient = clientFactory.create(signed);
         UserSelfService jwtUserSelfService = 
jwtClient.getService(UserSelfService.class);
         try {
             jwtUserSelfService.read();
             fail("Failure expected on an unknown id");
-        } catch (AccessControlException ex) {
+        } catch (AccessControlException e) {
             // expected
         }
     }
 
     @Test
-    public void thirdPartyToken() throws ParseException {
-        assumeFalse(SignatureAlgorithm.isPublicKeyAlgorithm(JWS_ALGORITHM));
+    public void thirdPartyToken() throws ParseException, JOSEException {
+        assumeFalse(JWSAlgorithm.Family.RSA.contains(JWS_ALGORITHM));
 
         // Create a new token
-        Date now = new Date();
-        long currentTime = now.getTime() / 1000L;
-
-        Calendar expiry = Calendar.getInstance();
-        expiry.setTime(now);
-        expiry.add(Calendar.MINUTE, 5);
-
-        JwtClaims jwtClaims = new JwtClaims();
-        jwtClaims.setTokenId(UUID.randomUUID().toString());
-        jwtClaims.setSubject("[email protected]");
-        jwtClaims.setIssuedAt(currentTime);
-        jwtClaims.setIssuer(CustomJWTSSOProvider.ISSUER);
-        jwtClaims.setExpiryTime(expiry.getTime().getTime() / 1000L);
-        jwtClaims.setNotBefore(currentTime);
-
-        JwsHeaders jwsHeaders = new JwsHeaders(JoseType.JWT, JWS_ALGORITHM);
-        JwtToken jwtToken = new JwtToken(jwsHeaders, jwtClaims);
-        JwsJwtCompactProducer producer = new JwsJwtCompactProducer(jwtToken);
-
-        JwsSignatureProvider customSignatureProvider =
-                new 
HmacJwsSignatureProvider(CustomJWTSSOProvider.CUSTOM_KEY.getBytes(), 
JWS_ALGORITHM);
-        String signed = producer.signWith(customSignatureProvider);
+        Date currentTime = new Date();
+
+        Calendar expiration = Calendar.getInstance();
+        expiration.setTime(currentTime);
+        expiration.add(Calendar.MINUTE, 5);
+
+        JWTClaimsSet.Builder claimsSet = new JWTClaimsSet.Builder().
+                jwtID(UUID.randomUUID().toString()).
+                subject("[email protected]").
+                issueTime(currentTime).
+                issuer(CustomJWTSSOProvider.ISSUER).
+                expirationTime(expiration.getTime()).
+                notBeforeTime(currentTime);
+        SignedJWT jwt = new SignedJWT(new JWSHeader(JWS_ALGORITHM), 
claimsSet.build());
+        jwt.sign(new MACSigner(CustomJWTSSOProvider.CUSTOM_KEY));
+        String signed = jwt.serialize();
 
         SyncopeClient jwtClient = clientFactory.create(signed);
 
@@ -443,120 +381,110 @@ public class JWTITCase extends AbstractITCase {
     }
 
     @Test
-    public void thirdPartyTokenUnknownUser() throws ParseException {
-        assumeFalse(SignatureAlgorithm.isPublicKeyAlgorithm(JWS_ALGORITHM));
+    public void thirdPartyTokenUnknownUser() throws ParseException, 
JOSEException {
+        assumeFalse(JWSAlgorithm.Family.RSA.contains(JWS_ALGORITHM));
 
         // Create a new token
-        Date now = new Date();
-        long currentTime = now.getTime() / 1000L;
-
-        Calendar expiry = Calendar.getInstance();
-        expiry.setTime(now);
-        expiry.add(Calendar.MINUTE, 5);
-
-        JwtClaims jwtClaims = new JwtClaims();
-        jwtClaims.setTokenId(UUID.randomUUID().toString());
-        jwtClaims.setSubject("[email protected]");
-        jwtClaims.setIssuedAt(currentTime);
-        jwtClaims.setIssuer(CustomJWTSSOProvider.ISSUER);
-        jwtClaims.setExpiryTime(expiry.getTime().getTime() / 1000L);
-        jwtClaims.setNotBefore(currentTime);
-
-        JwsHeaders jwsHeaders = new JwsHeaders(JoseType.JWT, JWS_ALGORITHM);
-        JwtToken jwtToken = new JwtToken(jwsHeaders, jwtClaims);
-        JwsJwtCompactProducer producer = new JwsJwtCompactProducer(jwtToken);
-
-        JwsSignatureProvider customSignatureProvider =
-                new 
HmacJwsSignatureProvider(CustomJWTSSOProvider.CUSTOM_KEY.getBytes(), 
JWS_ALGORITHM);
-        String signed = producer.signWith(customSignatureProvider);
+        Date currentTime = new Date();
+
+        Calendar expiration = Calendar.getInstance();
+        expiration.setTime(currentTime);
+        expiration.add(Calendar.MINUTE, 5);
+
+        JWTClaimsSet.Builder claimsSet = new JWTClaimsSet.Builder().
+                jwtID(UUID.randomUUID().toString()).
+                subject("[email protected]").
+                issueTime(currentTime).
+                issuer(CustomJWTSSOProvider.ISSUER).
+                expirationTime(expiration.getTime()).
+                notBeforeTime(currentTime);
+        SignedJWT jwt = new SignedJWT(new 
JWSHeader(JWS_SIGNER.getJwsAlgorithm()), claimsSet.build());
+        jwt.sign(JWS_SIGNER);
+        String signed = jwt.serialize();
 
         SyncopeClient jwtClient = clientFactory.create(signed);
 
         try {
             jwtClient.self();
             fail("Failure expected on an unknown subject");
-        } catch (AccessControlException ex) {
+        } catch (AccessControlException e) {
             // expected
         }
     }
 
     @Test
-    public void thirdPartyTokenUnknownIssuer() throws ParseException {
-        assumeFalse(SignatureAlgorithm.isPublicKeyAlgorithm(JWS_ALGORITHM));
+    public void thirdPartyTokenUnknownIssuer() throws ParseException, 
JOSEException {
+        assumeFalse(JWSAlgorithm.Family.RSA.contains(JWS_ALGORITHM));
 
         // Create a new token
-        Date now = new Date();
-        long currentTime = now.getTime() / 1000L;
-
-        Calendar expiry = Calendar.getInstance();
-        expiry.setTime(now);
-        expiry.add(Calendar.MINUTE, 5);
-
-        JwtClaims jwtClaims = new JwtClaims();
-        jwtClaims.setTokenId(UUID.randomUUID().toString());
-        jwtClaims.setSubject("[email protected]");
-        jwtClaims.setIssuedAt(currentTime);
-        jwtClaims.setIssuer(CustomJWTSSOProvider.ISSUER + '_');
-        jwtClaims.setExpiryTime(expiry.getTime().getTime() / 1000L);
-        jwtClaims.setNotBefore(currentTime);
-
-        JwsHeaders jwsHeaders = new JwsHeaders(JoseType.JWT, JWS_ALGORITHM);
-        JwtToken jwtToken = new JwtToken(jwsHeaders, jwtClaims);
-        JwsJwtCompactProducer producer = new JwsJwtCompactProducer(jwtToken);
-
-        JwsSignatureProvider customSignatureProvider =
-                new 
HmacJwsSignatureProvider(CustomJWTSSOProvider.CUSTOM_KEY.getBytes(), 
JWS_ALGORITHM);
-        String signed = producer.signWith(customSignatureProvider);
+        Date currentTime = new Date();
+
+        Calendar expiration = Calendar.getInstance();
+        expiration.setTime(currentTime);
+        expiration.add(Calendar.MINUTE, 5);
+
+        JWTClaimsSet.Builder claimsSet = new JWTClaimsSet.Builder().
+                jwtID(UUID.randomUUID().toString()).
+                subject("[email protected]").
+                issueTime(currentTime).
+                issuer(CustomJWTSSOProvider.ISSUER + "_").
+                expirationTime(expiration.getTime()).
+                notBeforeTime(currentTime);
+        SignedJWT jwt = new SignedJWT(new 
JWSHeader(JWS_SIGNER.getJwsAlgorithm()), claimsSet.build());
+        jwt.sign(JWS_SIGNER);
+        String signed = jwt.serialize();
 
         SyncopeClient jwtClient = clientFactory.create(signed);
 
         try {
             jwtClient.self();
             fail("Failure expected on an unknown issuer");
-        } catch (AccessControlException ex) {
+        } catch (AccessControlException e) {
             // expected
         }
     }
 
     @Test
-    public void thirdPartyTokenBadSignature() throws ParseException {
-        assumeFalse(SignatureAlgorithm.isPublicKeyAlgorithm(JWS_ALGORITHM));
+    public void thirdPartyTokenBadSignature()
+            throws ParseException, KeyLengthException, 
NoSuchAlgorithmException,
+            InvalidKeySpecException, JOSEException {
+
+        assumeFalse(JWSAlgorithm.Family.RSA.contains(JWS_ALGORITHM));
 
         // Create a new token
-        Date now = new Date();
+        Date currentTime = new Date();
 
-        Calendar expiry = Calendar.getInstance();
-        expiry.setTime(now);
-        expiry.add(Calendar.MINUTE, 5);
+        Calendar expiration = Calendar.getInstance();
+        expiration.setTime(currentTime);
+        expiration.add(Calendar.MINUTE, 5);
 
-        JwtClaims jwtClaims = new JwtClaims();
-        jwtClaims.setTokenId(UUID.randomUUID().toString());
-        jwtClaims.setSubject("[email protected]");
-        jwtClaims.setIssuedAt(now.getTime());
-        jwtClaims.setIssuer(CustomJWTSSOProvider.ISSUER);
-        jwtClaims.setExpiryTime(expiry.getTime().getTime());
-        jwtClaims.setNotBefore(now.getTime());
+        JWTClaimsSet.Builder claimsSet = new JWTClaimsSet.Builder().
+                jwtID(UUID.randomUUID().toString()).
+                subject("[email protected]").
+                issueTime(currentTime).
+                issuer(CustomJWTSSOProvider.ISSUER).
+                expirationTime(expiration.getTime()).
+                notBeforeTime(currentTime);
 
-        JwsHeaders jwsHeaders = new JwsHeaders(JoseType.JWT, JWS_ALGORITHM);
-        JwtToken jwtToken = new JwtToken(jwsHeaders, jwtClaims);
-        JwsJwtCompactProducer producer = new JwsJwtCompactProducer(jwtToken);
+        AccessTokenJWSSigner customJWSSigner =
+                new AccessTokenJWSSigner(JWS_ALGORITHM, 
RandomStringUtils.randomAlphanumeric(512));
 
-        JwsSignatureProvider customSignatureProvider =
-                new HmacJwsSignatureProvider((CustomJWTSSOProvider.CUSTOM_KEY 
+ '_').getBytes(), JWS_ALGORITHM);
-        String signed = producer.signWith(customSignatureProvider);
+        SignedJWT jwt = new SignedJWT(new 
JWSHeader(customJWSSigner.getJwsAlgorithm()), claimsSet.build());
+        jwt.sign(customJWSSigner);
+        String signed = jwt.serialize();
 
         SyncopeClient jwtClient = clientFactory.create(signed);
 
         try {
             jwtClient.self();
             fail("Failure expected on a bad signature");
-        } catch (AccessControlException ex) {
+        } catch (AccessControlException e) {
             // expected
         }
     }
 
     @Test
-    public void issueSYNCOPE1420() {
+    public void issueSYNCOPE1420() throws ParseException {
         Long orig = confParamOps.get(SyncopeConstants.MASTER_DOMAIN, 
"jwt.lifetime.minutes", null, Long.class);
         try {
             // set for immediate JWT expiration
@@ -569,10 +497,8 @@ public class JWTITCase extends AbstractITCase {
             // login, get JWT with  expiryTime
             String jwt = clientFactory.create(user.getUsername(), 
"password123").getJWT();
 
-            JwsJwtCompactConsumer consumer = new JwsJwtCompactConsumer(jwt);
-            assertTrue(consumer.verifySignatureWith(jwsSignatureVerifier));
-            Long expiryTime = consumer.getJwtClaims().getExpiryTime();
-            assertNotNull(expiryTime);
+            Date expirationTime = 
SignedJWT.parse(jwt).getJWTClaimsSet().getExpirationTime();
+            assertNotNull(expirationTime);
 
             // wait for 1 sec, check that JWT is effectively expired
             try {
@@ -580,7 +506,7 @@ public class JWTITCase extends AbstractITCase {
             } catch (InterruptedException e) {
                 // ignore
             }
-            assertTrue(expiryTime < System.currentTimeMillis());
+            assertTrue(expirationTime.before(new Date()));
 
             // login again, get new JWT
             // (even if ExpiredAccessTokenCleanup did not run yet, as it is 
scheduled every 5 minutes)
diff --git a/pom.xml b/pom.xml
index b325718..4b1a960 100644
--- a/pom.xml
+++ b/pom.xml
@@ -618,11 +618,6 @@ under the License.
       </dependency>
       <dependency>
         <groupId>org.apache.cxf</groupId>
-        <artifactId>cxf-rt-rs-security-jose</artifactId>
-        <version>${cxf.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.cxf</groupId>
         <artifactId>cxf-rt-rs-service-description</artifactId>
         <version>${cxf.version}</version>
       </dependency>

Reply via email to