|
| 1 | +/* |
| 2 | + * Copyright 2002-2020 the original author or authors. |
| 3 | + * |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | + * you may not use this file except in compliance with the License. |
| 6 | + * You may obtain a copy of the License at |
| 7 | + * |
| 8 | + * https://www.apache.org/licenses/LICENSE-2.0 |
| 9 | + * |
| 10 | + * Unless required by applicable law or agreed to in writing, software |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | + * See the License for the specific language governing permissions and |
| 14 | + * limitations under the License. |
| 15 | + */ |
| 16 | + |
| 17 | +package org.springframework.security.saml2.provider.service.registration; |
| 18 | + |
| 19 | +import okhttp3.mockwebserver.MockResponse; |
| 20 | +import okhttp3.mockwebserver.MockWebServer; |
| 21 | +import org.junit.Test; |
| 22 | + |
| 23 | +import org.springframework.security.saml2.Saml2Exception; |
| 24 | + |
| 25 | +import static org.assertj.core.api.Assertions.assertThat; |
| 26 | +import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; |
| 27 | + |
| 28 | +/** |
| 29 | + * Tests for {@link RelyingPartyRegistration} |
| 30 | + */ |
| 31 | +public class RelyingPartyRegistrationsTests { |
| 32 | + private static final String IDP_SSO_DESCRIPTOR_PAYLOAD = |
| 33 | + "<md:EntityDescriptor entityID=\"https://idp.example.com/idp/shibboleth\"\n" + |
| 34 | + " xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\"\n" + |
| 35 | + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + |
| 36 | + " xmlns:shibmd=\"urn:mace:shibboleth:metadata:1.0\"\n" + |
| 37 | + " xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\"\n" + |
| 38 | + " xmlns:mdui=\"urn:oasis:names:tc:SAML:metadata:ui\">\n" + |
| 39 | + " \n" + |
| 40 | + " <md:IDPSSODescriptor protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol\">\n" + |
| 41 | + " <md:Extensions>\n" + |
| 42 | + " <shibmd:Scope regexp=\"false\">example.com</shibmd:Scope>\n" + |
| 43 | + " \n" + |
| 44 | + " <mdui:UIInfo>\n" + |
| 45 | + " <mdui:DisplayName xml:lang=\"en\">\n" + |
| 46 | + " Consortium GARR IdP\n" + |
| 47 | + " </mdui:DisplayName>\n" + |
| 48 | + " <mdui:DisplayName xml:lang=\"it\">\n" + |
| 49 | + " Consortium GARR IdP\n" + |
| 50 | + " </mdui:DisplayName>\n" + |
| 51 | + " \n" + |
| 52 | + " <mdui:Description xml:lang=\"en\">\n" + |
| 53 | + " This Identity Provider gives support for the Consortium GARR's user community\n" + |
| 54 | + " </mdui:Description>\n" + |
| 55 | + " <mdui:Description xml:lang=\"it\">\n" + |
| 56 | + " Questo Identity Provider di test fornisce supporto alla comunita' utenti GARR\n" + |
| 57 | + " </mdui:Description>\n" + |
| 58 | + " </mdui:UIInfo>\n" + |
| 59 | + " </md:Extensions>\n" + |
| 60 | + " \n" + |
| 61 | + " <md:KeyDescriptor>\n" + |
| 62 | + " <ds:KeyInfo>\n" + |
| 63 | + " <ds:X509Data>\n" + |
| 64 | + " <ds:X509Certificate>\n" + |
| 65 | + " MIIDZjCCAk6gAwIBAgIVAL9O+PA7SXtlwZZY8MVSE9On1cVWMA0GCSqGSIb3DQEB\n" + |
| 66 | + " BQUAMCkxJzAlBgNVBAMTHmlkZW0tcHVwYWdlbnQuZG16LWludC51bmltby5pdDAe\n" + |
| 67 | + " Fw0xMzA3MjQwMDQ0MTRaFw0zMzA3MjQwMDQ0MTRaMCkxJzAlBgNVBAMTHmlkZW0t\n" + |
| 68 | + " cHVwYWdlbnQuZG16LWludC51bmltby5pdDCCASIwDQYJKoZIhvcNAMIIDQADggEP\n" + |
| 69 | + " ADCCAQoCggEBAIAcp/VyzZGXUF99kwj4NvL/Rwv4YvBgLWzpCuoxqHZ/hmBwJtqS\n" + |
| 70 | + " v0y9METBPFbgsF3hCISnxbcmNVxf/D0MoeKtw1YPbsUmow/bFe+r72hZ+IVAcejN\n" + |
| 71 | + " iDJ7t5oTjsRN1t1SqvVVk6Ryk5AZhpFW+W9pE9N6c7kJ16Rp2/mbtax9OCzxpece\n" + |
| 72 | + " byi1eiLfIBmkcRawL/vCc2v6VLI18i6HsNVO3l2yGosKCbuSoGDx2fCdAOk/rgdz\n" + |
| 73 | + " cWOvFsIZSKuD+FVbSS/J9GVs7yotsS4PRl4iX9UMnfDnOMfO7bcBgbXtDl4SCU1v\n" + |
| 74 | + " dJrRw7IL/pLz34Rv9a8nYitrzrxtLOp3nYUCAwEAAaOBhDCBgTBgBgMIIDEEWTBX\n" + |
| 75 | + " gh5pZGVtLXB1cGFnZW50LmRtei1pbnQudW5pbW8uaXSGNWh0dHBzOi8vaWRlbS1w\n" + |
| 76 | + " dXBhZ2VudC5kbXotaW50LnVuaW1vLml0L2lkcC9zaGliYm9sZXRoMB0GA1UdDgQW\n" + |
| 77 | + " BBT8PANzz+adGnTRe8ldcyxAwe4VnzANBgkqhkiG9w0BAQUFAAOCAQEAOEnO8Clu\n" + |
| 78 | + " 9z/Lf/8XOOsTdxJbV29DIF3G8KoQsB3dBsLwPZVEAQIP6ceS32Xaxrl6FMTDDNkL\n" + |
| 79 | + " qUvvInUisw0+I5zZwYHybJQCletUWTnz58SC4C9G7FpuXHFZnOGtRcgGD1NOX4UU\n" + |
| 80 | + " duus/4nVcGSLhDjszZ70Xtj0gw2Sn46oQPHTJ81QZ3Y9ih+Aj1c9OtUSBwtWZFkU\n" + |
| 81 | + " yooAKoR8li68Yb21zN2N65AqV+ndL98M8xUYMKLONuAXStDeoVCipH6PJ09Z5U2p\n" + |
| 82 | + " V5p4IQRV6QBsNw9CISJFuHzkVYTH5ZxzN80Ru46vh4y2M0Nu8GQ9I085KoZkrf5e\n" + |
| 83 | + " Cq53OZt9ISjHEw==\n" + |
| 84 | + " </ds:X509Certificate>\n" + |
| 85 | + " </ds:X509Data>\n" + |
| 86 | + " </ds:KeyInfo>\n" + |
| 87 | + " </md:KeyDescriptor>\n" + |
| 88 | + " \n" + |
| 89 | + " <md:SingleSignOnService\n" + |
| 90 | + " Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\"\n" + |
| 91 | + " Location=\"https://idp.example.com/idp/profile/SAML2/POST/SSO\"/>\n" + |
| 92 | + " </md:IDPSSODescriptor>\n" + |
| 93 | + " \n" + |
| 94 | + " <md:Organization>\n" + |
| 95 | + " <md:OrganizationName xml:lang=\"en\">\n" + |
| 96 | + " Consortium GARR\n" + |
| 97 | + " </md:OrganizationName>\n" + |
| 98 | + " <md:OrganizationName xml:lang=\"it\">\n" + |
| 99 | + " Consortium GARR\n" + |
| 100 | + " </md:OrganizationName>\n" + |
| 101 | + " \n" + |
| 102 | + " <md:OrganizationDisplayName xml:lang=\"en\">\n" + |
| 103 | + " Consortium GARR\n" + |
| 104 | + " </md:OrganizationDisplayName>\n" + |
| 105 | + " <md:OrganizationDisplayName xml:lang=\"it\">\n" + |
| 106 | + " Consortium GARR\n" + |
| 107 | + " </md:OrganizationDisplayName>\n" + |
| 108 | + " \n" + |
| 109 | + " <md:OrganizationURL xml:lang=\"it\">\n" + |
| 110 | + " https://example.org\n" + |
| 111 | + " </md:OrganizationURL>\n" + |
| 112 | + " </md:Organization>\n" + |
| 113 | + " \n" + |
| 114 | + " <md:ContactPerson contactType=\"technical\">\n" + |
| 115 | + " <md:EmailAddress>mailto:technical.contact@example.com</md:EmailAddress>\n" + |
| 116 | + " </md:ContactPerson>\n" + |
| 117 | + " \n" + |
| 118 | + "</md:EntityDescriptor>"; |
| 119 | + |
| 120 | + @Test |
| 121 | + public void fromMetadataLocationWhenResolvableThenPopulatesBuilder() throws Exception { |
| 122 | + try (MockWebServer server = new MockWebServer()) { |
| 123 | + server.enqueue(new MockResponse().setBody(IDP_SSO_DESCRIPTOR_PAYLOAD).setResponseCode(200)); |
| 124 | + RelyingPartyRegistration registration = RelyingPartyRegistrations |
| 125 | + .fromMetadataLocation(server.url("/").toString()) |
| 126 | + .entityId("rp") |
| 127 | + .build(); |
| 128 | + RelyingPartyRegistration.AssertingPartyDetails details = registration.getAssertingPartyDetails(); |
| 129 | + assertThat(details.getEntityId()).isEqualTo("https://idp.example.com/idp/shibboleth"); |
| 130 | + assertThat(details.getSingleSignOnServiceLocation()) |
| 131 | + .isEqualTo("https://idp.example.com/idp/profile/SAML2/POST/SSO"); |
| 132 | + assertThat(details.getSingleSignOnServiceBinding()) |
| 133 | + .isEqualTo(Saml2MessageBinding.POST); |
| 134 | + assertThat(details.getVerificationX509Credentials()).hasSize(1); |
| 135 | + assertThat(details.getEncryptionX509Credentials()).hasSize(1); |
| 136 | + } |
| 137 | + } |
| 138 | + |
| 139 | + @Test |
| 140 | + public void fromMetadataLocationWhenUnresolvableThenSaml2Exception() throws Exception { |
| 141 | + try (MockWebServer server = new MockWebServer()) { |
| 142 | + server.enqueue(new MockResponse().setBody(IDP_SSO_DESCRIPTOR_PAYLOAD).setResponseCode(200)); |
| 143 | + String url = server.url("/").toString(); |
| 144 | + server.shutdown(); |
| 145 | + assertThatCode(() -> RelyingPartyRegistrations.fromMetadataLocation(url)) |
| 146 | + .isInstanceOf(Saml2Exception.class); |
| 147 | + } |
| 148 | + } |
| 149 | + |
| 150 | + @Test |
| 151 | + public void fromMetadataLocationWhenMalformedResponseThenSaml2Exception() throws Exception { |
| 152 | + try (MockWebServer server = new MockWebServer()) { |
| 153 | + server.enqueue(new MockResponse().setBody("malformed").setResponseCode(200)); |
| 154 | + String url = server.url("/").toString(); |
| 155 | + assertThatCode(() -> RelyingPartyRegistrations.fromMetadataLocation(url)) |
| 156 | + .isInstanceOf(Saml2Exception.class); |
| 157 | + } |
| 158 | + } |
| 159 | +} |
0 commit comments