Skip to content

Commit

Permalink
Adding temporary classes to resolve NoSuchMethodError for BasicSignat…
Browse files Browse the repository at this point in the history
…ureSigningConfiguration.setSigningCredentials
  • Loading branch information
ilgrosso committed Jun 16, 2023
1 parent 7e76aa8 commit 6abf7e0
Show file tree
Hide file tree
Showing 7 changed files with 291 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,13 @@ public SAML2Client add(
cfg.setServiceProviderEntityId(spEntityID);
getSPMetadataPath(spEntityID).ifPresent(cfg::setServiceProviderMetadataResourceFilepath);

SAML2Client saml2Client = new SAML2Client(cfg);
SAML2Client saml2Client = new SAML2Client(cfg) {

@Override
protected void initSignatureSigningParametersProvider() {
signatureSigningParametersProvider = new SAML2SP4UISignatureSigningParametersProvider(configuration);
}
};
saml2Client.setCallbackUrlResolver(new NoParameterCallbackUrlResolver());
saml2Client.setCallbackUrl(callbackUrl);
saml2Client.init();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.syncope.core.logic.saml2;

import java.util.List;
import java.util.Optional;
import org.opensaml.xmlsec.SignatureSigningConfiguration;
import org.opensaml.xmlsec.config.impl.DefaultSecurityConfigurationBootstrap;
import org.opensaml.xmlsec.impl.BasicSignatureSigningConfiguration;
import org.pac4j.saml.config.SAML2Configuration;
import org.pac4j.saml.crypto.DefaultSignatureSigningParametersProvider;

public class SAML2SP4UISignatureSigningParametersProvider extends DefaultSignatureSigningParametersProvider {

protected final SAML2Configuration configuration;

public SAML2SP4UISignatureSigningParametersProvider(final SAML2Configuration configuration) {
super(configuration);
this.configuration = configuration;
}

@Override
protected SignatureSigningConfiguration getSignatureSigningConfiguration() {
BasicSignatureSigningConfiguration ssc =
DefaultSecurityConfigurationBootstrap.buildDefaultSignatureSigningConfiguration();

Optional.ofNullable(configuration.getBlackListedSignatureSigningAlgorithms()).
ifPresent(ssc::setExcludedAlgorithms);

Optional.ofNullable(configuration.getSignatureAlgorithms()).
ifPresent(ssc::setSignatureAlgorithms);

Optional.ofNullable(configuration.getSignatureCanonicalizationAlgorithm()).
ifPresent(ssc::setSignatureCanonicalizationAlgorithm);

Optional.ofNullable(configuration.getSignatureReferenceDigestMethods()).
ifPresent(ssc::setSignatureReferenceDigestMethods);

ssc.setSigningCredentials(List.of(configuration.getCredentialProvider().getCredential()));
return ssc;
}
}
9 changes: 8 additions & 1 deletion sra/src/main/java/org/apache/syncope/sra/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.apache.syncope.sra.security.saml2.SAML2MetadataEndpoint;
import org.apache.syncope.sra.security.saml2.SAML2SecurityConfigUtils;
import org.apache.syncope.sra.security.saml2.SAML2WebSsoAuthenticationWebFilter;
import org.apache.syncope.sra.security.saml2.SRASignatureSigningParametersProvider;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.pac4j.core.http.callback.NoParameterCallbackUrlResolver;
import org.pac4j.saml.client.SAML2Client;
Expand Down Expand Up @@ -293,7 +294,13 @@ public InputStream retrieve() throws Exception {

cfg.setSessionLogoutHandler(new NoOpSessionLogoutHandler());

SAML2Client saml2Client = new SAML2Client(cfg);
SAML2Client saml2Client = new SAML2Client(cfg) {

@Override
protected void initSignatureSigningParametersProvider() {
signatureSigningParametersProvider = new SRASignatureSigningParametersProvider(configuration);
}
};
saml2Client.setName(SRAProperties.AMType.SAML2.name());
saml2Client.setCallbackUrl(props.getSaml2().getEntityId()
+ SAML2WebSsoAuthenticationWebFilter.FILTER_PROCESSES_URI);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.syncope.sra.security.saml2;

import java.util.List;
import java.util.Optional;
import org.opensaml.xmlsec.SignatureSigningConfiguration;
import org.opensaml.xmlsec.config.impl.DefaultSecurityConfigurationBootstrap;
import org.opensaml.xmlsec.impl.BasicSignatureSigningConfiguration;
import org.pac4j.saml.config.SAML2Configuration;
import org.pac4j.saml.crypto.DefaultSignatureSigningParametersProvider;

public class SRASignatureSigningParametersProvider extends DefaultSignatureSigningParametersProvider {

protected final SAML2Configuration configuration;

public SRASignatureSigningParametersProvider(final SAML2Configuration configuration) {
super(configuration);
this.configuration = configuration;
}

@Override
protected SignatureSigningConfiguration getSignatureSigningConfiguration() {
BasicSignatureSigningConfiguration ssc =
DefaultSecurityConfigurationBootstrap.buildDefaultSignatureSigningConfiguration();

Optional.ofNullable(configuration.getBlackListedSignatureSigningAlgorithms()).
ifPresent(ssc::setExcludedAlgorithms);

Optional.ofNullable(configuration.getSignatureAlgorithms()).
ifPresent(ssc::setSignatureAlgorithms);

Optional.ofNullable(configuration.getSignatureCanonicalizationAlgorithm()).
ifPresent(ssc::setSignatureCanonicalizationAlgorithm);

Optional.ofNullable(configuration.getSignatureReferenceDigestMethods()).
ifPresent(ssc::setSignatureReferenceDigestMethods);

ssc.setSigningCredentials(List.of(configuration.getCredentialProvider().getCredential()));
return ssc;
}
}
4 changes: 4 additions & 0 deletions wa/starter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ under the License.
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-saml-idp-core</artifactId>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-saml-idp-web</artifactId>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-oidc</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import org.apache.syncope.wa.starter.oidc.WAOIDCJWKSGeneratorService;
import org.apache.syncope.wa.starter.pac4j.saml.WASAML2ClientCustomizer;
import org.apache.syncope.wa.starter.saml.idp.WASamlIdPCasEventListener;
import org.apache.syncope.wa.starter.saml.idp.WASamlIdPObjectSigner;
import org.apache.syncope.wa.starter.saml.idp.metadata.WASamlIdPMetadataGenerator;
import org.apache.syncope.wa.starter.saml.idp.metadata.WASamlIdPMetadataLocator;
import org.apache.syncope.wa.starter.services.WAServiceRegistry;
Expand Down Expand Up @@ -89,11 +90,13 @@
import org.apereo.cas.support.saml.idp.metadata.generator.SamlIdPMetadataGeneratorConfigurationContext;
import org.apereo.cas.support.saml.idp.metadata.locator.SamlIdPMetadataLocator;
import org.apereo.cas.support.saml.services.idp.metadata.SamlIdPMetadataDocument;
import org.apereo.cas.support.saml.web.idp.profile.builders.enc.SamlIdPObjectSigner;
import org.apereo.cas.util.DateTimeUtils;
import org.apereo.cas.util.LdapUtils;
import org.apereo.cas.util.crypto.CipherExecutor;
import org.apereo.cas.webauthn.storage.WebAuthnCredentialRepository;
import org.ldaptive.ConnectionFactory;
import org.opensaml.saml.metadata.resolver.MetadataResolver;
import org.pac4j.core.client.Client;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
Expand Down Expand Up @@ -259,10 +262,19 @@ public SamlIdPMetadataLocator samlIdPMetadataLocator(
final Cache<String, SamlIdPMetadataDocument> samlIdPMetadataCache,
final WARestClient waRestClient) {

return new WASamlIdPMetadataLocator(
cipherExecutor,
samlIdPMetadataCache,
waRestClient);
return new WASamlIdPMetadataLocator(cipherExecutor, samlIdPMetadataCache, waRestClient);
}

@Bean
@RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)
public SamlIdPObjectSigner samlObjectSigner(
final CasConfigurationProperties casProperties,
@Qualifier("casSamlIdPMetadataResolver")
final MetadataResolver casSamlIdPMetadataResolver,
@Qualifier("samlIdPMetadataLocator")
final SamlIdPMetadataLocator samlIdPMetadataLocator) {

return new WASamlIdPObjectSigner(casSamlIdPMetadataResolver, casProperties, samlIdPMetadataLocator);
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.syncope.wa.starter.saml.idp;

import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.Objects;
import java.util.regex.Pattern;
import net.shibboleth.shared.resolver.CriteriaSet;
import org.apache.commons.lang3.StringUtils;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.support.saml.SamlIdPUtils;
import org.apereo.cas.support.saml.idp.metadata.locator.SamlIdPMetadataCredentialResolver;
import org.apereo.cas.support.saml.idp.metadata.locator.SamlIdPMetadataLocator;
import org.apereo.cas.support.saml.idp.metadata.locator.SamlIdPSamlRegisteredServiceCriterion;
import org.apereo.cas.support.saml.services.SamlRegisteredService;
import org.apereo.cas.support.saml.web.idp.profile.builders.enc.DefaultSamlIdPObjectSigner;
import org.apereo.cas.util.DigestUtils;
import org.apereo.cas.util.RegexUtils;
import org.opensaml.core.criterion.EntityIdCriterion;
import org.opensaml.saml.criterion.EntityRoleCriterion;
import org.opensaml.saml.metadata.criteria.entity.impl.EvaluableEntityRoleEntityDescriptorCriterion;
import org.opensaml.saml.metadata.resolver.MetadataResolver;
import org.opensaml.saml.saml2.metadata.IDPSSODescriptor;
import org.opensaml.security.credential.AbstractCredential;
import org.opensaml.security.credential.Credential;
import org.opensaml.security.credential.UsageType;
import org.opensaml.security.criteria.UsageCriterion;
import org.opensaml.xmlsec.SignatureSigningConfiguration;
import org.opensaml.xmlsec.config.impl.DefaultSecurityConfigurationBootstrap;
import org.opensaml.xmlsec.criterion.SignatureSigningConfigurationCriterion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WASamlIdPObjectSigner extends DefaultSamlIdPObjectSigner {

protected static final Logger LOG = LoggerFactory.getLogger(WASamlIdPObjectSigner.class);

protected static boolean doesCredentialFingerprintMatch(
final AbstractCredential credential,
final SamlRegisteredService samlRegisteredService) {

var fingerprint = samlRegisteredService.getSigningCredentialFingerprint();
if (StringUtils.isNotBlank(fingerprint)) {
var digest = DigestUtils.digest("SHA-1", Objects.requireNonNull(credential.getPublicKey()).getEncoded());
var pattern = RegexUtils.createPattern(fingerprint, Pattern.CASE_INSENSITIVE);
LOG.debug("Matching credential fingerprint [{}] against filter [{}] for service [{}]",
digest, fingerprint, samlRegisteredService.getName());
return pattern.matcher(digest).find();
}
return true;
}

protected final MetadataResolver samlIdPMetadataResolver;

protected final CasConfigurationProperties casProperties;

protected final SamlIdPMetadataLocator samlIdPMetadataLocator;

public WASamlIdPObjectSigner(
final MetadataResolver samlIdPMetadataResolver,
final CasConfigurationProperties casProperties,
final SamlIdPMetadataLocator samlIdPMetadataLocator) {

super(samlIdPMetadataResolver, casProperties, samlIdPMetadataLocator);
this.samlIdPMetadataResolver = samlIdPMetadataResolver;
this.casProperties = casProperties;
this.samlIdPMetadataLocator = samlIdPMetadataLocator;
}

@Override
protected SignatureSigningConfiguration getSignatureSigningConfiguration(final SamlRegisteredService service)
throws Exception {

var config = configureSignatureSigningSecurityConfiguration(service);

var samlIdp = casProperties.getAuthn().getSamlIdp();
var privateKey = getSigningPrivateKey(service);

var mdCredentialResolver = new SamlIdPMetadataCredentialResolver();
var roleDescriptorResolver = SamlIdPUtils.getRoleDescriptorResolver(
samlIdPMetadataResolver,
samlIdp.getMetadata().getCore().isRequireValidMetadata());
mdCredentialResolver.setRoleDescriptorResolver(roleDescriptorResolver);
mdCredentialResolver.setKeyInfoCredentialResolver(
DefaultSecurityConfigurationBootstrap.buildBasicInlineKeyInfoCredentialResolver());
mdCredentialResolver.initialize();

var criteriaSet = new CriteriaSet();
criteriaSet.add(new SignatureSigningConfigurationCriterion(config));
criteriaSet.add(new UsageCriterion(UsageType.SIGNING));

var entityIdCriteriaSet = new CriteriaSet(
new EvaluableEntityRoleEntityDescriptorCriterion(IDPSSODescriptor.DEFAULT_ELEMENT_NAME),
new SamlIdPSamlRegisteredServiceCriterion(service));
LOG.trace("Resolving entity id from SAML2 IdP metadata for signature signing configuration is [{}]", service.
getName());
var entityId = Objects.requireNonNull(samlIdPMetadataResolver.resolveSingle(entityIdCriteriaSet)).getEntityID();
LOG.trace("Resolved entity id from SAML2 IdP metadata is [{}]", entityId);
criteriaSet.add(new EntityIdCriterion(entityId));
criteriaSet.add(new EntityRoleCriterion(IDPSSODescriptor.DEFAULT_ELEMENT_NAME));
criteriaSet.add(new SamlIdPSamlRegisteredServiceCriterion(service));

LOG.trace("Resolved signing credentials based on criteria [{}]", criteriaSet);
var credentials = Sets.newLinkedHashSet(mdCredentialResolver.resolve(criteriaSet));
LOG.trace("Resolved [{}] signing credentials", credentials.size());

var finalCredentials = new ArrayList<Credential>();
credentials.stream()
.map(creds -> getResolvedSigningCredential(creds, privateKey, service))
.filter(Objects::nonNull)
.filter(creds -> doesCredentialFingerprintMatch(creds, service))
.forEach(finalCredentials::add);

if (finalCredentials.isEmpty()) {
LOG.error("Unable to locate any signing credentials for service [{}]", service.getName());
throw new IllegalArgumentException("Unable to locate signing credentials");
}

config.setSigningCredentials(finalCredentials);
LOG.trace("Signature signing credentials configured with [{}] credentials", finalCredentials.size());
return config;
}
}

0 comments on commit 6abf7e0

Please sign in to comment.