Upgrading Spring Boot to 2.7 and CAS to 6.6 (#362)

diff --git a/archetype/src/main/resources/archetype-resources/wa/pom.xml b/archetype/src/main/resources/archetype-resources/wa/pom.xml
index 7a634d2..30bfb10 100644
--- a/archetype/src/main/resources/archetype-resources/wa/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/wa/pom.xml
@@ -32,6 +32,18 @@
   <artifactId>${artifactId}</artifactId>
   <packaging>war</packaging>
 
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.apereo.cas</groupId>
+        <artifactId>cas-server-support-bom</artifactId>
+        <version>${cas.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
   <dependencies>
     <dependency>
       <groupId>${groupId}</groupId>
diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/rest/OIDCJWKSRestClient.java b/client/am/console/src/main/java/org/apache/syncope/client/console/rest/OIDCJWKSRestClient.java
index 340634c..57c4e68 100644
--- a/client/am/console/src/main/java/org/apache/syncope/client/console/rest/OIDCJWKSRestClient.java
+++ b/client/am/console/src/main/java/org/apache/syncope/client/console/rest/OIDCJWKSRestClient.java
@@ -21,7 +21,6 @@
 import java.util.concurrent.atomic.AtomicReference;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.common.lib.to.OIDCJWKSTO;
-import org.apache.syncope.common.lib.types.JWSAlgorithm;
 import org.apache.syncope.common.rest.api.service.OIDCJWKSService;
 
 public class OIDCJWKSRestClient extends BaseRestClient {
@@ -39,7 +38,7 @@
     }
 
     public static OIDCJWKSTO generate() {
-        Response response = getService(OIDCJWKSService.class).generate(2048, JWSAlgorithm.RS256);
+        Response response = getService(OIDCJWKSService.class).generate("syncope", "RSA", 2048);
         return response.readEntity(OIDCJWKSTO.class);
     }
 
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SecurityConfig.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SecurityConfig.java
index 86a5e39..f33629d 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SecurityConfig.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SecurityConfig.java
@@ -22,35 +22,34 @@
 import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.SecurityFilterChain;
 
 @EnableWebSecurity
 @Configuration(proxyBeanMethods = false)
 public class SecurityConfig {
 
     @Bean
-    public WebSecurityConfigurerAdapter consoleSecurityConfigAdapter(final ConsoleProperties props) {
-        return new WebSecurityConfigurerAdapter() {
-            @Override
-            protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
-                auth.inMemoryAuthentication().
-                    withUser(props.getAnonymousUser()).
-                    password("{noop}" + props.getAnonymousKey()).
-                    roles(IdRepoEntitlement.ANONYMOUS);
-            }
+    public SecurityFilterChain filterChain(final HttpSecurity http) throws Exception {
+        http.csrf().disable().
+                authorizeRequests().
+                requestMatchers(EndpointRequest.toAnyEndpoint()).
+                authenticated().
+                and().
+                httpBasic();
+        return http.build();
+    }
 
-            @Override
-            protected void configure(final HttpSecurity http) throws Exception {
-                http.csrf().disable().
-                    authorizeRequests().
-                    requestMatchers(EndpointRequest.toAnyEndpoint()).
-                    authenticated().
-                    and().
-                    httpBasic();
-            }
-        };
+    @Bean
+    public InMemoryUserDetailsManager userDetailsService(final ConsoleProperties props) {
+        UserDetails user = User.withUsername(props.getAnonymousUser()).
+                password("{noop}" + props.getAnonymousKey()).
+                roles(IdRepoEntitlement.ANONYMOUS).
+                build();
+        return new InMemoryUserDetailsManager(user);
     }
 }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SecurityConfig.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SecurityConfig.java
index 38e6e6a..3218618 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SecurityConfig.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SecurityConfig.java
@@ -22,35 +22,34 @@
 import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.SecurityFilterChain;
 
 @EnableWebSecurity
 @Configuration(proxyBeanMethods = false)
 public class SecurityConfig {
 
     @Bean
-    public WebSecurityConfigurerAdapter enduserSecurityAdapter(final EnduserProperties props) {
-        return new WebSecurityConfigurerAdapter() {
-            @Override
-            protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
-                auth.inMemoryAuthentication().
-                    withUser(props.getAnonymousUser()).
-                    password("{noop}" + props.getAnonymousKey()).
-                    roles(IdRepoEntitlement.ANONYMOUS);
-            }
+    public SecurityFilterChain filterChain(final HttpSecurity http) throws Exception {
+        http.csrf().disable().
+                authorizeRequests().
+                requestMatchers(EndpointRequest.toAnyEndpoint()).
+                authenticated().
+                and().
+                httpBasic();
+        return http.build();
+    }
 
-            @Override
-            protected void configure(final HttpSecurity http) throws Exception {
-                http.csrf().disable().
-                    authorizeRequests().
-                    requestMatchers(EndpointRequest.toAnyEndpoint()).
-                    authenticated().
-                    and().
-                    httpBasic();
-            }
-        };
+    @Bean
+    public InMemoryUserDetailsManager userDetailsService(final EnduserProperties props) {
+        UserDetails user = User.withUsername(props.getAnonymousUser()).
+                password("{noop}" + props.getAnonymousKey()).
+                roles(IdRepoEntitlement.ANONYMOUS).
+                build();
+        return new InMemoryUserDetailsManager(user);
     }
 }
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_fr_CA.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_fr_CA.properties
index bcdb339..3d4c66f 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_fr_CA.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfResult_fr_CA.properties
@@ -14,4 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-login=Back to Home
+login=Retour \u00e0 la page d'accueil
diff --git a/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCJWKSService.java b/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCJWKSService.java
index 53eb241..97f83f8 100644
--- a/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCJWKSService.java
+++ b/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCJWKSService.java
@@ -38,7 +38,6 @@
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.common.lib.to.OIDCJWKSTO;
-import org.apache.syncope.common.lib.types.JWSAlgorithm;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 
 @Tag(name = "OpenID Connect 1.0")
@@ -53,7 +52,7 @@
     OIDCJWKSTO get();
 
     @ApiResponses(
-        @ApiResponse(responseCode = "204", description = "Operation was successful"))
+            @ApiResponse(responseCode = "204", description = "Operation was successful"))
     @POST
     @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
@@ -72,8 +71,9 @@
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
     @Path("new")
     Response generate(
-            @NotNull @QueryParam("size") @DefaultValue("2048") int size,
-            @NotNull @QueryParam("algorithm") @DefaultValue("RS256") JWSAlgorithm algorithm);
+            @NotNull @QueryParam("jwksKeyId") @DefaultValue("syncope") String jwksKeyId,
+            @NotNull @QueryParam("jwksType") @DefaultValue("RSA") String jwksType,
+            @NotNull @QueryParam("jwksKeySize") @DefaultValue("2048") int jwksKeySize);
 
     @DELETE
     @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/OIDCJWKSLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/OIDCJWKSLogic.java
index 59cb1b6..e088d7b 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/OIDCJWKSLogic.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/OIDCJWKSLogic.java
@@ -23,7 +23,6 @@
 import org.apache.syncope.common.lib.to.OIDCJWKSTO;
 import org.apache.syncope.common.lib.types.AMEntitlement;
 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
-import org.apache.syncope.common.lib.types.JWSAlgorithm;
 import org.apache.syncope.core.persistence.api.dao.DuplicateException;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.OIDCJWKSDAO;
