/******************************************************************************* * Cloud Foundry * Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved. * * This product is licensed to you under the Apache License, Version 2.0 (the "License"). * You may not use this product except in compliance with the License. * * This product includes a number of subcomponents with * separate copyright notices and license terms. Your use of these * subcomponents is subject to the terms and conditions of the * subcomponent's license, as noted in the LICENSE file. *******************************************************************************/ package org.cloudfoundry.identity.uaa.login.saml; import org.apache.commons.httpclient.HttpClient; import org.cloudfoundry.identity.uaa.config.YamlMapFactoryBean; import org.cloudfoundry.identity.uaa.config.YamlProcessor; import org.junit.Before; import org.junit.Test; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.Resource; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Timer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; public class IdentityProviderConfiguratorTests { IdentityProviderConfigurator conf = null; Map<String, Map<String, Object>> data = null; String sampleYaml = " providers:\n" + " okta-local:\n" + " idpMetadata: sample-okta-localhost.xml\n" + " nameID: urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\n" + " assertionConsumerIndex: 0\n" + " metadataTrustCheck: true\n" + " showSamlLoginLink: true\n" + " linkText: 'Okta Preview 1'\n" + " iconUrl: 'http://link.to/icon.jpg'\n" + " okta-local-2:\n" + " idpMetadata: |\n" + " <?xml version=\"1.0\" encoding=\"UTF-8\"?><md:EntityDescriptor xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\" entityID=\"http://www.okta.com/k2lw4l5bPODCMIIDBRYZ\"><md:IDPSSODescriptor WantAuthnRequestsSigned=\"true\" 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>MIICmTCCAgKgAwIBAgIGAUPATqmEMA0GCSqGSIb3DQEBBQUAMIGPMQswCQYDVQQGEwJVUzETMBEG\n" + " A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU\n" + " MBIGA1UECwwLU1NPUHJvdmlkZXIxEDAOBgNVBAMMB1Bpdm90YWwxHDAaBgkqhkiG9w0BCQEWDWlu\n" + " Zm9Ab2t0YS5jb20wHhcNMTQwMTIzMTgxMjM3WhcNNDQwMTIzMTgxMzM3WjCBjzELMAkGA1UEBhMC\n" + " VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNVBAoM\n" + " BE9rdGExFDASBgNVBAsMC1NTT1Byb3ZpZGVyMRAwDgYDVQQDDAdQaXZvdGFsMRwwGgYJKoZIhvcN\n" + " AQkBFg1pbmZvQG9rdGEuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeil67/TLOiTZU\n" + " WWgW2XEGgFZ94bVO90v5J1XmcHMwL8v5Z/8qjdZLpGdwI7Ph0CyXMMNklpaR/Ljb8fsls3amdT5O\n" + " Bw92Zo8ulcpjw2wuezTwL0eC0wY/GQDAZiXL59npE6U+fH1lbJIq92hx0HJSru/0O1q3+A/+jjZL\n" + " 3tL/SwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAI5BoWZoH6Mz9vhypZPOJCEKa/K+biZQsA4Zqsuk\n" + " vvphhSERhqk/Nv76Vkl8uvJwwHbQrR9KJx4L3PRkGCG24rix71jEuXVGZUsDNM3CUKnARx4MEab6\n" + " GFHNkZ6DmoT/PFagngecHu+EwmuDtaG0rEkFrARwe+d8Ru0BN558abFb</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat><md:SingleSignOnService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\" Location=\"https://pivotal.oktapreview.com/app/pivotal_pivotalcfstaging_1/k2lw4l5bPODCMIIDBRYZ/sso/saml\"/><md:SingleSignOnService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\" Location=\"https://pivotal.oktapreview.com/app/pivotal_pivotalcfstaging_1/k2lw4l5bPODCMIIDBRYZ/sso/saml\"/></md:IDPSSODescriptor></md:EntityDescriptor>\n" + " nameID: urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\n" + " assertionConsumerIndex: 0\n" + " metadataTrustCheck: true\n" + " showSamlLoginLink: true\n" + " linkText: 'Okta Preview 2'\n" + " vsphere.local:\n" + " idpMetadata: https://win2012-sso2.localdomain:7444/websso/SAML2/Metadata/vsphere.local\n" + " nameID: urn:oasis:names:tc:SAML:2.0:nameid-format:persistent\n" + " assertionConsumerIndex: 1\n" + " metadataTrustCheck: false\n"+ " showSamlLoginLink: false\n" + " linkText: 'Log in with vCenter SSO'\n" + " iconUrl: 'http://vsphere.local/iconurl.jpg'\n" + " openam-local:\n" + " idpMetadata: http://localhost:8081/openam/saml2/jsp/exportmetadata.jsp?entityid=http://localhost:8081/openam\n" + " nameID: urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\n" + " assertionConsumerIndex: 0\n" + " signMetaData: false\n" + " signRequest: false\n" + " showSamlLoginLink: true\n" + " linkText: 'Log in with OpenAM'\n" + " incomplete-provider:\n" + " idpMetadata: http://localhost:8081/openam/saml2/jsp/exportmetadata.jsp?entityid=http://localhost:8081/openam\n"; @Before public void setUp() throws Exception { conf = new IdentityProviderConfigurator(); parseYaml(sampleYaml); } private void parseYaml(String sampleYaml) { YamlMapFactoryBean factory = new YamlMapFactoryBean(); factory.setResolutionMethod(YamlProcessor.ResolutionMethod.OVERRIDE_AND_IGNORE); List<Resource> resources = new ArrayList<>(); ByteArrayResource resource = new ByteArrayResource(sampleYaml.getBytes()); resources.add(resource); factory.setResources(resources.toArray(new Resource[resources.size()])); Map<String, Object> tmpdata = factory.getObject(); data = new HashMap<>(); for (Map.Entry<String, Object> entry : ((Map<String, Object>)tmpdata.get("providers")).entrySet()) { data.put(entry.getKey(), (Map<String, Object>)entry.getValue()); } } @Test public void testGetIdentityProviderDefinitions() throws Exception { testGetIdentityProviderDefinitions(5); } protected void testGetIdentityProviderDefinitions(int count) throws Exception { conf.setIdentityProviders(data); List<IdentityProviderDefinition> idps = conf.getIdentityProviderDefinitions(); assertEquals(count, idps.size()); for (IdentityProviderDefinition idp : idps) { switch (idp.getIdpEntityAlias()) { case "vsphere.local" : { assertEquals(IdentityProviderDefinition.MetadataLocation.URL, idp.getType()); assertEquals("https://win2012-sso2.localdomain:7444/websso/SAML2/Metadata/vsphere.local", idp.getMetaDataLocation()); assertEquals("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", idp.getNameID()); assertEquals(1, idp.getAssertionConsumerIndex()); assertEquals("Log in with vCenter SSO", idp.getLinkText()); assertEquals("http://vsphere.local/iconurl.jpg", idp.getIconUrl()); assertFalse(idp.isShowSamlLink()); assertFalse(idp.isMetadataTrustCheck()); assertEquals("org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory", idp.getSocketFactoryClassName()); break; } case "okta-local" : { assertEquals(IdentityProviderDefinition.MetadataLocation.FILE, idp.getType()); assertEquals("sample-okta-localhost.xml", idp.getMetaDataLocation()); assertEquals("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", idp.getNameID()); assertEquals(0, idp.getAssertionConsumerIndex()); assertEquals("Okta Preview 1", idp.getLinkText()); assertEquals("http://link.to/icon.jpg", idp.getIconUrl()); assertTrue(idp.isShowSamlLink()); assertTrue(idp.isMetadataTrustCheck()); break; } case "okta-local-2" : { assertEquals(IdentityProviderDefinition.MetadataLocation.DATA, idp.getType()); assertEquals("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", idp.getNameID()); assertEquals(0, idp.getAssertionConsumerIndex()); assertEquals("Okta Preview 2", idp.getLinkText()); assertNull(idp.getIconUrl()); assertTrue(idp.isShowSamlLink()); assertTrue(idp.isMetadataTrustCheck()); break; } case "openam-local" : { assertEquals(IdentityProviderDefinition.MetadataLocation.URL, idp.getType()); assertEquals("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", idp.getNameID()); assertEquals(0, idp.getAssertionConsumerIndex()); assertEquals("Log in with OpenAM", idp.getLinkText()); assertNull(idp.getIconUrl()); assertTrue(idp.isShowSamlLink()); assertTrue(idp.isMetadataTrustCheck()); assertEquals("org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory", idp.getSocketFactoryClassName()); break; } case "vsphere.local.legacy" : assertEquals(IdentityProviderDefinition.MetadataLocation.URL, idp.getType()); assertEquals("http://win2012-sso2.localdomain:7444/websso/SAML2/Metadata/vsphere.local", idp.getMetaDataLocation()); assertEquals("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", idp.getNameID()); assertEquals(0, idp.getAssertionConsumerIndex()); assertEquals("Use your corporate credentials", idp.getLinkText()); assertNull(idp.getIconUrl()); assertTrue(idp.isShowSamlLink()); assertTrue(idp.isMetadataTrustCheck()); assertEquals("org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory", idp.getSocketFactoryClassName()); break; case "incomplete-provider" : assertTrue(idp.isShowSamlLink()); break; default: fail(); } } } @Test public void testGetIdentityProvidersWithLegacyProvider() throws Exception { conf.setLegacyIdpMetaData("http://win2012-sso2.localdomain:7444/websso/SAML2/Metadata/vsphere.local"); conf.setLegacyIdpIdentityAlias("vsphere.local.legacy"); conf.setLegacyNameId("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"); testGetIdentityProviderDefinitions(6); } @Test public void testGetIdentityProviders() throws Exception { conf.setLegacyIdpMetaData("http://win2012-sso2.localdomain:7444/websso/SAML2/Metadata/vsphere.local"); conf.setLegacyIdpIdentityAlias("vsphere.local.legacy"); conf.setLegacyNameId("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"); conf.setMetadataFetchingHttpClientTimer(new Timer()); conf.setHttpClient(new HttpClient()); testGetIdentityProviderDefinitions(6); conf.getIdentityProviders(); } @Test(expected = IllegalStateException.class) public void testDuplicateAlias() throws Exception { conf.setLegacyIdpMetaData("https://win2012-sso2.localdomain:7444/websso/SAML2/Metadata/vsphere.local"); conf.setLegacyIdpIdentityAlias("vsphere.local"); conf.setIdentityProviders(data); conf.getIdentityProviderDefinitions(); } }