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 442a7360c7 Upgrading Spring Boot to 2.7 and CAS to 6.6 (#362) 442a7360c7 is described below commit 442a7360c76dca1c6d741fe5979b0be42018c4d0 Author: Francesco Chicchiriccò <ilgro...@users.noreply.github.com> AuthorDate: Fri Jul 29 14:52:33 2022 +0200 Upgrading Spring Boot to 2.7 and CAS to 6.6 (#362) --- .../main/resources/archetype-resources/wa/pom.xml | 12 + .../client/console/rest/OIDCJWKSRestClient.java | 3 +- .../syncope/client/console/SecurityConfig.java | 41 ++- .../syncope/client/enduser/SecurityConfig.java | 41 ++- .../enduser/pages/SelfResult_fr_CA.properties | 2 +- .../common/rest/api/service/OIDCJWKSService.java | 8 +- .../apache/syncope/core/logic/OIDCJWKSLogic.java | 7 +- .../core/rest/cxf/service/OIDCJWKSServiceImpl.java | 5 +- .../provisioning/api/data/OIDCJWKSDataBinder.java | 3 +- .../java/data/OIDCJWKSDataBinderImpl.java | 75 ++++- .../spring/security/MustChangePasswordFilter.java | 7 +- .../core/spring/security/WebSecurityContext.java | 122 +++---- .../apache/syncope/fit/core/OIDCJWKSITCase.java | 5 +- fit/wa-reference/pom.xml | 12 + pom.xml | 362 +-------------------- wa/bootstrap/pom.xml | 1 + .../bootstrap/AuthModulePropertySourceMapper.java | 6 +- wa/pom.xml | 12 + wa/starter/pom.xml | 82 +++-- .../syncope/wa/starter/SyncopeWAApplication.java | 7 +- .../wa/starter/audit/WAAuditTrailManager.java | 3 +- .../syncope/wa/starter/config/WAContext.java | 28 +- .../gauth/WAGoogleMfaAuthCredentialRepository.java | 38 +-- .../gauth/WAGoogleMfaAuthTokenRepository.java | 7 +- .../starter/mapping/AbstractClientAppMapper.java | 8 +- .../wa/starter/mapping/CASSPClientAppTOMapper.java | 4 +- .../starter/mapping/DefaultAttrReleaseMapper.java | 3 +- .../starter/mapping/SAML2SPClientAppTOMapper.java | 2 +- .../starter/oidc/WAOIDCJWKSGeneratorService.java | 23 +- .../pac4j/saml/WASAML2ClientCustomizer.java | 2 +- .../apache/syncope/wa/starter/AbstractTest.java | 2 +- .../token/WAGoogleMfaAuthTokenRepositoryTest.java | 2 +- 32 files changed, 360 insertions(+), 575 deletions(-) diff --git a/archetype/src/main/resources/archetype-resources/wa/pom.xml b/archetype/src/main/resources/archetype-resources/wa/pom.xml index 7a634d2e49..30bfb10273 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 @@ under the License. <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 340634c92f..57c4e68ff2 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 @@ package org.apache.syncope.client.console.rest; 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 class OIDCJWKSRestClient extends BaseRestClient { } 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 86a5e39294..f33629d732 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.apache.syncope.common.lib.types.IdRepoEntitlement; 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 38e6e6a5ae..3218618cdf 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.apache.syncope.common.lib.types.IdRepoEntitlement; 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 bcdb339109..3d4c66feed 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 53eb241b5a..97f83f86d9 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.HttpHeaders; 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 @@ public interface OIDCJWKSService extends JAXRSService { 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 @@ public interface OIDCJWKSService extends JAXRSService { @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 59cb1b6b98..e088d7bbd3 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 java.util.Optional; 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 @@ public class OIDCJWKSLogic extends AbstractTransactionalLogic<OIDCJWKSTO> { @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 @@ public class OIDCJWKSLogic extends AbstractTransactionalLogic<OIDCJWKSTO> { } @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 183ced746f..dd58b47704 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 @@ package org.apache.syncope.core.rest.cxf.service; 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 @@ public class OIDCJWKSServiceImpl extends AbstractService implements OIDCJWKSServ } @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 bfd8303c32..8baf5da9e0 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 88f28c9222..c8296be68c 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 @@ public class OIDCJWKSDataBinderImpl implements OIDCJWKSDataBinder { } @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 33479e83fa..92c6b8b191 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 javax.servlet.ServletResponse; 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 class MustChangePasswordFilter implements Filter { 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 6117375848..e9ffb1b855 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.ApplicationContext; 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 @@ public class WebSecurityContext { } @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) { - - return new WebSecurityConfigurerAdapter(true) { - - @Override - public void configure(final WebSecurity web) { - web.httpFirewall(allowUrlEncodedSlashHttpFirewall); - } - - @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); - - SyncopeBasicAuthenticationEntryPoint basicAuthenticationEntryPoint = - new SyncopeBasicAuthenticationEntryPoint(); - basicAuthenticationEntryPoint.setRealmName("Apache Syncope authentication"); - - JWTAuthenticationFilter jwtAuthenticationFilter = new JWTAuthenticationFilter( - authenticationManager(), - basicAuthenticationEntryPoint, - authenticationDetailsSource, - ctx.getBean(AuthDataAccessor.class), - ctx.getBean(DefaultCredentialChecker.class)); - - 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(); - } - - @Override - protected void configure(final AuthenticationManagerBuilder builder) throws Exception { - builder. - authenticationProvider(ctx.getBean(UsernamePasswordAuthenticationProvider.class)). - authenticationProvider(ctx.getBean(JWTAuthenticationProvider.class)); - } - }; + final ApplicationContext ctx) throws Exception { + + AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManagerBuilder.class). + authenticationProvider(usernamePasswordAuthenticationProvider). + authenticationProvider(jwtAuthenticationProvider). + build(); + + 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); + + SyncopeBasicAuthenticationEntryPoint basicAuthenticationEntryPoint = + new SyncopeBasicAuthenticationEntryPoint(); + basicAuthenticationEntryPoint.setRealmName("Apache Syncope authentication"); + + JWTAuthenticationFilter jwtAuthenticationFilter = new JWTAuthenticationFilter( + authenticationManager, + basicAuthenticationEntryPoint, + authenticationDetailsSource, + ctx.getBean(AuthDataAccessor.class), + ctx.getBean(DefaultCredentialChecker.class)); + + MustChangePasswordFilter mustChangePasswordFilter = new MustChangePasswordFilter(); + + 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(); + + 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 6ba3177c2a..39af643ccc 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.SyncopeClient; 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 @@ public class OIDCJWKSITCase extends AbstractITCase { 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 ddc3dff626..efbf265ab9 100644 --- a/fit/wa-reference/pom.xml +++ b/fit/wa-reference/pom.xml @@ -39,6 +39,18 @@ under the License. <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 9a4e18b502..6c49eeff0d 100644 --- a/pom.xml +++ b/pom.xml @@ -411,7 +411,7 @@ under the License. <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 @@ under the License. <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 @@ under the License. <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 @@ under the License. <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> @@ -1272,354 +1272,6 @@ under the License. <!-- PAC4J --> <!-- 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> @@ -2009,7 +1661,7 @@ under the License. <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 9ea1e97449..5fe2a70b71 100644 --- a/wa/bootstrap/pom.xml +++ b/wa/bootstrap/pom.xml @@ -48,6 +48,7 @@ under the License. <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 da16ba0fd7..b14c7fe137 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 @@ public class AuthModulePropertySourceMapper extends PropertySourceMapper impleme 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 0dd676a0b0..49f3b7c56f 100644 --- a/wa/pom.xml +++ b/wa/pom.xml @@ -36,6 +36,18 @@ under the License. <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 8abf4c0bcd..0c9e1608ec 100644 --- a/wa/starter/pom.xml +++ b/wa/starter/pom.xml @@ -64,19 +64,15 @@ under the License. </dependency> <dependency> <groupId>org.apereo.cas</groupId> - <artifactId>cas-server-core-authentication</artifactId> - </dependency> - <dependency> - <groupId>org.apereo.cas</groupId> - <artifactId>cas-server-core-configuration</artifactId> + <artifactId>cas-server-core-events-api</artifactId> </dependency> <dependency> <groupId>org.apereo.cas</groupId> - <artifactId>cas-server-core-audit-api</artifactId> + <artifactId>cas-server-core-authentication</artifactId> </dependency> <dependency> <groupId>org.apereo.cas</groupId> - <artifactId>cas-server-core-events-api</artifactId> + <artifactId>cas-server-core-configuration</artifactId> </dependency> <dependency> <groupId>org.apereo.cas</groupId> @@ -94,6 +90,10 @@ under the License. <groupId>org.apereo.cas</groupId> <artifactId>cas-server-core-services</artifactId> </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> @@ -118,10 +118,6 @@ under the License. <groupId>org.apereo.cas</groupId> <artifactId>cas-server-core-web</artifactId> </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> @@ -153,6 +149,12 @@ under the License. <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> @@ -170,6 +172,10 @@ under the License. <groupId>org.apereo.cas</groupId> <artifactId>cas-server-support-themes</artifactId> </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> @@ -218,22 +224,53 @@ under the License. <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> + <artifactId>cas-server-support-u2f</artifactId> </dependency> <dependency> <groupId>org.apereo.cas</groupId> - <artifactId>cas-server-support-webauthn-core</artifactId> + <artifactId>cas-server-support-u2f-core</artifactId> </dependency> <dependency> <groupId>org.apereo.cas</groupId> - <artifactId>cas-server-support-u2f</artifactId> + <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-u2f-core</artifactId> + <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> @@ -249,11 +286,11 @@ under the License. </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 @@ under the License. </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 @@ under the License. </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 @@ under the License. <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 5cd8a43e58..cda6bd0976 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.apache.syncope.wa.starter.config.WARefreshContextJob; 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 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; @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 6dfdf01a54..f4119a8065 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 @@ public class WAAuditTrailManager extends AbstractAuditTrailManager { } @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 76bea8a57d..9a91ba0260 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.commons.lang3.StringUtils; 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.configuration.model.support.mfa.u2f.U2FCoreMultifactorAuth 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 @@ public class WAContext { } @Bean - public OneTimeTokenRepository oneTimeTokenAuthenticatorTokenRepository( + public WAGoogleMfaAuthTokenRepository oneTimeTokenAuthenticatorTokenRepository( final CasConfigurationProperties casProperties, final WARestClient restClient) { @@ -290,7 +288,9 @@ public class WAContext { 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 @@ public class WAContext { 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 cb2b4fa0d5..e785ea29dd 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 class WAGoogleMfaAuthCredentialRepository extends BaseGoogleAuthenticator 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 @@ public class WAGoogleMfaAuthCredentialRepository extends BaseGoogleAuthenticator } @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 95f887cb05..74d33363b9 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 java.time.LocalDateTime; 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 @@ public class WAGoogleMfaAuthTokenRepository extends BaseOneTimeTokenRepository { } @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 @@ public class WAGoogleMfaAuthTokenRepository extends BaseOneTimeTokenRepository { } @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 ee62c2b43c..f9a9685c16 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.Map; 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 @@ import org.apereo.cas.services.RegisteredServiceProperty; 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 @@ abstract class AbstractClientAppMapper implements ClientAppMapper { } protected void setPolicies( - final RegexRegisteredService service, + final BaseWebBasedRegisteredService service, final RegisteredServiceAuthenticationPolicy authPolicy, final RegisteredServiceMultifactorPolicy mfaPolicy, final RegisteredServiceAccessStrategy accessStrategy, @@ -58,7 +58,7 @@ abstract class AbstractClientAppMapper implements ClientAppMapper { 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 e1146ef929..5d007d2a05 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 @@ package org.apache.syncope.wa.starter.mapping; 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 @@ public class CASSPClientAppTOMapper extends AbstractClientAppMapper { 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 ae508d6e96..f7eb0b3e57 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 @@ public class DefaultAttrReleaseMapper implements AttrReleaseMapper { 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 d90dd0d510..ac7e576c69 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 @@ public class SAML2SPClientAppTOMapper extends AbstractClientAppMapper { 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 e82f1ac992..bac970623d 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 javax.ws.rs.core.Response; 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 @@ import org.springframework.core.io.Resource; 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 @@ public class WAOIDCJWKSGeneratorService implements OidcJsonWebKeystoreGeneratorS } 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 24563344e6..20afed79cf 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 c3d2927772..0c37f9e86e 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 @@ package org.apache.syncope.wa.starter; 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 835ddbf663..b3089233da 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 @@ import org.springframework.beans.factory.annotation.Autowired; public class WAGoogleMfaAuthTokenRepositoryTest extends AbstractTest { @Autowired - private OneTimeTokenRepository tokenRepository; + private OneTimeTokenRepository<GoogleAuthenticatorToken> tokenRepository; @Test public void verifyOps() {