diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SAMLMetadataUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SAMLMetadataUtil.java index 424a26ece08..660b96c0438 100755 --- a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SAMLMetadataUtil.java +++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SAMLMetadataUtil.java @@ -45,6 +45,8 @@ import org.w3c.dom.NodeList; */ public class SAMLMetadataUtil { + public static final String UTF8_BOM = "\uFEFF"; + /** * Get the {@link X509Certificate} from the KeyInfo * @@ -107,6 +109,7 @@ public class SAMLMetadataUtil { } public static EntityDescriptorType parseEntityDescriptorType(String descriptor) throws ParsingException { + descriptor = removeUTF8BOM(descriptor); Object parsedObject = SAMLParser.getInstance().parse(StaxParserUtil.getXMLEventReader(descriptor)); EntityDescriptorType entityType; @@ -153,4 +156,11 @@ public class SAMLMetadataUtil { } return descriptor; } -} \ No newline at end of file + + public static String removeUTF8BOM(String s) { + if (s.startsWith(UTF8_BOM)) { + s = s.substring(1); + } + return s; + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java index 8eca003b4ed..7f45bc1dc15 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java @@ -743,6 +743,19 @@ public class IdentityProviderTest extends AbstractAdminTest { assertSamlExport(body, true); } + @Test + public void testSamlImportWithBom() throws URISyntaxException, IOException, ParsingException { + testSamlImport("saml-idp-metadata_utf8_bom.xml", true); + + // Perform export, and make sure some of the values are like they're supposed to be + Response response = realm.identityProviders().get("saml").export("xml"); + Assert.assertEquals(200, response.getStatus()); + String body = response.readEntity(String.class); + response.close(); + + assertSamlExport(body, true); + } + @Test public void testSamlImportAndExportDifferentBindings() throws URISyntaxException, IOException, ParsingException { testSamlImport("saml-idp-metadata-different-bindings.xml", false); diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/admin-test/saml-idp-metadata_utf8_bom.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/admin-test/saml-idp-metadata_utf8_bom.xml new file mode 100644 index 00000000000..9e65a0d27ce --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/admin-test/saml-idp-metadata_utf8_bom.xml @@ -0,0 +1,39 @@ + + + + + + http://refeds.org/category/hide-from-discovery + + + + + + + + + MIICmzCCAYMCBgFUYnC0OjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMTYwNDI5MTQzMjEzWhcNMjYwNDI5MTQzMzUzWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCN25AW1poMEZRbuMAHG58AThZmCwMV6/Gcui4mjGacRFyudgqzLjQ2rxpoW41JAtLjbjeAhuWvirUcFVcOeS3gM/ZC27qCpYighAcylZz6MYocnEe1+e8rPPk4JlID6Wv62dgu+pL/vYsQpRhvD3Y2c/ytgr5D32xF+KnzDehUy5BSyzypvu12Wq9mS5vK5tzkN37EjkhpY2ZxaXPubjDIITCAL4Q8M/m5IlacBaUZbzI4AQrHnMP1O1IH2dHSWuMiBe+xSDTco72PmuYPJKTV4wQdeBUIkYbfLc4RxVmXEvgkQgyW86EoMPxlWJpj7+mTIR+l+2thZPr/VgwTs82rAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAA/Ip/Hi8RoVu5ouaFFlc5whT7ltuK8slfLGW4tM4vJXhInYwsqIRQKBNDYW/64xle3eII4u1yAH1OYRRwEs7Em1pr4QuFuTY1at+aE0sE46XDlyESI0txJjWxYoT133vM0We2pj1b2nxgU30rwjKA3whnKEfTEYT/n3JBSqNggy6l8ZGw/oPSgvPaR4+xeB1tfQFC4VrLoYKoqH6hAL530nKxL+qV8AIfL64NDEE8ankIAEDAAFe8x3CPUfXR/p4KOANKkpz8ieQaHDb1eITkAwUwjESj6UF9D1aePlhWls/HX0gujFXtWfWfrJ8CU/ogwlH8y1jgRuLjFQYZk6llc= + + + + + + urn:oasis:names:tc:SAML:2.0:nameid-format:persistent + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified + urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress + + + +