/*******************************************************************************
* Cloud Foundry
* Copyright (c) [2009-2016] 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.provider.saml;
import org.cloudfoundry.identity.uaa.impl.config.YamlMapFactoryBean;
import org.cloudfoundry.identity.uaa.impl.config.YamlProcessor;
import org.cloudfoundry.identity.uaa.provider.AbstractIdentityProviderDefinition;
import org.cloudfoundry.identity.uaa.provider.SamlIdentityProviderDefinition;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class BootstrapSamlIdentityProviderConfiguratorTests {
public static final String testXmlFileData = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><md:EntityDescriptor xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\" entityID=\"http://www.okta.com/k2lvtem0VAJDMINKEYJW\"><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_pivotalcfdevelopment_1/k2lvtem0VAJDMINKEYJW/sso/saml\"/><md:SingleSignOnService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\" Location=\"https://pivotal.oktapreview.com/app/pivotal_pivotalcfdevelopment_1/k2lvtem0VAJDMINKEYJW/sso/saml\"/></md:IDPSSODescriptor></md:EntityDescriptor>";
public static final String testXmlFileData2 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!--\n" +
" ~ ******************************************************************************\n" +
" ~ Cloud Foundry\n" +
" ~ Copyright (c) [2009-2015] Pivotal Software, Inc. All Rights Reserved.\n" +
" ~ This product is licensed to you under the Apache License, Version 2.0 (the \"License\").\n" +
" ~ You may not use this product except in compliance with the License.\n" +
" ~\n" +
" ~ This product includes a number of subcomponents with\n" +
" ~ separate copyright notices and license terms. Your use of these\n" +
" ~ subcomponents is subject to the terms and conditions of the\n" +
" ~ subcomponent's license, as noted in the LICENSE file.\n" +
" ~ ******************************************************************************\n" +
" -->\n" +
"\n" +
"<md:EntityDescriptor xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\" entityID=\"http://www.okta.com/k2lvtem0VAJDMINKEYJX\"><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_pivotalcfdevelopment_1/k2lvtem0VAJDMINKEYJW/sso/saml\"/><md:SingleSignOnService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\" Location=\"https://pivotal.oktapreview.com/app/pivotal_pivotalcfdevelopment_1/k2lvtem0VAJDMINKEYJW/sso/saml\"/></md:IDPSSODescriptor></md:EntityDescriptor>";
public static final String xmlWithoutID =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><md:EntityDescriptor xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\" entityID=\"%s\"><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";
public static final String xml = String.format(xmlWithoutID, "http://www.okta.com/k2lw4l5bPODCMIIDBRYZ");
BootstrapSamlIdentityProviderConfigurator bootstrap = null;
SamlIdentityProviderDefinition singleAdd = null;
public static final String singleAddAlias = "sample-alias";
public static String sampleYaml = " providers:\n" +
" okta-local:\n" +
" storeCustomAttributes: true\n" +
" idpMetadata: |\n" +
" " + testXmlFileData.replace("\n","\n ") + "\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" +
" "+ AbstractIdentityProviderDefinition.EMAIL_DOMAIN_ATTR+":\n" +
" - test.org\n" +
" - test.com\n" +
" externalGroupsWhitelist:\n" +
" - admin\n" +
" - user\n" +
" attributeMappings:\n" +
" given_name: first_name\n" +
" external_groups:\n" +
" - roles\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" +
" simplesamlphp-url:\n" +
" assertionConsumerIndex: 0\n" +
" idpMetadata: http://simplesamlphp.identity.cf-app.com/saml2/idp/metadata.php\n" +
" metadataTrustCheck: false\n" +
" nameID: urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\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 {
bootstrap = new BootstrapSamlIdentityProviderConfigurator();
singleAdd = new SamlIdentityProviderDefinition()
.setMetaDataLocation(String.format(BootstrapSamlIdentityProviderConfiguratorTests.xmlWithoutID, new RandomValueStringGenerator().generate()))
.setIdpEntityAlias(singleAddAlias)
.setNameID("sample-nameID")
.setAssertionConsumerIndex(1)
.setMetadataTrustCheck(true)
.setLinkText("sample-link-test")
.setIconUrl("sample-icon-url")
.setZoneId("uaa");
}
public static Map<String, Map<String, Object>> 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();
Map<String, Map<String, Object>> dataMap = new HashMap<>();
for (Map.Entry<String, Object> entry : ((Map<String, Object>)tmpdata.get("providers")).entrySet()) {
dataMap.put(entry.getKey(), (Map<String, Object>)entry.getValue());
}
return Collections.unmodifiableMap(dataMap);
}
private Map<String, Map<String, Object>> sampleData = parseYaml(sampleYaml);
@Test
public void testCloneIdentityProviderDefinition() throws Exception {
SamlIdentityProviderDefinition clone = singleAdd.clone();
assertEquals(singleAdd, clone);
assertNotSame(singleAdd, clone);
}
@Test
public void testAddProviderDefinition() throws Exception {
bootstrap.setIdentityProviders(sampleData);
bootstrap.afterPropertiesSet();
testGetIdentityProviderDefinitions(3, false);
}
@Test
public void testGetIdentityProviderDefinitions() throws Exception {
testGetIdentityProviderDefinitions(3);
}
protected void testGetIdentityProviderDefinitions(int count) throws Exception {
testGetIdentityProviderDefinitions(count, true);
}
protected void testGetIdentityProviderDefinitions(int count, boolean addData) throws Exception {
if (addData) {
bootstrap.setIdentityProviders(sampleData);
bootstrap.afterPropertiesSet();
}
List<SamlIdentityProviderDefinition> idps = bootstrap.getIdentityProviderDefinitions();
assertEquals(count, idps.size());
for (SamlIdentityProviderDefinition idp : idps) {
switch (idp.getIdpEntityAlias()) {
case "okta-local" : {
assertEquals(SamlIdentityProviderDefinition.MetadataLocation.DATA, idp.getType());
assertEquals(testXmlFileData.trim(), idp.getMetaDataLocation().trim());
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());
Map<String, Object> attributeMappings = new HashMap<>();
attributeMappings.put("given_name", "first_name");
attributeMappings.put("external_groups", asList("roles"));
assertEquals(attributeMappings, idp.getAttributeMappings());
assertEquals(asList("admin", "user"), idp.getExternalGroupsWhitelist());
assertTrue(idp.isShowSamlLink());
assertTrue(idp.isMetadataTrustCheck());
assertTrue(idp.getEmailDomain().containsAll(asList("test.com", "test.org")));
break;
}
case "okta-local-2" : {
assertEquals(SamlIdentityProviderDefinition.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 "okta-local-3" : {
assertEquals(SamlIdentityProviderDefinition.MetadataLocation.DATA, idp.getType());
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());
break;
}
case singleAddAlias : {
assertEquals(singleAdd, idp);
assertNotSame(singleAdd, idp);
break;
}
case "simplesamlphp-url" : {
assertTrue(idp.isShowSamlLink());
assertEquals("simplesamlphp-url", idp.getLinkText());
break;
}
default:
fail();
}
}
}
@Test
public void testGetIdentityProvidersWithLegacy_Valid_Provider() throws Exception {
bootstrap.setLegacyIdpMetaData(testXmlFileData2);
bootstrap.setLegacyIdpIdentityAlias("okta-local-3");
bootstrap.setLegacyShowSamlLink(true);
bootstrap.setLegacyNameId("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent");
testGetIdentityProviderDefinitions(4);
}
@Test
public void testGetIdentityProviders() throws Exception {
testGetIdentityProviderDefinitions(3);
}
@Test
public void testSetAddShadowUserOnLoginFromYaml() throws Exception {
String yaml = " providers:\n" +
" provider-without-shadow-user-definition:\n" +
" storeCustomAttributes: true\n" +
" idpMetadata: |\n" +
" <?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
" <md:EntityDescriptor xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\" entityID=\"provider1\">" +
" <md:IDPSSODescriptor WantAuthnRequestsSigned=\"true\" protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol\">" +
" <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>" +
" <md:SingleSignOnService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\" Location=\"https://example.com\"/>" +
" </md:IDPSSODescriptor>" +
" </md:EntityDescriptor>\n" +
" nameID: urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\n" +
" provider-with-shadow-users-enabled:\n" +
" storeCustomAttributes: false\n" +
" idpMetadata: |\n" +
" <?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
" <md:EntityDescriptor xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\" entityID=\"provider2\">" +
" <md:IDPSSODescriptor WantAuthnRequestsSigned=\"true\" protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol\">" +
" <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>" +
" <md:SingleSignOnService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\" Location=\"https://example.com\"/>" +
" </md:IDPSSODescriptor>" +
" </md:EntityDescriptor>\n" +
" nameID: urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\n" +
" addShadowUserOnLogin: true\n" +
" provider-with-shadow-user-disabled:\n" +
" idpMetadata: |\n" +
" <?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
" <md:EntityDescriptor xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\" entityID=\"provider3\">" +
" <md:IDPSSODescriptor WantAuthnRequestsSigned=\"true\" protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol\">" +
" <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>" +
" <md:SingleSignOnService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\" Location=\"https://example.com\"/>" +
" </md:IDPSSODescriptor>" +
" </md:EntityDescriptor>\n" +
" nameID: urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\n" +
" addShadowUserOnLogin: false\n";
bootstrap.setIdentityProviders(parseYaml(yaml));
bootstrap.afterPropertiesSet();
for (SamlIdentityProviderDefinition def : bootstrap.getIdentityProviderDefinitions()) {
switch (def.getIdpEntityAlias()) {
case "provider-without-shadow-user-definition" : {
assertTrue("If not specified, addShadowUserOnLogin is set to true", def.isAddShadowUserOnLogin());
assertTrue("Override store custom attributes to true", def.isStoreCustomAttributes());
break;
}
case "provider-with-shadow-users-enabled" : {
assertTrue("addShadowUserOnLogin can be set to true", def.isAddShadowUserOnLogin());
assertFalse("Default store custom attributes is false", def.isStoreCustomAttributes());
break;
}
case "provider-with-shadow-user-disabled" : {
assertFalse("addShadowUserOnLogin can be set to false", def.isAddShadowUserOnLogin());
assertFalse("Default store custom attributes is false", def.isStoreCustomAttributes());
break;
}
default: fail(String.format("Unknown provider %s", def.getIdpEntityAlias()));
}
}
}
}