This is an automated email from the ASF dual-hosted git repository. ilgrosso pushed a commit to branch 4_0_X in repository https://gitbox.apache.org/repos/asf/syncope.git
commit 40f3850eefe8d5a3e09f4680c3b5291558b9b6f3 Author: Francesco Chicchiriccò <[email protected]> AuthorDate: Tue May 13 12:09:49 2025 +0200 [SYNCOPE-1881] Ensure to fetch the SP metadata value from the matching AuthModule instance --- .../console/wizards/AuthModuleWizardBuilder.java | 31 +++++++++- .../pac4j/saml/WASAML2ClientMetadataGenerator.java | 67 +++++++++++++++++++--- .../pac4j/saml/WASAML2MetadataResolver.java | 4 +- 3 files changed, 90 insertions(+), 12 deletions(-) diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder.java b/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder.java index 2dac0c7875..6afacdc038 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder.java @@ -19,6 +19,8 @@ package org.apache.syncope.client.console.wizards; import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.util.Base64; import java.util.List; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -205,8 +207,33 @@ public class AuthModuleWizardBuilder extends BaseAjaxWizardBuilder<AuthModuleTO> return pageRef; } }); - add(new XMLEditorPanel(null, - new PropertyModel<>(authModule, "conf.serviceProviderMetadata"), false, pageRef)); + add(new XMLEditorPanel(null, new IModel<String>() { + + private static final long serialVersionUID = -6439061267623081672L; + + @Override + public String getObject() { + SAML2IdPAuthModuleConf conf = (SAML2IdPAuthModuleConf) authModule.getConf(); + if (StringUtils.isEmpty(conf.getServiceProviderMetadata())) { + return null; + } + + return new String( + Base64.getDecoder().decode(conf.getServiceProviderMetadata()), + StandardCharsets.UTF_8); + } + + @Override + public void setObject(final String object) { + SAML2IdPAuthModuleConf conf = (SAML2IdPAuthModuleConf) authModule.getConf(); + if (StringUtils.isEmpty(object)) { + conf.setServiceProviderMetadata(null); + } else { + conf.setServiceProviderMetadata(Base64.getEncoder(). + encodeToString(object.getBytes(StandardCharsets.UTF_8))); + } + } + }, false, pageRef)); } @Override diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientMetadataGenerator.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientMetadataGenerator.java index 9f90207dca..eaadfdd8a2 100644 --- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientMetadataGenerator.java +++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientMetadataGenerator.java @@ -20,11 +20,13 @@ package org.apache.syncope.wa.starter.pac4j.saml; import java.nio.charset.StandardCharsets; import java.util.Base64; +import java.util.Optional; import org.apache.commons.io.IOUtils; import org.apache.syncope.common.rest.api.service.wa.WASAML2SPService; import org.apache.syncope.wa.bootstrap.WARestClient; import org.opensaml.saml.metadata.resolver.MetadataResolver; import org.opensaml.saml.metadata.resolver.impl.AbstractMetadataResolver; +import org.opensaml.saml.saml2.metadata.EntityDescriptor; import org.pac4j.saml.client.SAML2Client; import org.pac4j.saml.metadata.BaseSAML2MetadataGenerator; import org.slf4j.Logger; @@ -48,6 +50,52 @@ public class WASAML2ClientMetadataGenerator extends BaseSAML2MetadataGenerator { return true; } + protected Optional<String> metadataAvailable() { + try { + String encodedMetadata = waRestClient.getService(WASAML2SPService.class). + getSAML2SPMetadata(saml2Client.getName()).readEntity(String.class); + + LOG.debug("Retrieved metadata {}", encodedMetadata); + return Optional.of(new String(Base64.getDecoder().decode(encodedMetadata), StandardCharsets.UTF_8)); + } catch (Exception e) { + LOG.error("While attempting to read metadata for SP Entity {}", saml2Client.getName(), e); + return Optional.empty(); + } + } + + /** + * {@inheritDoc} + * + * @return {@code null} if metadata was found in Syncope Core via REST + */ + @Override + public EntityDescriptor buildEntityDescriptor() { + return metadataAvailable(). + map(m -> (EntityDescriptor) null). + orElseGet(() -> { + EntityDescriptor entityDescriptor = super.buildEntityDescriptor(); + entityDescriptor.setValidUntil(null); + if (signMetadata) { + signMetadata(entityDescriptor); + } + return entityDescriptor; + }); + } + + /** + * {@inheritDoc} + * + * return metadata from Syncope Core via REST, if available; otherwise, generate + */ + @Override + public String getMetadata(final EntityDescriptor entityDescriptor) throws Exception { + String metadata = metadataAvailable().orElse(null); + if (metadata == null) { + return super.getMetadata(entityDescriptor); + } + return metadata; + } + @Override protected AbstractMetadataResolver createMetadataResolver() { return new WASAML2MetadataResolver(waRestClient, saml2Client); @@ -55,15 +103,18 @@ public class WASAML2ClientMetadataGenerator extends BaseSAML2MetadataGenerator { @Override public MetadataResolver buildMetadataResolver() throws Exception { - String encodedMetadata = Base64.getEncoder().encodeToString( - getMetadata(buildEntityDescriptor()).getBytes(StandardCharsets.UTF_8)); - LOG.debug("Encoded SP metadata {}", encodedMetadata); + EntityDescriptor entityDescriptor = buildEntityDescriptor(); + if (entityDescriptor != null) { + String encodedMetadata = Base64.getEncoder().encodeToString( + getMetadata(entityDescriptor).getBytes(StandardCharsets.UTF_8)); + LOG.debug("Encoded SP metadata {}", encodedMetadata); - try { - waRestClient.getService(WASAML2SPService.class).setSAML2SPMetadata( - saml2Client.getName(), IOUtils.toInputStream(encodedMetadata, StandardCharsets.UTF_8)); - } catch (Exception e) { - LOG.error("While storing SP {} metadata", saml2Client.getName(), e); + try { + waRestClient.getService(WASAML2SPService.class).setSAML2SPMetadata( + saml2Client.getName(), IOUtils.toInputStream(encodedMetadata, StandardCharsets.UTF_8)); + } catch (Exception e) { + LOG.error("While storing SP {} metadata", saml2Client.getName(), e); + } } return super.buildMetadataResolver(); diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2MetadataResolver.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2MetadataResolver.java index 1788e31baf..da9b3ea7a0 100644 --- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2MetadataResolver.java +++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2MetadataResolver.java @@ -51,10 +51,10 @@ public class WASAML2MetadataResolver extends AbstractReloadingMetadataResolver { String encodedMetadata = waRestClient.getService(WASAML2SPService.class). getSAML2SPMetadata(saml2Client.getName()).readEntity(String.class); - LOG.debug("Retrieved keystore {}", encodedMetadata); + LOG.debug("Retrieved metadata {}", encodedMetadata); return Base64.getDecoder().decode(encodedMetadata); } catch (Exception e) { - String message = "Unable to fetch SP metadata for " + saml2Client.getName(); + String message = "Unable to fetch SP metadata for SP entity " + saml2Client.getName(); LOG.error(message, e); throw new ResolverException(message); }