@@ -54,10 +53,10 @@
 
     @PreAuthorize("hasRole('" + AMEntitlement.OIDC_JWKS_GENERATE + "') "
             + "or hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
-    public OIDCJWKSTO generate(final int size, final JWSAlgorithm algorithm) {
+    public OIDCJWKSTO generate(final String jwksKeyId, final String jwksType, final int jwksKeySize) {
         OIDCJWKS jwks = dao.get();
         if (jwks == null) {
-            return binder.getOIDCJWKSTO(dao.save(binder.create(size, algorithm)));
+            return binder.getOIDCJWKSTO(dao.save(binder.create(jwksKeyId, jwksType, jwksKeySize)));
         }
         throw new DuplicateException("OIDC JWKS already set");
     }
@@ -78,7 +77,7 @@
     }
 
     @PreAuthorize("hasRole('" + AMEntitlement.OIDC_JWKS_SET + "') "
-        + "or hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
+            + "or hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
     public OIDCJWKSTO set(final OIDCJWKSTO entityTO) {
         OIDCJWKS jwks = dao.get();
         jwks.setJson(entityTO.getJson());
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCJWKSServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCJWKSServiceImpl.java
index 183ced7..dd58b47 100644
--- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCJWKSServiceImpl.java
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCJWKSServiceImpl.java
@@ -21,7 +21,6 @@
 import java.net.URI;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.common.lib.to.OIDCJWKSTO;
-import org.apache.syncope.common.lib.types.JWSAlgorithm;
 import org.apache.syncope.common.rest.api.service.OIDCJWKSService;
 import org.apache.syncope.core.logic.OIDCJWKSLogic;
 import org.springframework.stereotype.Service;
@@ -46,8 +45,8 @@
     }
 
     @Override
-    public Response generate(final int size, final JWSAlgorithm algorithm) {
-        OIDCJWKSTO jwks = logic.generate(size, algorithm);
+    public Response generate(final String jwksKeyId, final String jwksType, final int jwksKeySize) {
+        OIDCJWKSTO jwks = logic.generate(jwksKeyId, jwksType, jwksKeySize);
         URI location = uriInfo.getAbsolutePathBuilder().build();
         return Response.created(location).entity(jwks).build();
     }
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/OIDCJWKSDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/OIDCJWKSDataBinder.java
index bfd8303..8baf5da 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/OIDCJWKSDataBinder.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/OIDCJWKSDataBinder.java
@@ -19,12 +19,11 @@
 package org.apache.syncope.core.provisioning.api.data;
 
 import org.apache.syncope.common.lib.to.OIDCJWKSTO;
-import org.apache.syncope.common.lib.types.JWSAlgorithm;
 import org.apache.syncope.core.persistence.api.entity.am.OIDCJWKS;
 
 public interface OIDCJWKSDataBinder {
 
     OIDCJWKSTO getOIDCJWKSTO(OIDCJWKS jwks);
 
-    OIDCJWKS create(int size, JWSAlgorithm algorithm);
+    OIDCJWKS create(String jwksKeyId, String jwksType, int jwksKeySize);
 }
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/OIDCJWKSDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/OIDCJWKSDataBinderImpl.java
index 88f28c9..c8296be 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/OIDCJWKSDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/OIDCJWKSDataBinderImpl.java
@@ -19,15 +19,22 @@
 package org.apache.syncope.core.provisioning.java.data;
 
 import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.jwk.Curve;
+import com.nimbusds.jose.jwk.ECKey;
+import com.nimbusds.jose.jwk.JWK;
 import com.nimbusds.jose.jwk.JWKSet;
 import com.nimbusds.jose.jwk.KeyUse;
-import com.nimbusds.jose.jwk.RSAKey;
 import com.nimbusds.jose.jwk.gen.RSAKeyGenerator;
 import com.nimbusds.jose.util.JSONObjectUtils;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.OIDCJWKSTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.JWSAlgorithm;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.am.OIDCJWKS;
 import org.apache.syncope.core.provisioning.api.data.OIDCJWKSDataBinder;
@@ -51,22 +58,66 @@
     }
 
     @Override
-    public OIDCJWKS create(final int size, final JWSAlgorithm algorithm) {
+    public OIDCJWKS create(final String jwksKeyId, final String jwksType, final int jwksKeySize) {
+        JWK jwk;
         try {
-            OIDCJWKS jwks = entityFactory.newEntity(OIDCJWKS.class);
-            RSAKey jwk = new RSAKeyGenerator(size).
-                    keyUse(KeyUse.SIGNATURE).
-                    keyID(SecureRandomUtils.generateRandomUUID().toString()).
-                    algorithm(new com.nimbusds.jose.JWSAlgorithm(algorithm.name())).
-                    generate();
-            jwks.setJson(JSONObjectUtils.toJSONString(new JWKSet(jwk).toJSONObject(false)));
-            return jwks;
-        } catch (JOSEException e) {
+            switch (jwksType.trim().toLowerCase()) {
+                case "ec":
+                    KeyPairGenerator gen = KeyPairGenerator.getInstance("EC");
+                    KeyPair keyPair;
+                    switch (jwksKeySize) {
+                        case 384:
+                            gen.initialize(Curve.P_384.toECParameterSpec());
+                            keyPair = gen.generateKeyPair();
+                            jwk = new ECKey.Builder(Curve.P_384, (ECPublicKey) keyPair.getPublic()).
+                                    privateKey((ECPrivateKey) keyPair.getPrivate()).
+                                    keyUse(KeyUse.SIGNATURE).
+                                    keyID(jwksKeyId.concat("-").
+                                            concat(SecureRandomUtils.generateRandomUUID().toString().substring(0, 8))).
+                                    build();
+                            break;
+
+                        case 512:
+                            gen.initialize(Curve.P_521.toECParameterSpec());
+                            keyPair = gen.generateKeyPair();
+                            jwk = new ECKey.Builder(Curve.P_521, (ECPublicKey) keyPair.getPublic()).
+                                    privateKey((ECPrivateKey) keyPair.getPrivate()).
+                                    keyUse(KeyUse.SIGNATURE).
+                                    keyID(jwksKeyId.concat("-").
+                                            concat(SecureRandomUtils.generateRandomUUID().toString().substring(0, 8))).
+                                    build();
+                            break;
+
+                        default:
+                            gen.initialize(Curve.P_256.toECParameterSpec());
+                            keyPair = gen.generateKeyPair();
+                            jwk = new ECKey.Builder(Curve.P_256, (ECPublicKey) keyPair.getPublic()).
+                                    privateKey((ECPrivateKey) keyPair.getPrivate()).
+                                    keyUse(KeyUse.SIGNATURE).
+                                    keyID(jwksKeyId.concat("-").
+                                            concat(SecureRandomUtils.generateRandomUUID().toString().substring(0, 8))).
+                                    build();
+                    }
+                    break;
+
+                case "rsa":
+                default:
+                    jwk = new RSAKeyGenerator(jwksKeySize).
+                            keyUse(KeyUse.SIGNATURE).
+                            keyID(jwksKeyId.concat("-").
+                                    concat(SecureRandomUtils.generateRandomUUID().toString().substring(0, 8))).
+                            generate();
+            }
+        } catch (JOSEException | InvalidAlgorithmParameterException | NoSuchAlgorithmException e) {
             LOG.error("Could not create OIDC JWKS", e);
 
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unknown);
             sce.getElements().add(e.getMessage());
             throw sce;
         }
+
+        OIDCJWKS jwks = entityFactory.newEntity(OIDCJWKS.class);
+        jwks.setJson(JSONObjectUtils.toJSONString(new JWKSet(jwk).toJSONObject(false)));
+        return jwks;
     }
 }
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/MustChangePasswordFilter.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/MustChangePasswordFilter.java
index 33479e8..92c6b8b 100644
--- a/core/spring/src/main/java/org/apache/syncope/core/spring/security/MustChangePasswordFilter.java
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/MustChangePasswordFilter.java
@@ -28,7 +28,7 @@
 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
 import org.springframework.security.access.AccessDeniedException;
 import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.web.firewall.FirewalledRequest;
+import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper;
 
 public class MustChangePasswordFilter implements Filter {
 
@@ -46,12 +46,13 @@
     public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
             throws IOException, ServletException {
 
-        if (request instanceof FirewalledRequest) {
+        if (request instanceof SecurityContextHolderAwareRequestWrapper) {
             boolean isMustChangePassword =
                     SecurityContextHolder.getContext().getAuthentication().getAuthorities().stream().anyMatch(
                             authority -> IdRepoEntitlement.MUST_CHANGE_PASSWORD.equals(authority.getAuthority()));
 
-            FirewalledRequest wrappedRequest = FirewalledRequest.class.cast(request);
+            SecurityContextHolderAwareRequestWrapper wrappedRequest =
+                    SecurityContextHolderAwareRequestWrapper.class.cast(request);
             if (isMustChangePassword && !"POST".equalsIgnoreCase(wrappedRequest.getMethod())
                     && !"/users/self/changePassword".equals(wrappedRequest.getPathInfo())) {
 
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/WebSecurityContext.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/WebSecurityContext.java
index 6117375..e9ffb1b 100644
--- a/core/spring/src/main/java/org/apache/syncope/core/spring/security/WebSecurityContext.java
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/WebSecurityContext.java
@@ -38,15 +38,16 @@
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.authentication.AnonymousAuthenticationProvider;
+import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.builders.WebSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
 import org.springframework.security.config.http.SessionCreationPolicy;
 import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.access.AccessDeniedHandler;
 import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
 import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
@@ -74,66 +75,65 @@
     }
 
     @Bean
-    public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter(
-            final ApplicationContext ctx,
+    public WebSecurityCustomizer webSecurityCustomizer(final HttpFirewall allowUrlEncodedSlashHttpFirewall) {
+        return web -> web.httpFirewall(allowUrlEncodedSlashHttpFirewall);
+    }
+
+    @Bean
+    public SecurityFilterChain filterChain(
+            final HttpSecurity http,
+            final UsernamePasswordAuthenticationProvider usernamePasswordAuthenticationProvider,
+            final JWTAuthenticationProvider jwtAuthenticationProvider,
             final SecurityProperties securityProperties,
-            final HttpFirewall allowUrlEncodedSlashHttpFirewall) {
+            final ApplicationContext ctx) throws Exception {
 
-        return new WebSecurityConfigurerAdapter(true) {
+        AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManagerBuilder.class).
+                authenticationProvider(usernamePasswordAuthenticationProvider).
+                authenticationProvider(jwtAuthenticationProvider).
+                build();
 
-            @Override
-            public void configure(final WebSecurity web) {
-                web.httpFirewall(allowUrlEncodedSlashHttpFirewall);
-            }
+        SyncopeAuthenticationDetailsSource authenticationDetailsSource =
+                new SyncopeAuthenticationDetailsSource();
 
-            @Override
-            protected void configure(final HttpSecurity http) throws Exception {
-                SyncopeAuthenticationDetailsSource authenticationDetailsSource =
-                        new SyncopeAuthenticationDetailsSource();
+        AnonymousAuthenticationProvider anonymousAuthenticationProvider =
+                new AnonymousAuthenticationProvider(ANONYMOUS_BEAN_KEY);
+        AnonymousAuthenticationFilter anonymousAuthenticationFilter =
+                new AnonymousAuthenticationFilter(
+                        ANONYMOUS_BEAN_KEY,
+                        securityProperties.getAnonymousUser(),
+                        AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"));
+        anonymousAuthenticationFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
 
-                AnonymousAuthenticationProvider anonymousAuthenticationProvider =
-                        new AnonymousAuthenticationProvider(ANONYMOUS_BEAN_KEY);
-                AnonymousAuthenticationFilter anonymousAuthenticationFilter =
-                        new AnonymousAuthenticationFilter(
-                                ANONYMOUS_BEAN_KEY,
-                                securityProperties.getAnonymousUser(),
-                                AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"));
-                anonymousAuthenticationFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
+        SyncopeBasicAuthenticationEntryPoint basicAuthenticationEntryPoint =
+                new SyncopeBasicAuthenticationEntryPoint();
+        basicAuthenticationEntryPoint.setRealmName("Apache Syncope authentication");
 
-                SyncopeBasicAuthenticationEntryPoint basicAuthenticationEntryPoint =
-                        new SyncopeBasicAuthenticationEntryPoint();
-                basicAuthenticationEntryPoint.setRealmName("Apache Syncope authentication");
+        JWTAuthenticationFilter jwtAuthenticationFilter = new JWTAuthenticationFilter(
+                authenticationManager,
+                basicAuthenticationEntryPoint,
+                authenticationDetailsSource,
+                ctx.getBean(AuthDataAccessor.class),
+                ctx.getBean(DefaultCredentialChecker.class));
 
-                JWTAuthenticationFilter jwtAuthenticationFilter = new JWTAuthenticationFilter(
-                        authenticationManager(),
-                        basicAuthenticationEntryPoint,
-                        authenticationDetailsSource,
-                        ctx.getBean(AuthDataAccessor.class),
-                        ctx.getBean(DefaultCredentialChecker.class));
+        MustChangePasswordFilter mustChangePasswordFilter = new MustChangePasswordFilter();
 
-                http.authorizeRequests().
-                        antMatchers("/**").permitAll().and().
-                        sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().
-                        securityContext().securityContextRepository(new NullSecurityContextRepository()).and().
-                        anonymous().
-                        authenticationProvider(anonymousAuthenticationProvider).
-                        authenticationFilter(anonymousAuthenticationFilter).and().
-                        httpBasic().authenticationEntryPoint(basicAuthenticationEntryPoint).
-                        authenticationDetailsSource(authenticationDetailsSource).and().
-                        exceptionHandling().accessDeniedHandler(accessDeniedHandler()).and().
-                        addFilterBefore(jwtAuthenticationFilter, BasicAuthenticationFilter.class).
-                        addFilterBefore(new MustChangePasswordFilter(), FilterSecurityInterceptor.class).
-                        headers().disable().
-                        csrf().disable();
-            }
+        http.authenticationManager(authenticationManager).
+                authorizeRequests().
+                antMatchers("/**").permitAll().and().
+                sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().
+                securityContext().securityContextRepository(new NullSecurityContextRepository()).and().
+                anonymous().
+                authenticationProvider(anonymousAuthenticationProvider).
+                authenticationFilter(anonymousAuthenticationFilter).and().
+                httpBasic().authenticationEntryPoint(basicAuthenticationEntryPoint).
+                authenticationDetailsSource(authenticationDetailsSource).and().
+                exceptionHandling().accessDeniedHandler(accessDeniedHandler()).and().
+                addFilterBefore(jwtAuthenticationFilter, BasicAuthenticationFilter.class).
+                addFilterBefore(mustChangePasswordFilter, FilterSecurityInterceptor.class).
+                headers().disable().
+                csrf().disable();
 
-            @Override
-            protected void configure(final AuthenticationManagerBuilder builder) throws Exception {
-                builder.
-                        authenticationProvider(ctx.getBean(UsernamePasswordAuthenticationProvider.class)).
-                        authenticationProvider(ctx.getBean(JWTAuthenticationProvider.class));
-            }
-        };
+        return http.build();
     }
 
     @ConditionalOnMissingBean
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/OIDCJWKSITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/OIDCJWKSITCase.java
index 6ba3177..39af643 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/OIDCJWKSITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/OIDCJWKSITCase.java
@@ -28,7 +28,6 @@
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.JWSAlgorithm;
 import org.apache.syncope.common.rest.api.service.OIDCJWKSService;
 import org.apache.syncope.fit.AbstractITCase;
 import org.junit.jupiter.api.BeforeAll;
@@ -59,10 +58,10 @@
             assertEquals(ClientExceptionType.NotFound, e.getType());
         }
 
-        Response response = WA_OIDC_JWKS_SERVICE.generate(2048, JWSAlgorithm.RS256);
+        Response response = WA_OIDC_JWKS_SERVICE.generate("syncope", "RSA", 2048);
         assertEquals(HttpStatus.CREATED.value(), response.getStatus());
         try {
-            WA_OIDC_JWKS_SERVICE.generate(2048, JWSAlgorithm.RS512);
+            WA_OIDC_JWKS_SERVICE.generate("syncope", "RSA", 2048);
             fail("Should not recreate an OIDC JWKS");
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.EntityExists, e.getType());
diff --git a/fit/wa-reference/pom.xml b/fit/wa-reference/pom.xml
index ddc3dff..efbf265 100644
--- a/fit/wa-reference/pom.xml
+++ b/fit/wa-reference/pom.xml
@@ -39,6 +39,18 @@
     <rootpom.basedir>${basedir}/../..</rootpom.basedir>
   </properties>
 
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.apereo.cas</groupId>
+        <artifactId>cas-server-support-bom</artifactId>
+        <version>${cas.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
   <dependencies>
     <dependency>
       <groupId>org.apache.syncope.wa</groupId>
diff --git a/pom.xml b/pom.xml
index 9a4e18b..6c49eef 100644
--- a/pom.xml
+++ b/pom.xml
@@ -411,7 +411,7 @@
 
     <jackson.version>2.13.3</jackson.version>
 
-    <spring-boot.version>2.6.10</spring-boot.version>
+    <spring-boot.version>2.7.2</spring-boot.version>
     <spring-cloud-gateway.version>3.1.3</spring-cloud-gateway.version>
 
     <openjpa.version>3.2.2</openjpa.version>
@@ -430,7 +430,7 @@
 
     <slf4j.version>1.7.36</slf4j.version>
 
-    <elasticsearch.version>8.3.2</elasticsearch.version>
+    <elasticsearch.version>8.3.3</elasticsearch.version>
 
     <apacheds.version>2.0.0.AM26</apacheds.version>
     <apachedirapi.version>2.0.0</apachedirapi.version>
@@ -446,9 +446,9 @@
 
     <modernizer-maven.version>2.4.0</modernizer-maven.version>
 
-    <pac4j.version>5.3.1</pac4j.version>
+    <pac4j.version>5.4.3</pac4j.version>
 
-    <cas.version>6.5.6</cas.version>
+    <cas.version>6.6.0-RC5</cas.version>
     <cas-client.version>3.6.4</cas-client.version>
 
     <h2.version>2.1.214</h2.version>
@@ -510,11 +510,11 @@
     <docker.mysql.version>8.0</docker.mysql.version>
     <docker.mariadb.version>10</docker.mariadb.version>
 
-    <jdbc.postgresql.version>42.3.6</jdbc.postgresql.version>
+    <jdbc.postgresql.version>42.4.0</jdbc.postgresql.version>
     <jdbc.mysql.version>8.0.28</jdbc.mysql.version>
     <jdbc.mariadb.version>3.0.5</jdbc.mariadb.version>
     <jdbc.mssql.version>10.2.1.jre</jdbc.mssql.version>
-    <jdbc.oracle.version>21.5.0.0</jdbc.oracle.version>
+    <jdbc.oracle.version>21.6.0.0.1</jdbc.oracle.version>
 
     <conf.directory>${project.build.directory}/test-classes</conf.directory>
     <bundles.directory>${project.build.directory}/bundles</bundles.directory>
@@ -1273,354 +1273,6 @@
 
       <!-- CAS -->
       <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-audit</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-events-api</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-authentication</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-configuration-api</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-util-api</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-configuration</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-cookie</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-logout</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-logging</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-services</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-authentication-api</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-services-registry</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-services-api</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-tickets</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-util</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-validation</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-web</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-webflow</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-events-configuration</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-thymeleaf</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-actions</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-jpa-util</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-ldap</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-reports</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-syncope-authentication</artifactId>
-        <version>${cas.version}</version>
-        <exclusions>
-          <exclusion>
-            <groupId>com.github.mmoayyed.cxf</groupId>
-            <artifactId>cxf-rt-rs-extension-search</artifactId>
-          </exclusion>
-        </exclusions>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-saml</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-person-directory</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-person-directory-core</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-themes</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-audit-api</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-saml-idp</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-saml-idp-core</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-oidc</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-oidc-core-api</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-oidc-core</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-oauth-services</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-validation</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-pm-webflow</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-pac4j-webflow</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-pac4j-core-clients</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-consent-webflow</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-aup-webflow</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-u2f</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-u2f-core</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-webauthn</artifactId>
-        <version>${cas.version}</version>
-        <exclusions>
-          <exclusion>
-            <groupId>javax.ws.rs</groupId>
-            <artifactId>javax.ws.rs-api</artifactId>
-          </exclusion>
-          <exclusion>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-servlet</artifactId>
-          </exclusion>
-          <exclusion>
-            <groupId>org.glassfish.jersey.containers</groupId>
-            <artifactId>jersey-container-servlet-core</artifactId>
-          </exclusion>
-        </exclusions>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-webauthn-core</artifactId>
-        <version>${cas.version}</version>
-        <exclusions>
-          <exclusion>
-            <groupId>javax.ws.rs</groupId>
-            <artifactId>javax.ws.rs-api</artifactId>
-          </exclusion>
-          <exclusion>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-servlet</artifactId>
-          </exclusion>
-          <exclusion>
-            <groupId>org.glassfish.jersey.containers</groupId>
-            <artifactId>jersey-container-servlet-core</artifactId>
-          </exclusion>
-          <exclusion>
-            <groupId>com.google.code.findbugs</groupId>
-            <artifactId>jsr305</artifactId>
-          </exclusion>
-        </exclusions>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-simple-mfa</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-simple-mfa-core</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-gauth</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-ldap-core</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-gauth-ldap</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-duo</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-gauth-core-mfa</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-otp-mfa-core</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-oidc-services</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-swagger</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-authentication-attributes</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-core-services-authentication</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-webapp-config</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-surrogate-webflow</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apereo.cas</groupId>
-        <artifactId>cas-server-support-surrogate-api</artifactId>
-        <version>${cas.version}</version>
-      </dependency>
-      <dependency>
         <groupId>org.jasig.cas.client</groupId>
         <artifactId>cas-client-core</artifactId>
         <version>${cas-client.version}</version>
@@ -2009,7 +1661,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-resources-plugin</artifactId>
-          <version>3.1.0</version>
+          <version>3.3.0</version>
           <configuration>
             <useDefaultDelimiters>false</useDefaultDelimiters>
             <delimiters>
diff --git a/wa/bootstrap/pom.xml b/wa/bootstrap/pom.xml
index 9ea1e97..5fe2a70 100644
--- a/wa/bootstrap/pom.xml
+++ b/wa/bootstrap/pom.xml
@@ -48,6 +48,7 @@
       <artifactId>syncope-common-keymaster-client-api</artifactId>
       <version>${project.version}</version>
     </dependency>
+
     <dependency>
       <groupId>org.apereo.cas</groupId>
       <artifactId>cas-server-core-configuration-api</artifactId>
diff --git a/wa/bootstrap/src/main/java/org/apache/syncope/wa/bootstrap/AuthModulePropertySourceMapper.java b/wa/bootstrap/src/main/java/org/apache/syncope/wa/bootstrap/AuthModulePropertySourceMapper.java
index da16ba0..b14c7fe 100644
--- a/wa/bootstrap/src/main/java/org/apache/syncope/wa/bootstrap/AuthModulePropertySourceMapper.java
+++ b/wa/bootstrap/src/main/java/org/apache/syncope/wa/bootstrap/AuthModulePropertySourceMapper.java
@@ -248,13 +248,15 @@
         CasSimpleMultifactorAuthenticationProperties props = new CasSimpleMultifactorAuthenticationProperties();
         props.setName(authModuleTO.getKey());
         props.setOrder(authModuleTO.getOrder());
-        props.setTokenLength(conf.getTokenLength());
-        props.setTimeToKillInSeconds(conf.getTimeToKillInSeconds());
+
         props.getMail().setAttributeName(conf.getEmailAttribute());
         props.getMail().setFrom(conf.getEmailFrom());
         props.getMail().setSubject(conf.getEmailSubject());
         props.getMail().setText(conf.getEmailText());
 
+        props.getToken().getCore().setTokenLength(conf.getTokenLength());
+        props.getToken().getCore().setTimeToKillInSeconds(conf.getTimeToKillInSeconds());
+
         if (StringUtils.isNotBlank(conf.getBypassGroovyScript())) {
             try {
                 props.getBypass().getGroovy().setLocation(ResourceUtils.getResourceFrom(conf.getBypassGroovyScript()));
diff --git a/wa/pom.xml b/wa/pom.xml
index 0dd676a..49f3b7c 100644
--- a/wa/pom.xml
+++ b/wa/pom.xml
@@ -36,6 +36,18 @@
     <rootpom.basedir>${basedir}/..</rootpom.basedir>
   </properties>
 
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.apereo.cas</groupId>
+        <artifactId>cas-server-support-bom</artifactId>
+        <version>${cas.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
   <profiles>
     <profile>
       <id>site</id>
diff --git a/wa/starter/pom.xml b/wa/starter/pom.xml
index 8abf4c0..0c9e160 100644
--- a/wa/starter/pom.xml
+++ b/wa/starter/pom.xml
@@ -64,6 +64,10 @@
     </dependency>
     <dependency>
       <groupId>org.apereo.cas</groupId>
+      <artifactId>cas-server-core-events-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apereo.cas</groupId>
       <artifactId>cas-server-core-authentication</artifactId>
     </dependency>
     <dependency>
@@ -72,14 +76,6 @@
     </dependency>
     <dependency>
       <groupId>org.apereo.cas</groupId>
-      <artifactId>cas-server-core-audit-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apereo.cas</groupId>
-      <artifactId>cas-server-core-events-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apereo.cas</groupId>
       <artifactId>cas-server-core-cookie</artifactId>
     </dependency>
     <dependency>
@@ -96,6 +92,10 @@
     </dependency>
     <dependency>
       <groupId>org.apereo.cas</groupId>
+      <artifactId>cas-server-core-authentication-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apereo.cas</groupId>
       <artifactId>cas-server-core-services-registry</artifactId>
     </dependency>
     <dependency>
@@ -120,10 +120,6 @@
     </dependency>
     <dependency>
       <groupId>org.apereo.cas</groupId>
-      <artifactId>cas-server-core-authentication-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apereo.cas</groupId>
       <artifactId>cas-server-core-webflow</artifactId>
     </dependency>
     <dependency>
@@ -153,6 +149,12 @@
     <dependency>
       <groupId>org.apereo.cas</groupId>
       <artifactId>cas-server-support-syncope-authentication</artifactId>
+      <exclusions>
+        <exclusion>
+          <groupId>com.github.mmoayyed.cxf</groupId>
+          <artifactId>cxf-rt-rs-extension-search</artifactId>
+        </exclusion>
+      </exclusions>
     </dependency>
     <dependency>
       <groupId>org.apereo.cas</groupId>
@@ -172,6 +174,10 @@
     </dependency>
     <dependency>
       <groupId>org.apereo.cas</groupId>
+      <artifactId>cas-server-core-audit-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apereo.cas</groupId>
       <artifactId>cas-server-support-saml-idp</artifactId>
     </dependency>
     <dependency>
@@ -218,15 +224,6 @@
       <groupId>org.apereo.cas</groupId>
       <artifactId>cas-server-support-aup-webflow</artifactId>
     </dependency>
-
-    <dependency>
-      <groupId>org.apereo.cas</groupId>
-      <artifactId>cas-server-support-webauthn</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apereo.cas</groupId>
-      <artifactId>cas-server-support-webauthn-core</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.apereo.cas</groupId>
       <artifactId>cas-server-support-u2f</artifactId>
@@ -237,6 +234,46 @@
     </dependency>
     <dependency>
       <groupId>org.apereo.cas</groupId>
+      <artifactId>cas-server-support-webauthn</artifactId>
+      <exclusions>
+        <exclusion>
+          <groupId>javax.ws.rs</groupId>
+          <artifactId>javax.ws.rs-api</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-servlet</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.glassfish.jersey.containers</groupId>
+          <artifactId>jersey-container-servlet-core</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.apereo.cas</groupId>
+      <artifactId>cas-server-support-webauthn-core</artifactId>
+      <exclusions>
+        <exclusion>
+          <groupId>javax.ws.rs</groupId>
+          <artifactId>javax.ws.rs-api</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-servlet</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.glassfish.jersey.containers</groupId>
+          <artifactId>jersey-container-servlet-core</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.google.code.findbugs</groupId>
+          <artifactId>jsr305</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.apereo.cas</groupId>
       <artifactId>cas-server-support-simple-mfa</artifactId>
     </dependency>
     <dependency>
@@ -249,11 +286,11 @@
     </dependency>
     <dependency>
       <groupId>org.apereo.cas</groupId>
-      <artifactId>cas-server-support-gauth-ldap</artifactId>
+      <artifactId>cas-server-support-ldap-core</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apereo.cas</groupId>
-      <artifactId>cas-server-support-ldap-core</artifactId>
+      <artifactId>cas-server-support-gauth-ldap</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apereo.cas</groupId>
@@ -269,12 +306,12 @@
     </dependency>
     <dependency>
       <groupId>org.apereo.cas</groupId>
-      <artifactId>cas-server-webapp-config</artifactId>
+      <artifactId>cas-server-support-oidc-services</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apereo.cas</groupId>
-      <artifactId>cas-server-support-oidc-services</artifactId>
-    </dependency>   
+      <artifactId>cas-server-support-swagger</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.apereo.cas</groupId>
       <artifactId>cas-server-core-authentication-attributes</artifactId>
@@ -285,7 +322,7 @@
     </dependency>
     <dependency>
       <groupId>org.apereo.cas</groupId>
-      <artifactId>cas-server-support-swagger</artifactId>
+      <artifactId>cas-server-webapp-config</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apereo.cas</groupId>
@@ -295,6 +332,7 @@
       <groupId>org.apereo.cas</groupId>
       <artifactId>cas-server-support-surrogate-api</artifactId>
     </dependency>
+
     <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/SyncopeWAApplication.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/SyncopeWAApplication.java
index 5cd8a43..cda6bd0 100644
--- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/SyncopeWAApplication.java
+++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/SyncopeWAApplication.java
@@ -27,6 +27,7 @@
 import org.apereo.cas.config.GoogleAuthenticatorLdapConfiguration;
 import org.apereo.cas.configuration.CasConfigurationProperties;
 import org.apereo.cas.configuration.CasConfigurationPropertiesValidator;
+import org.apereo.cas.oidc.config.OidcJwksJpaConfiguration;
 import org.quartz.JobBuilder;
 import org.quartz.JobDetail;
 import org.quartz.JobKey;
@@ -61,10 +62,12 @@
 
 @SpringBootApplication(exclude = {
     /*
-     * List of CAS-specific classes that we want to exclude from auto-configuration. This is required when there is a
-     * competing option/implementation available in Syncope that needs to be conditionally activated.
+     * List of CAS-specific classes that we want to exclude from auto-configuration.
+     * This is required when there is a competing option/implementation available in Syncope that needs to be
+     * conditionally activated.
      */
     GoogleAuthenticatorLdapConfiguration.class,
+    OidcJwksJpaConfiguration.class,
     /*
      * List of Spring Boot classes that we want to disable and remove from auto-configuration.
      */
diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/audit/WAAuditTrailManager.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/audit/WAAuditTrailManager.java
index 6dfdf01..f4119a8 100644
--- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/audit/WAAuditTrailManager.java
+++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/audit/WAAuditTrailManager.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.wa.starter.audit;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
-import java.time.LocalDate;
 import java.time.OffsetDateTime;
 import java.util.Map;
 import java.util.Set;
@@ -79,7 +78,7 @@
     }
 
     @Override
-    public Set<? extends AuditActionContext> getAuditRecordsSince(final LocalDate sinceDate) {
+    public Set<? extends AuditActionContext> getAuditRecords(final Map<WhereClauseFields, Object> map) {
         throw new UnsupportedOperationException("Fetching audit events from WA is not supported");
     }
 
diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/config/WAContext.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/config/WAContext.java
index 76bea8a..9a91ba0 100644
--- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/config/WAContext.java
+++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/config/WAContext.java
@@ -35,7 +35,6 @@
 import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
 import org.apache.syncope.common.keymaster.client.api.startstop.KeymasterStart;
 import org.apache.syncope.common.keymaster.client.api.startstop.KeymasterStop;
-import org.apache.syncope.common.lib.types.JWSAlgorithm;
 import org.apache.syncope.wa.bootstrap.WAProperties;
 import org.apache.syncope.wa.bootstrap.WARestClient;
 import org.apache.syncope.wa.starter.actuate.SyncopeCoreHealthIndicator;
@@ -77,12 +76,11 @@
 import org.apereo.cas.gauth.credential.LdapGoogleAuthenticatorTokenCredentialRepository;
 import org.apereo.cas.oidc.jwks.generator.OidcJsonWebKeystoreGeneratorService;
 import org.apereo.cas.otp.repository.credentials.OneTimeTokenCredentialRepository;
-import org.apereo.cas.otp.repository.token.OneTimeTokenRepository;
 import org.apereo.cas.services.ServiceRegistryExecutionPlanConfigurer;
 import org.apereo.cas.services.ServiceRegistryListener;
 import org.apereo.cas.support.events.CasEventRepository;
 import org.apereo.cas.support.events.CasEventRepositoryFilter;
-import org.apereo.cas.support.pac4j.authentication.DelegatedClientFactoryCustomizer;
+import org.apereo.cas.support.pac4j.authentication.clients.DelegatedClientFactoryCustomizer;
 import org.apereo.cas.support.pac4j.authentication.handler.support.DelegatedClientAuthenticationHandler;
 import org.apereo.cas.support.saml.idp.metadata.generator.SamlIdPMetadataGenerator;
 import org.apereo.cas.support.saml.idp.metadata.generator.SamlIdPMetadataGeneratorConfigurationContext;
@@ -276,7 +274,7 @@
     }
 
     @Bean
-    public OneTimeTokenRepository oneTimeTokenAuthenticatorTokenRepository(
+    public WAGoogleMfaAuthTokenRepository oneTimeTokenAuthenticatorTokenRepository(
             final CasConfigurationProperties casProperties,
             final WARestClient restClient) {
 
@@ -290,7 +288,9 @@
     public OneTimeTokenCredentialRepository googleAuthenticatorAccountRegistry(
             final CasConfigurationProperties casProperties,
             @Qualifier("googleAuthenticatorAccountCipherExecutor")
-            final CipherExecutor<String, String> cipherExecutor,
+            final CipherExecutor<String, String> googleAuthenticatorAccountCipherExecutor,
+            @Qualifier("googleAuthenticatorScratchCodesCipherExecutor")
+            final CipherExecutor<Number, Number> googleAuthenticatorScratchCodesCipherExecutor,
             final IGoogleAuthenticator googleAuthenticatorInstance,
             final WARestClient restClient) {
 
@@ -308,21 +308,25 @@
 
             ConnectionFactory connectionFactory = LdapUtils.newLdaptiveConnectionFactory(ldap);
             return new LdapGoogleAuthenticatorTokenCredentialRepository(
-                    cipherExecutor, googleAuthenticatorInstance, connectionFactory, ldap);
+                    googleAuthenticatorAccountCipherExecutor,
+                    googleAuthenticatorScratchCodesCipherExecutor,
+                    googleAuthenticatorInstance,
+                    connectionFactory,
+                    ldap);
         }
         return new WAGoogleMfaAuthCredentialRepository(restClient, googleAuthenticatorInstance);
     }
 
     @Bean
     public OidcJsonWebKeystoreGeneratorService oidcJsonWebKeystoreGeneratorService(
-            final ConfigurableApplicationContext ctx,
+            final CasConfigurationProperties casProperties,
             final WARestClient restClient) {
 
-        int size = ctx.getEnvironment().
-                getProperty("cas.authn.oidc.jwks.size", int.class, 2048);
-        JWSAlgorithm algorithm = ctx.getEnvironment().
-                getProperty("cas.authn.oidc.jwks.algorithm", JWSAlgorithm.class, JWSAlgorithm.RS256);
-        return new WAOIDCJWKSGeneratorService(restClient, size, algorithm);
+        return new WAOIDCJWKSGeneratorService(
+                restClient,
+                casProperties.getAuthn().getOidc().getJwks().getCore().getJwksKeyId(),
+                casProperties.getAuthn().getOidc().getJwks().getCore().getJwksType(),
+                casProperties.getAuthn().getOidc().getJwks().getCore().getJwksKeySize());
     }
 
     @Bean
diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/gauth/WAGoogleMfaAuthCredentialRepository.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/gauth/WAGoogleMfaAuthCredentialRepository.java
index cb2b4fa0..e785ea2 100644
--- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/gauth/WAGoogleMfaAuthCredentialRepository.java
+++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/gauth/WAGoogleMfaAuthCredentialRepository.java
@@ -44,27 +44,27 @@
     public WAGoogleMfaAuthCredentialRepository(
             final WARestClient waRestClient, final IGoogleAuthenticator googleAuthenticator) {
 
-        super(CipherExecutor.noOpOfStringToString(), googleAuthenticator);
+        super(CipherExecutor.noOpOfStringToString(), CipherExecutor.noOpOfNumberToNumber(), googleAuthenticator);
         this.waRestClient = waRestClient;
     }
 
-    protected GoogleMfaAuthAccount mapGoogleMfaAuthAccount(final OneTimeTokenAccount account) {
+    protected GoogleMfaAuthAccount mapGoogleMfaAuthAccount(final OneTimeTokenAccount otta) {
         return new GoogleMfaAuthAccount.Builder().
                 registrationDate(OffsetDateTime.now()).
-                scratchCodes(account.getScratchCodes()).
-                validationCode(account.getValidationCode()).
-                secretKey(account.getSecretKey()).
-                id(account.getId()).
+                scratchCodes(otta.getScratchCodes().stream().map(Number::intValue).collect(Collectors.toList())).
+                validationCode(otta.getValidationCode()).
+                secretKey(otta.getSecretKey()).
+                id(otta.getId()).
                 build();
     }
 
-    protected GoogleAuthenticatorAccount mapGoogleMfaAuthAccount(final GoogleMfaAuthAccount account) {
+    protected GoogleAuthenticatorAccount mapGoogleMfaAuthAccount(final GoogleMfaAuthAccount gmfaa) {
         return GoogleAuthenticatorAccount.builder().
-                secretKey(account.getSecretKey()).
-                validationCode(account.getValidationCode()).
-                scratchCodes(account.getScratchCodes()).
-                name(account.getName()).
-                id(account.getId()).
+                secretKey(gmfaa.getSecretKey()).
+                validationCode(gmfaa.getValidationCode()).
+                scratchCodes(gmfaa.getScratchCodes().stream().map(Number::intValue).collect(Collectors.toList())).
+                name(gmfaa.getName()).
+                id(gmfaa.getId()).
                 build();
     }
 
@@ -134,17 +134,17 @@
     }
 
     @Override
-    public OneTimeTokenAccount save(final OneTimeTokenAccount tokenAccount) {
+    public OneTimeTokenAccount save(final OneTimeTokenAccount otta) {
         GoogleMfaAuthAccount account = new GoogleMfaAuthAccount.Builder().
                 registrationDate(OffsetDateTime.now()).
-                scratchCodes(tokenAccount.getScratchCodes()).
-                validationCode(tokenAccount.getValidationCode()).
-                secretKey(tokenAccount.getSecretKey()).
-                name(tokenAccount.getName()).
-                id(tokenAccount.getId()).
+                scratchCodes(otta.getScratchCodes().stream().map(Number::intValue).collect(Collectors.toList())).
+                validationCode(otta.getValidationCode()).
+                secretKey(otta.getSecretKey()).
+                name(otta.getName()).
+                id(otta.getId()).
                 build();
         waRestClient.getSyncopeClient().
-                getService(GoogleMfaAuthAccountService.class).create(tokenAccount.getUsername(), account);
+                getService(GoogleMfaAuthAccountService.class).create(otta.getUsername(), account);
         return mapGoogleMfaAuthAccount(account);
     }
 
diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/gauth/WAGoogleMfaAuthTokenRepository.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/gauth/WAGoogleMfaAuthTokenRepository.java
index 95f887c..74d3336 100644
--- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/gauth/WAGoogleMfaAuthTokenRepository.java
+++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/gauth/WAGoogleMfaAuthTokenRepository.java
@@ -22,13 +22,12 @@
 import org.apache.syncope.common.lib.wa.GoogleMfaAuthToken;
 import org.apache.syncope.common.rest.api.service.wa.GoogleMfaAuthTokenService;
 import org.apache.syncope.wa.bootstrap.WARestClient;
-import org.apereo.cas.authentication.OneTimeToken;
 import org.apereo.cas.gauth.token.GoogleAuthenticatorToken;
 import org.apereo.cas.otp.repository.token.BaseOneTimeTokenRepository;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class WAGoogleMfaAuthTokenRepository extends BaseOneTimeTokenRepository {
+public class WAGoogleMfaAuthTokenRepository extends BaseOneTimeTokenRepository<GoogleAuthenticatorToken> {
 
     protected static final Logger LOG = LoggerFactory.getLogger(WAGoogleMfaAuthTokenRepository.class);
 
@@ -51,7 +50,7 @@
     }
 
     @Override
-    public void store(final OneTimeToken token) {
+    public void store(final GoogleAuthenticatorToken token) {
         GoogleMfaAuthToken tokenTO = new GoogleMfaAuthToken.Builder().
                 token(token.getToken()).
                 issueDate(token.getIssuedDateTime()).
@@ -60,7 +59,7 @@
     }
 
     @Override
-    public OneTimeToken get(final String username, final Integer otp) {
+    public GoogleAuthenticatorToken get(final String username, final Integer otp) {
         try {
             GoogleMfaAuthToken tokenTO = service().read(username, otp);
             GoogleAuthenticatorToken token = new GoogleAuthenticatorToken(tokenTO.getOtp(), username);
diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/AbstractClientAppMapper.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/AbstractClientAppMapper.java
index ee62c2b..f9a9685 100644
--- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/AbstractClientAppMapper.java
+++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/AbstractClientAppMapper.java
@@ -22,8 +22,8 @@
 import java.util.stream.Collectors;
 import org.apache.syncope.common.lib.Attr;
 import org.apache.syncope.common.lib.to.ClientAppTO;
+import org.apereo.cas.services.BaseWebBasedRegisteredService;
 import org.apereo.cas.services.DefaultRegisteredServiceProperty;
-import org.apereo.cas.services.RegexRegisteredService;
 import org.apereo.cas.services.RegisteredServiceAccessStrategy;
 import org.apereo.cas.services.RegisteredServiceAttributeReleasePolicy;
 import org.apereo.cas.services.RegisteredServiceAuthenticationPolicy;
@@ -32,7 +32,7 @@
 
 abstract class AbstractClientAppMapper implements ClientAppMapper {
 
-    protected void setCommon(final RegexRegisteredService service, final ClientAppTO clientApp) {
+    protected void setCommon(final BaseWebBasedRegisteredService service, final ClientAppTO clientApp) {
         service.setId(clientApp.getClientAppId());
         service.setName(clientApp.getName());
         service.setDescription(clientApp.getDescription());
@@ -48,7 +48,7 @@
     }
 
     protected void setPolicies(
-            final RegexRegisteredService service,
+            final BaseWebBasedRegisteredService service,
             final RegisteredServiceAuthenticationPolicy authPolicy,
             final RegisteredServiceMultifactorPolicy mfaPolicy,
             final RegisteredServiceAccessStrategy accessStrategy,
@@ -58,7 +58,7 @@
             service.setAuthenticationPolicy(authPolicy);
         }
         if (mfaPolicy != null) {
-            service.setMultifactorPolicy(mfaPolicy);
+            service.setMultifactorAuthenticationPolicy(mfaPolicy);
         }
         if (accessStrategy != null) {
             service.setAccessStrategy(accessStrategy);
diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/CASSPClientAppTOMapper.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/CASSPClientAppTOMapper.java
index e1146ef..5d007d2 100644
--- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/CASSPClientAppTOMapper.java
+++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/CASSPClientAppTOMapper.java
@@ -20,7 +20,7 @@
 
 import org.apache.syncope.common.lib.to.CASSPClientAppTO;
 import org.apache.syncope.common.lib.wa.WAClientApp;
-import org.apereo.cas.services.RegexRegisteredService;
+import org.apereo.cas.services.CasRegisteredService;
 import org.apereo.cas.services.RegisteredService;
 import org.apereo.cas.services.RegisteredServiceAccessStrategy;
 import org.apereo.cas.services.RegisteredServiceAttributeReleasePolicy;
@@ -42,7 +42,7 @@
 
         CASSPClientAppTO cas = CASSPClientAppTO.class.cast(clientApp.getClientAppTO());
 
-        RegexRegisteredService service = new RegexRegisteredService();
+        CasRegisteredService service = new CasRegisteredService();
         service.setServiceId(cas.getServiceId());
         setCommon(service, cas);
 
diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/DefaultAttrReleaseMapper.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/DefaultAttrReleaseMapper.java
index ae508d6..f7eb0b3 100644
--- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/DefaultAttrReleaseMapper.java
+++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/DefaultAttrReleaseMapper.java
@@ -46,7 +46,8 @@
 
         ReturnMappedAttributeReleasePolicy returnMapped = null;
         if (!releaseAttrs.isEmpty()) {
-            returnMapped = new ReturnMappedAttributeReleasePolicy(releaseAttrs);
+            returnMapped = new ReturnMappedAttributeReleasePolicy();
+            returnMapped.setAllowedAttributes(releaseAttrs);
         }
 
         ReturnAllowedAttributeReleasePolicy returnAllowed = null;
diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/SAML2SPClientAppTOMapper.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/SAML2SPClientAppTOMapper.java
index d90dd0d..ac7e576 100644
--- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/SAML2SPClientAppTOMapper.java
+++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/SAML2SPClientAppTOMapper.java
@@ -52,7 +52,7 @@
         service.setMetadataLocation(sp.getMetadataLocation());
         service.setMetadataSignatureLocation(sp.getMetadataSignatureLocation());
         service.setSignAssertions(TriStateBoolean.fromBoolean(sp.isSignAssertions()));
-        service.setSignResponses(sp.isSignResponses());
+        service.setSignResponses(TriStateBoolean.fromBoolean(sp.isSignResponses()));
         service.setEncryptionOptional(sp.isEncryptionOptional());
         service.setEncryptAssertions(sp.isEncryptAssertions());
         service.setRequiredAuthenticationContextClass(sp.getRequiredAuthenticationContextClass());
diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/oidc/WAOIDCJWKSGeneratorService.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/oidc/WAOIDCJWKSGeneratorService.java
index e82f1ac..bac9706 100644
--- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/oidc/WAOIDCJWKSGeneratorService.java
+++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/oidc/WAOIDCJWKSGeneratorService.java
@@ -24,7 +24,6 @@
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.OIDCJWKSTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.JWSAlgorithm;
 import org.apache.syncope.common.rest.api.service.OIDCJWKSService;
 import org.apache.syncope.wa.bootstrap.WARestClient;
 import org.apereo.cas.oidc.jwks.generator.OidcJsonWebKeystoreGeneratorService;
@@ -37,20 +36,26 @@
 
 public class WAOIDCJWKSGeneratorService implements OidcJsonWebKeystoreGeneratorService {
 
-    private static final Logger LOG = LoggerFactory.getLogger(WAOIDCJWKSGeneratorService.class);
+    protected static final Logger LOG = LoggerFactory.getLogger(WAOIDCJWKSGeneratorService.class);
 
-    private final WARestClient waRestClient;
+    protected final WARestClient waRestClient;
 
-    private final int size;
+    protected final String jwksKeyId;
 
-    private final JWSAlgorithm algorithm;
+    protected final String jwksType;
+
+    protected final int jwksKeySize;
 
     public WAOIDCJWKSGeneratorService(
-            final WARestClient restClient, final int size, final JWSAlgorithm algorithm) {
+            final WARestClient restClient,
+            final String jwksKeyId,
+            final String jwksType,
+            final int jwksKeySize) {
 
         this.waRestClient = restClient;
-        this.size = size;
-        this.algorithm = algorithm;
+        this.jwksKeyId = jwksKeyId;
+        this.jwksType = jwksType;
+        this.jwksKeySize = jwksKeySize;
     }
 
     @Override
@@ -83,7 +88,7 @@
         } catch (SyncopeClientException e) {
             if (e.getType() == ClientExceptionType.NotFound) {
                 try {
-                    Response response = service.generate(size, algorithm);
+                    Response response = service.generate(jwksKeyId, jwksType, jwksKeySize);
                     jwksTO = response.readEntity(OIDCJWKSTO.class);
                 } catch (Exception ge) {
                     LOG.error("While generating new OIDC JWKS", ge);
diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientCustomizer.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientCustomizer.java
index 2456334..20afed7 100644
--- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientCustomizer.java
+++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientCustomizer.java
@@ -19,7 +19,7 @@
 package org.apache.syncope.wa.starter.pac4j.saml;
 
 import org.apache.syncope.wa.bootstrap.WARestClient;
-import org.apereo.cas.support.pac4j.authentication.DelegatedClientFactoryCustomizer;
+import org.apereo.cas.support.pac4j.authentication.clients.DelegatedClientFactoryCustomizer;
 import org.pac4j.core.client.Client;
 import org.pac4j.saml.client.SAML2Client;
 import org.pac4j.saml.config.SAML2Configuration;
diff --git a/wa/starter/src/test/java/org/apache/syncope/wa/starter/AbstractTest.java b/wa/starter/src/test/java/org/apache/syncope/wa/starter/AbstractTest.java
index c3d2927..0c37f9e 100644
--- a/wa/starter/src/test/java/org/apache/syncope/wa/starter/AbstractTest.java
+++ b/wa/starter/src/test/java/org/apache/syncope/wa/starter/AbstractTest.java
@@ -21,7 +21,7 @@
 import java.util.UUID;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.context.TestConfiguration;
-import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.boot.test.web.server.LocalServerPort;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.test.context.ContextConfiguration;
diff --git a/wa/starter/src/test/java/org/apache/syncope/wa/starter/gauth/token/WAGoogleMfaAuthTokenRepositoryTest.java b/wa/starter/src/test/java/org/apache/syncope/wa/starter/gauth/token/WAGoogleMfaAuthTokenRepositoryTest.java
index 835ddbf..b308923 100644
--- a/wa/starter/src/test/java/org/apache/syncope/wa/starter/gauth/token/WAGoogleMfaAuthTokenRepositoryTest.java
+++ b/wa/starter/src/test/java/org/apache/syncope/wa/starter/gauth/token/WAGoogleMfaAuthTokenRepositoryTest.java
@@ -29,7 +29,7 @@
 public class WAGoogleMfaAuthTokenRepositoryTest extends AbstractTest {
 
     @Autowired
-    private OneTimeTokenRepository tokenRepository;
+    private OneTimeTokenRepository<GoogleAuthenticatorToken> tokenRepository;
 
     @Test
     public void verifyOps() {