Skip to content

Commit

Permalink
Merge pull request #3138 from cloudfoundry/new-saml-0530-remove-dummy
Browse files Browse the repository at this point in the history
Replace dummy-saml-idp-metadata
  • Loading branch information
duanemay authored Nov 15, 2024
2 parents 540cba4 + 64f189f commit c4fcd6d
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,6 @@ public static MetadataLocation getType(String urlOrXmlData) {
} catch (MalformedURLException e) {
//invalid URL
}
} else if (trimmedValue.startsWith("classpath:")) {
return MetadataLocation.URL;
}
return MetadataLocation.UNKNOWN;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
* but for non-default zones.
*/
public class DefaultRelyingPartyRegistrationRepository extends BaseUaaRelyingPartyRegistrationRepository {
public static final String CLASSPATH_DUMMY_SAML_IDP_METADATA_XML = "classpath:dummy-saml-idp-metadata.xml";

public DefaultRelyingPartyRegistrationRepository(String uaaWideSamlEntityID,
String uaaWideSamlEntityIDAlias,
Expand Down Expand Up @@ -50,7 +49,7 @@ public RelyingPartyRegistration findByRegistrationId(String registrationId) {
.samlEntityID(zonedSamlEntityID)
.samlSpNameId(uaaWideSamlNameId)
.keys(keyWithCerts)
.metadataLocation(CLASSPATH_DUMMY_SAML_IDP_METADATA_XML)
.metadataLocation(RelyingPartyRegistrationBuilder.createOwnMetadata(zonedSamlEntityID, keyWithCerts))
.rpRegistrationId(registrationId)
.samlSpAlias(zonedSamlEntityIDAlias)
.requestSigned(requestSigned)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.apache.commons.lang3.StringUtils;
import org.cloudfoundry.identity.uaa.provider.SamlIdentityProviderDefinition;
import org.cloudfoundry.identity.uaa.util.KeyWithCert;
import org.cloudfoundry.identity.uaa.util.UaaStringUtils;
import org.springframework.security.saml2.Saml2Exception;
import org.springframework.security.saml2.core.Saml2X509Credential;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
Expand All @@ -15,6 +16,7 @@

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.cert.CertificateException;
import java.util.List;
import java.util.function.UnaryOperator;

Expand All @@ -23,7 +25,6 @@
*/
@Slf4j
public class RelyingPartyRegistrationBuilder {
public static final String CLASSPATH_DUMMY_SAML_IDP_METADATA_XML = "classpath:dummy-saml-idp-metadata.xml";

private static final UnaryOperator<String> assertionConsumerServiceLocationFunction = "{baseUrl}/saml/SSO/alias/%s"::formatted;
private static final UnaryOperator<String> singleLogoutServiceResponseLocationFunction = "{baseUrl}/saml/SingleLogout/alias/%s"::formatted;
Expand All @@ -36,13 +37,13 @@ private RelyingPartyRegistrationBuilder() {
/**
* Build a RelyingPartyRegistration object from the given parameters
*
* @param params the params object used to build the RelyingPartyRegistration object
* @param builderParams the params object used to build the RelyingPartyRegistration object
* @return a RelyingPartyRegistration object
*/
public static RelyingPartyRegistration buildRelyingPartyRegistration(Params builderParams) {
final Params params;
if (StringUtils.isEmpty(builderParams.getMetadataLocation())) {
params = builderParams.withMetadataLocation(CLASSPATH_DUMMY_SAML_IDP_METADATA_XML);
params = builderParams.withMetadataLocation(createOwnMetadata(builderParams.samlEntityID, builderParams.keys));
} else {
params = builderParams;
}
Expand Down Expand Up @@ -88,6 +89,38 @@ public static RelyingPartyRegistration buildRelyingPartyRegistration(Params buil
}).build();
}

/**
* Create the metadata XML
* @param entityId entityID
* @param keyWithCerts Keys
* @return metadata XML
*/
public static String createOwnMetadata(String entityId, List<KeyWithCert> keyWithCerts) {
String certificate = keyWithCerts.stream().findFirst().map(e -> {
try {
return e.getEncodedCertificate();
} catch (CertificateException ex) {
return UaaStringUtils.EMPTY_STRING;
}
}).orElse(UaaStringUtils.EMPTY_STRING);

return """
<?xml version="1.0"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="%s">
<md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>%s</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:SingleSignOnService
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://www.cloudfoundry.org"/>
</md:IDPSSODescriptor>
</md:EntityDescriptor>""".formatted(entityId, certificate);
}

/**
* Parameters for building a {@link RelyingPartyRegistration} using {@link RelyingPartyRegistrationBuilder}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
@Slf4j
public class SamlRelyingPartyRegistrationRepositoryConfig {

public static final String CLASSPATH_DUMMY_SAML_IDP_METADATA_XML = "classpath:dummy-saml-idp-metadata.xml";

private final String samlEntityID;
private final SamlConfigProps samlConfigProps;
private final BootstrapSamlIdentityProviderData bootstrapSamlIdentityProviderData;
Expand Down Expand Up @@ -66,7 +64,7 @@ RelyingPartyRegistrationRepository relyingPartyRegistrationRepository(SamlIdenti
.samlEntityID(samlEntityID)
.samlSpNameId(samlSpNameID)
.keys(defaultKeysWithCerts)
.metadataLocation(CLASSPATH_DUMMY_SAML_IDP_METADATA_XML)
.metadataLocation(RelyingPartyRegistrationBuilder.createOwnMetadata(samlEntityID, defaultKeysWithCerts))
.rpRegistrationId(DEFAULT_REGISTRATION_ID)
.samlSpAlias(uaaWideSamlEntityIDAlias)
.requestSigned(samlConfigProps.getSignRequest())
Expand Down
16 changes: 0 additions & 16 deletions server/src/main/resources/dummy-saml-idp-metadata.xml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class DefaultRelyingPartyRegistrationRepositoryTest {
private static final String REGISTRATION_ID = "registrationId";
private static final String REGISTRATION_ID_2 = "registrationId2";

private static final SamlConfigProps samlConfigProps = new SamlConfigProps();
private static final SamlConfigProps samlConfigProps = Saml2TestUtils.createTestSamlProperties();

@Mock
private IdentityZone identityZone;
Expand Down Expand Up @@ -79,7 +79,7 @@ void findByRegistrationId() {
.returns("{baseUrl}/saml/SingleLogout/alias/entityIdAlias", RelyingPartyRegistration::getSingleLogoutServiceResponseLocation)
// from xml
.extracting(RelyingPartyRegistration::getAssertingPartyDetails)
.returns("exampleEntityId", RelyingPartyRegistration.AssertingPartyDetails::getEntityId);
.returns("entityId", RelyingPartyRegistration.AssertingPartyDetails::getEntityId);
}

@Test
Expand All @@ -102,7 +102,7 @@ void findByRegistrationIdForZone() {
.returns("{baseUrl}/saml/SingleLogout/alias/testzone.entityIdAlias", RelyingPartyRegistration::getSingleLogoutServiceResponseLocation)
// from xml
.extracting(RelyingPartyRegistration::getAssertingPartyDetails)
.returns("exampleEntityId", RelyingPartyRegistration.AssertingPartyDetails::getEntityId)
.returns("testzone.entityId", RelyingPartyRegistration.AssertingPartyDetails::getEntityId)
// signature algorithm defaults to SHA256
.extracting(RelyingPartyRegistration.AssertingPartyDetails::getSigningAlgorithms)
.isEqualTo(List.of(ALGO_ID_SIGNATURE_RSA_SHA256));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ void beforeEach() {
);
SamlRelyingPartyRegistrationRepositoryConfig samlRelyingPartyRegistrationRepositoryConfig =
new SamlRelyingPartyRegistrationRepositoryConfig(
"integration-saml-entity-id", new SamlConfigProps(),
"integration-saml-entity-id", Saml2TestUtils.createTestSamlProperties(),
new BootstrapSamlIdentityProviderData(identityProviderConfigurator),
"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
List.of(SignatureAlgorithm.SHA256, SignatureAlgorithm.SHA512));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.cloudfoundry.identity.uaa.provider.saml;

import net.shibboleth.utilities.java.support.xml.SerializeSupport;
import org.cloudfoundry.identity.uaa.saml.SamlKey;
import org.opensaml.core.xml.XMLObject;
import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
import org.opensaml.core.xml.io.Marshaller;
Expand Down Expand Up @@ -67,6 +68,55 @@ public final class Saml2TestUtils {

private static final String ASSERTING_PARTY_ENTITY_ID = "https://some.idp.test/saml2/idp";

private static final String PRIVATE_KEY = """
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA0iq1SNMD4EHTO/33gxXn6ptjyitcAbA0cq4CufABS7KZjVm9
/Khvn4NlejfqZe02Md7vwTqoImdnyKFoIzUwPGDki2Gy6/Cm0raLbuIfDH1ba0Rq
2fNs8AWpk1wP3IcBGvU18EsirS7SOuGieAmKk/2UPeeau0RPwpZ7sEsoOJteYOuO
eJ3JYOufxUOSCw2moISEu+EcsjZw1Fhs9htbyr1ImRJOzArHczecyL6X45Hrrimv
hIenxjCwYROtf80RhT6R7LNOPIzhd212FmZLnbYf2pavtW1dyZTAjljQu4wUjDFB
DzJjvGfS1v36WiraXv8qJgN8PwV3GUMLitHmMQIDAQABAoIBAQDCN0tt7+rOC6Z7
8xcO4Wh/CnguNOGCgeYF8D5+u4dG/9YcpMkIOlNk0lUtm4yWAp8peP6Qz3bezDZB
Vr9YgeeAdH3fPDrPBIX1hVHW90mADjw0JXak0Opj6KerkNDrlyrzUZU16Qkzh2gp
l6e/S/nvBtA+YNBBrEAU72GAKgQSQf09Km0x9+eHO2zvmxGoALJeHBEr9wfCxP63
xWTbJYnkVX41chHlsk0TntTFPgvwtm4U468AjnOBrmWwoECbzDAa1uuMgpL4M5UH
Y2BW7TgBY22Yv0WMNTIq0SlIF7LY8HSe6BPCGLkBo2p5HARZaXI+N6XjA5cltXmn
469oBj9tAoGBAOoaMiZOFLAlVDLMhon5QLNRqePs+p37uV17Ogr4YIh/WJMl+7I0
y70cygxBv61PZcb4bgfOtVsAPXm1wgwbFhZzR++dnWXi6e03VMGA9yM6S7/PFt8U
vQvTnxDIc06xutTja7Bf/L6Z2ahEDHhVkDxmcA9fMQqCoaU1p69YJmRvAoGBAOXT
WpS8/PRThDv/WF5Zz3FalhpfWVGF1jiUnyoLYZ9s7LGDtS2E0eVY8YWAxBRz175i
ro5cIYn+DAmEKhTkT9vza0J2yySAWFi1n1UXGF1wW1XnUidTYur8mD+P2rd4HZLD
zOvsbV1vXd0mZWbkOMWYphUHg6o5bAtJOPvdoe9fAoGBAMdg2CVXircak8NP/aW0
6y3N92tvgWLb6Nt8/8ooD88w5jcsuljkLkE6K7qUpLLuVDhJjSyJGFwQsErgSgwV
ZZJpTHL/QfZsc97cqQrE07blB26s6UXFW9yet3KLxejX5c86gZUNqyyJy55LlnNG
LDnE5NuyrwnMh+8060OjR89xAoGAbjHDqbNf2co9igLpnPuU4jXb6LM1AUiZqTFh
i2g/m5A/gPG0qimX9k6KJ0fRPDk7BXcNWQbFsgNURC/ReYjq3Xw+PnT0/ABp28bh
qYvUS+D2eh7ani52LFOGsFtKNFPsYhVtqOUInxcpu0KQth/RNLT3VPfwYmr76gFm
yCTBYyMCgYBKowVroyYpaoCd/I0+zXkw2tU982U9pZpjMQJUIDYpKOjppicuzF6C
m2aVwkGNZlbk7EJnR9hQQZtitpi2Z6l4UkfNa70AxlViLdHvgvSRN+OrV3T7Rd7F
R7nO/5euJjEyRK4v1cOvGxlHGtQCN/cknWBeDakT7Rzd8OvsNnY9SQ==
-----END RSA PRIVATE KEY-----""";

private static final String CERTIFICATE = """
-----BEGIN CERTIFICATE-----
MIIC5zCCAc8CFC/HOKAyFrw/UMS9PB3nmVsJ/+c+MA0GCSqGSIb3DQEBCwUAMDAx
CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTb21lLVN0YXRlMQwwCgYDVQQKDANVQUEw
HhcNMjIxMTIzMTQxNTE4WhcNMjUwODIwMTQxNTE4WjAwMQswCQYDVQQGEwJVUzET
MBEGA1UECAwKU29tZS1TdGF0ZTEMMAoGA1UECgwDVUFBMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEA0iq1SNMD4EHTO/33gxXn6ptjyitcAbA0cq4CufAB
S7KZjVm9/Khvn4NlejfqZe02Md7vwTqoImdnyKFoIzUwPGDki2Gy6/Cm0raLbuIf
DH1ba0Rq2fNs8AWpk1wP3IcBGvU18EsirS7SOuGieAmKk/2UPeeau0RPwpZ7sEso
OJteYOuOeJ3JYOufxUOSCw2moISEu+EcsjZw1Fhs9htbyr1ImRJOzArHczecyL6X
45HrrimvhIenxjCwYROtf80RhT6R7LNOPIzhd212FmZLnbYf2pavtW1dyZTAjljQ
u4wUjDFBDzJjvGfS1v36WiraXv8qJgN8PwV3GUMLitHmMQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQCAExiglWf/gCbpcsBE+kodih5V0yJQsyf0net7VehSJt2sKxHq
P+D05RQMAlet6osHrMDVkG0cAB4UlBpcywPHRBajijSwzEXDZP41EhNLKHKnzRPE
iNbUeoCfjeecb6uATbSVTsiKM4IycWbYxwyIxw/lTEyVTP1xw/Hy1zg5q/HUFd3q
y0J9KAmGP/z1zEOq4q2AGVIF/pf5GnkiQ4JqMJmwdKLAksGJs5TK1a9yTBm/PkKC
BvQqCT8e8aJ4m2NJ0zpXcn8ObDZE3lpe4WSF+yS29AM/36FWLPQlCuhNTDJBx/nt
eFWGllY+4er+Ml08PVUZLxr/n44ZOixrA633
-----END CERTIFICATE-----""";

private Saml2TestUtils() {
throw new java.lang.UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
Expand Down Expand Up @@ -215,4 +265,11 @@ public static Map<String, String> xmlNamespaces() {
"saml", "urn:oasis:names:tc:SAML:2.0:assertion"
);
}

public static SamlConfigProps createTestSamlProperties() {
SamlConfigProps samlConfigProps = new SamlConfigProps();
samlConfigProps.setActiveKeyId("1");
samlConfigProps.setKeys(Map.of("1", new SamlKey(PRIVATE_KEY, "", CERTIFICATE)));
return samlConfigProps;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ class SamlRelyingPartyRegistrationRepositoryConfigTest {
private static final String ENTITY_ID = "entityId";
private static final String NAME_ID = "nameIdFormat";

@Mock
SamlConfigProps samlConfigProps;
private static SamlConfigProps samlConfigProps;

@Mock
BootstrapSamlIdentityProviderData bootstrapSamlIdentityProviderData;
Expand All @@ -32,6 +31,7 @@ class SamlRelyingPartyRegistrationRepositoryConfigTest {
@BeforeAll
public static void beforeAll() {
Security.addProvider(new BouncyCastleFipsProvider());
samlConfigProps = Saml2TestUtils.createTestSamlProperties();
}

@Test
Expand Down Expand Up @@ -67,6 +67,6 @@ void buildsRegistrationForExample() {
.returns("{baseUrl}/saml/SingleLogout/alias/entityId", RelyingPartyRegistration::getSingleLogoutServiceResponseLocation)
// from xml
.extracting(RelyingPartyRegistration::getAssertingPartyDetails)
.returns("exampleEntityId", RelyingPartyRegistration.AssertingPartyDetails::getEntityId);
.returns("entityId", RelyingPartyRegistration.AssertingPartyDetails::getEntityId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ void legacyDeprecatedProperties() {
@Test
void legacySamlIdpAsTopLevelElement() {
System.setProperty(LOGIN_SAML_METADATA_TRUST_CHECK, "false");
System.setProperty(LOGIN_IDP_METADATA_URL, "classpath:sample-okta-localhost.xml");
System.setProperty(LOGIN_IDP_METADATA, loadResouceAsString("sample-okta-localhost.xml"));
System.setProperty(LOGIN_IDP_ENTITY_ALIAS, "testIDPFile");

context = getServletContext("default", "uaa.yml");
Expand All @@ -191,7 +191,7 @@ void legacySamlIdpAsTopLevelElement() {
.returns(false, BootstrapSamlIdentityProviderData::isLegacyMetadataTrustCheck);
List<SamlIdentityProviderDefinition> defs = context.getBean(BootstrapSamlIdentityProviderData.class).getIdentityProviderDefinitions();
assertThat(providerByAlias(defs, "testIDPFile"))
.returns(SamlIdentityProviderDefinition.MetadataLocation.URL, SamlIdentityProviderDefinition::getType);
.returns(SamlIdentityProviderDefinition.MetadataLocation.DATA, SamlIdentityProviderDefinition::getType);
}

@Test
Expand Down

0 comments on commit c4fcd6d

Please sign in to comment.