/* * ***************************************************************************** * Cloud Foundry * Copyright (c) [2009-2015] 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.bouncycastle.jce.provider.BouncyCastleProvider; import org.cloudfoundry.identity.uaa.provider.saml.idp.SamlTestUtils; import org.cloudfoundry.identity.uaa.saml.SamlKey; import org.cloudfoundry.identity.uaa.zone.IdentityZone; import org.cloudfoundry.identity.uaa.zone.IdentityZoneConfiguration; import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.opensaml.Configuration; import org.opensaml.DefaultBootstrap; import org.opensaml.xml.io.MarshallingException; import org.opensaml.xml.security.keyinfo.NamedKeyInfoGeneratorManager; import org.springframework.security.saml.SAMLConstants; import org.springframework.security.saml.key.KeyManager; import org.springframework.security.saml.metadata.ExtendedMetadata; import org.springframework.security.saml.metadata.MetadataManager; import org.springframework.security.saml.util.SAMLUtil; import java.security.Security; import java.util.List; import static org.cloudfoundry.identity.uaa.provider.saml.SamlKeyManagerFactoryTests.certificate1; import static org.cloudfoundry.identity.uaa.provider.saml.SamlKeyManagerFactoryTests.certificate2; import static org.cloudfoundry.identity.uaa.provider.saml.SamlKeyManagerFactoryTests.key1; import static org.cloudfoundry.identity.uaa.provider.saml.SamlKeyManagerFactoryTests.key2; import static org.cloudfoundry.identity.uaa.provider.saml.SamlKeyManagerFactoryTests.passphrase1; import static org.cloudfoundry.identity.uaa.provider.saml.SamlKeyManagerFactoryTests.passphrase2; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; public class ZoneAwareMetadataGeneratorTests { public static final String ZONE_ID = "zone-id"; private ZoneAwareMetadataGenerator generator; private IdentityZone otherZone; private IdentityZoneConfiguration otherZoneDefinition; private KeyManager keyManager; private ExtendedMetadata extendedMetadata; public static final SamlKey samlKey1 = new SamlKey(key1, passphrase1, certificate1); public static final SamlKey samlKey2 = new SamlKey(key2, passphrase2, certificate2); public static final String cert1Plain = certificate1.replace("-----BEGIN CERTIFICATE-----","").replace("-----END CERTIFICATE-----","").replace("\n",""); public static final String cert2Plain = certificate2.replace("-----BEGIN CERTIFICATE-----","").replace("-----END CERTIFICATE-----","").replace("\n",""); @BeforeClass public static void bootstrap() throws Exception { Security.addProvider(new BouncyCastleProvider()); DefaultBootstrap.bootstrap(); NamedKeyInfoGeneratorManager keyInfoGeneratorManager = Configuration.getGlobalSecurityConfiguration().getKeyInfoGeneratorManager(); keyInfoGeneratorManager.getManager(SAMLConstants.SAML_METADATA_KEY_INFO_GENERATOR); } @Before public void setUp() { otherZone = new IdentityZone(); otherZone.setId(ZONE_ID); otherZone.setName(ZONE_ID); otherZone.setSubdomain(ZONE_ID); otherZone.setConfig(new IdentityZoneConfiguration()); otherZoneDefinition = otherZone.getConfig(); otherZoneDefinition.getSamlConfig().setRequestSigned(true); otherZoneDefinition.getSamlConfig().setWantAssertionSigned(true); otherZoneDefinition.getSamlConfig().addAndActivateKey("key-1", samlKey1); otherZone.setConfig(otherZoneDefinition); generator = new ZoneAwareMetadataGenerator(); generator.setEntityBaseURL("http://localhost:8080/uaa"); generator.setEntityId("entityIdValue"); extendedMetadata = new org.springframework.security.saml.metadata.ExtendedMetadata(); extendedMetadata.setIdpDiscoveryEnabled(true); extendedMetadata.setAlias("entityAlias"); extendedMetadata.setSignMetadata(true); generator.setExtendedMetadata(extendedMetadata); keyManager = new ZoneAwareKeyManager(); generator.setKeyManager(keyManager); } @After public void clear() { IdentityZoneHolder.clear(); } @Test public void test_request_and_want_assertion_signed_in_another_zone() { generator.setRequestSigned(true); generator.setWantAssertionSigned(true); assertTrue(generator.isRequestSigned()); assertTrue(generator.isWantAssertionSigned()); generator.setRequestSigned(false); generator.setWantAssertionSigned(false); assertFalse(generator.isRequestSigned()); assertFalse(generator.isWantAssertionSigned()); IdentityZoneHolder.set(otherZone); assertTrue(generator.isRequestSigned()); assertTrue(generator.isWantAssertionSigned()); } @Test public void test_metadata_contains_saml_bearer_grant_endpoint() throws Exception { String s = getMetadata(); assertThat(s, containsString("md:AssertionConsumerService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:URI\" Location=\"http://zone-id.localhost:8080/uaa/oauth/token/alias/zone-id.entityAlias\" index=\"2\"/>")); } public String getMetadata() throws MarshallingException { IdentityZoneHolder.set(otherZone); return SAMLUtil.getMetadataAsString(mock(MetadataManager.class), keyManager , generator.generateMetadata(), extendedMetadata); } @Test public void default_keys() throws Exception { String s = getMetadata(); List<String> encryptionKeys = getCertificates(s, "encryption"); assertEquals(1, encryptionKeys.size()); assertEquals(cert1Plain, encryptionKeys.get(0)); List<String> signingVerificationCerts = getCertificates(s, "signing"); assertEquals(1, signingVerificationCerts.size()); assertEquals(cert1Plain, signingVerificationCerts.get(0)); } @Test public void multiple_keys() throws Exception { otherZoneDefinition.getSamlConfig().addKey("key2", samlKey2); String s = getMetadata(); List<String> encryptionKeys = getCertificates(s, "encryption"); assertEquals(1, encryptionKeys.size()); assertEquals(cert1Plain, encryptionKeys.get(0)); List<String> signingVerificationCerts = getCertificates(s, "signing"); assertEquals(2, signingVerificationCerts.size()); assertThat(signingVerificationCerts, contains(cert1Plain, cert2Plain)); } @Test public void change_active_key() throws Exception { multiple_keys(); otherZoneDefinition.getSamlConfig().addAndActivateKey("key2", samlKey2); String s = getMetadata(); List<String> encryptionKeys = getCertificates(s, "encryption"); assertEquals(1, encryptionKeys.size()); assertEquals(cert2Plain, encryptionKeys.get(0)); List<String> signingVerificationCerts = getCertificates(s, "signing"); assertEquals(2, signingVerificationCerts.size()); assertThat(signingVerificationCerts, contains(cert2Plain, cert1Plain)); } @Test public void remove_key() throws Exception { change_active_key(); otherZoneDefinition.getSamlConfig().removeKey("key-1"); String s = getMetadata(); List<String> encryptionKeys = getCertificates(s, "encryption"); assertEquals(1, encryptionKeys.size()); assertEquals(cert2Plain, encryptionKeys.get(0)); List<String> signingVerificationCerts = getCertificates(s, "signing"); assertEquals(1, signingVerificationCerts.size()); assertThat(signingVerificationCerts, contains(cert2Plain)); } public List<String> getCertificates(String metadata, String type) throws Exception { return SamlTestUtils.getCertificates(metadata, type); } }