diff --git a/service_provider.go b/service_provider.go
index a63bdfe1..23eec556 100644
--- a/service_provider.go
+++ b/service_provider.go
@@ -1657,17 +1657,26 @@ func findChild(parentEl *etree.Element, childNS string, childTag string) (*etree
func elementToBytes(el *etree.Element) ([]byte, error) {
namespaces := map[string]string{}
- for _, childEl := range el.FindElements("//*") {
- ns := childEl.NamespaceURI()
- if ns != "" {
- namespaces[childEl.Space] = ns
+ currentElement := el
+ // Retrieve namespaces from the element itself and its parents
+ for currentElement != nil {
+ // Iterate over the attributes of the element, if an attribute is a namespace declaration, add it to the list of namespaces
+ for _, attr := range currentElement.Attr {
+ // "xmlns" is either the space or the key of the attribute, depending on whether it is a default namespace declaration or not
+ if attr.Space == "xmlns" || attr.Key == "xmlns" {
+ // If the namespace is already preset in the list, it means that a child element has overriden it, so skip it
+ if _, prefixExists := namespaces[attr.FullKey()]; !prefixExists {
+ namespaces[attr.FullKey()] = attr.Value
+ }
+ }
}
+ currentElement = currentElement.Parent()
}
doc := etree.NewDocument()
doc.SetRoot(el.Copy())
- for space, uri := range namespaces {
- doc.Root().CreateAttr("xmlns:"+space, uri)
+ for prefix, uri := range namespaces {
+ doc.Root().CreateAttr(prefix, uri)
}
return doc.WriteToBytes()
diff --git a/service_provider_test.go b/service_provider_test.go
index cdf5c723..1389c290 100644
--- a/service_provider_test.go
+++ b/service_provider_test.go
@@ -1851,3 +1851,28 @@ func TestMultipleAssertions(t *testing.T) {
assert.Check(t, err)
assert.Check(t, profile.Subject.NameID.Value != "admin@evil.com")
}
+
+func TestResponseWithDefaultNamespace(t *testing.T) {
+ idpMetadata := golden.Get(t, "TestSPWithDefaultNamespace_idp_metadata")
+ respStr := golden.Get(t, "TestSPWithDefaultNamespace")
+ TimeNow = func() time.Time {
+ rv, _ := time.Parse("Mon Jan 2 15:04:05 MST 2006", "Fri Apr 21 13:12:51 UTC 2017")
+ return rv
+ }
+ Clock = dsig.NewFakeClockAt(TimeNow())
+ s := ServiceProvider{
+ Key: mustParsePrivateKey(golden.Get(t, "key_2017.pem")).(*rsa.PrivateKey),
+ Certificate: mustParseCertificate(golden.Get(t, "cert_2017.pem")),
+ MetadataURL: mustParseURL("https://sp.example.com/saml2/metadata"),
+ AcsURL: mustParseURL("https://sp.example.com/saml2/acs"),
+ IDPMetadata: &EntityDescriptor{},
+ }
+ err := xml.Unmarshal(idpMetadata, &s.IDPMetadata)
+ assert.NilError(t, err)
+
+ req := http.Request{PostForm: url.Values{}}
+ req.PostForm.Set("SAMLResponse", base64.StdEncoding.EncodeToString(respStr))
+ _, err = s.ParseResponse(&req, []string{"id-00020406080a0c0e10121416181a1c1e"})
+
+ assert.NilError(t, err)
+}
diff --git a/testdata/TestSPWithDefaultNamespace b/testdata/TestSPWithDefaultNamespace
new file mode 100644
index 00000000..ef5512a6
--- /dev/null
+++ b/testdata/TestSPWithDefaultNamespace
@@ -0,0 +1 @@
+https://idp.example.com/saml/metadatak/YYE7FN38le10KY8AOrpSN8HQc=KhB4vVN3JxVfjJnrIV12kzKawGgp7V9EkUPp4Pqak1R++rN7GluYy+okQHUKhmD71qokmhpxKbVTCt/IAS4pumd3yRZg/kT0xeG/U9qoNIzzqJECYev7mOjyKRxfJEahcTEu0QDuge0uNf5Uj21oQMqdcV4C4jCLwW2zWLYFLpf+IJPVjQjDL7cogffq7c5AD8fpS6ad7lt7tbWxjOLt1xyDoJRcEYbZrV2QrWpJ64V8R+Y0pzsMJ85r6gPtZpZRuqPeOtP3NOrR3XdT2w435SngGR0mqwvcGGOvgXuHz7xePrhKDxZCBc6Bx7VUOgLlMTXDlmmQf50W3aypMGEoNg==MIIDRTCCAi2gAwIBAgIJANke+OUVRk19MA0GCSqGSIb3DQEBBQUAMCAxHjAcBgNVBAMTFW15c2VydmljZS5leGFtcGxlLmNvbTAeFw0xNzA0MTkxOTU2MTNaFw0xODA0MTkxOTU2MTNaMCAxHjAcBgNVBAMTFW15c2VydmljZS5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ7tsAJqJ4rUZFT/5SjvoA1mpQBC+KidcehMsTFW/9l73cPnYNhtnNe+9S8n76eF2ASuEwAKN5xoXDP297y4ZOORnkouP8jiYZjqNHTckE9LevM8YOpTPVojhq+rq7hiQyMF6pJkBPgduolcsnBg188jn/oNmdmzIaS33QiNOZ6FGXLKt3/Fapscea0gq8a46wKhFFQmW8i+MGqdSSi255c05ZZL5H04plDNoGEvES5OsxSjbZ4+294K83nOXoGSEPfsO4XUTORlryis0p/f3aNUgooueeTphD9Go2pGHYvahjusx9ONbZ7egc07dJoIAVjgaMSv+UwqfpxjAU7018sCAwEAAaOBgTB/MB0GA1UdDgQWBBSYE9Nwp/eUqfRQ11rqwoowNFHNyTBQBgNVHSMESTBHgBSYE9Nwp/eUqfRQ11rqwoowNFHNyaEkpCIwIDEeMBwGA1UEAxMVbXlzZXJ2aWNlLmV4YW1wbGUuY29tggkA2R745RVGTX0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAVJmpMg1ZpDGweoCU4k66RVDpPzSuPJ+9H9L2jcaA38itDtXmG9IzdbOLpNF9fDbU60P421SgS0nF/s7zkxkYJWOoZaced/vUO6H9TdWEZay+uywAjvoZGwkZ9HxYMqKMVld4EwW/OwT67UVBdtgkSfI1O7ojqDOFx7U4+HJWxUEwGOc0pOPzNyLSYCsAkQt2CZU7dN72L96Ka8xxklNaVcUaUH+zOWF1JBamV9s6M2umcdBot8MO3m1zQTkXzBKM3f+Yvk+dRjO4TSW90h2oQqot8xrkPhy+DgOqJj3/lKmZXjqE5mAEhpQB0uVPekPvKN89hCnkPo2EvXKPf7VZgg==https://idp.example.com/saml/metadataunqkaATYuvJT2koFrke8ArX8K9s=Qzb+/IyJgHq2WLR4PyCXNX2pR87GYm0pDm0yBcKjcISo3i8S9Xm04yxqm+zxYb+4HuReB6ZJHId2Jhaz9Ny0aDmj0WMa2QDpeCugffhDdgEEhNiqCpZJVLfACK6QpgqLnsKccalM2VPexU96Q73INxz/zNQKw0Dltf/GBRCbEbJKcHNIX/Xg7CPJdV2sgAGPVlXbZ5vahW3Oy+7HUcGVajZTc6P5DrLEIQRSsZgHZLv4RSvbKBxQc/CvIzVagDWJDD5kJniqf9JGYVZ8j4MQeb8u0VtDlijvrq008Ia566OGom3qj7trdxYdz+Co0ZPJra4c9sKyDa3udXW428fqog==MIIDRTCCAi2gAwIBAgIJANke+OUVRk19MA0GCSqGSIb3DQEBBQUAMCAxHjAcBgNVBAMTFW15c2VydmljZS5leGFtcGxlLmNvbTAeFw0xNzA0MTkxOTU2MTNaFw0xODA0MTkxOTU2MTNaMCAxHjAcBgNVBAMTFW15c2VydmljZS5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ7tsAJqJ4rUZFT/5SjvoA1mpQBC+KidcehMsTFW/9l73cPnYNhtnNe+9S8n76eF2ASuEwAKN5xoXDP297y4ZOORnkouP8jiYZjqNHTckE9LevM8YOpTPVojhq+rq7hiQyMF6pJkBPgduolcsnBg188jn/oNmdmzIaS33QiNOZ6FGXLKt3/Fapscea0gq8a46wKhFFQmW8i+MGqdSSi255c05ZZL5H04plDNoGEvES5OsxSjbZ4+294K83nOXoGSEPfsO4XUTORlryis0p/f3aNUgooueeTphD9Go2pGHYvahjusx9ONbZ7egc07dJoIAVjgaMSv+UwqfpxjAU7018sCAwEAAaOBgTB/MB0GA1UdDgQWBBSYE9Nwp/eUqfRQ11rqwoowNFHNyTBQBgNVHSMESTBHgBSYE9Nwp/eUqfRQ11rqwoowNFHNyaEkpCIwIDEeMBwGA1UEAxMVbXlzZXJ2aWNlLmV4YW1wbGUuY29tggkA2R745RVGTX0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAVJmpMg1ZpDGweoCU4k66RVDpPzSuPJ+9H9L2jcaA38itDtXmG9IzdbOLpNF9fDbU60P421SgS0nF/s7zkxkYJWOoZaced/vUO6H9TdWEZay+uywAjvoZGwkZ9HxYMqKMVld4EwW/OwT67UVBdtgkSfI1O7ojqDOFx7U4+HJWxUEwGOc0pOPzNyLSYCsAkQt2CZU7dN72L96Ka8xxklNaVcUaUH+zOWF1JBamV9s6M2umcdBot8MO3m1zQTkXzBKM3f+Yvk+dRjO4TSW90h2oQqot8xrkPhy+DgOqJj3/lKmZXjqE5mAEhpQB0uVPekPvKN89hCnkPo2EvXKPf7VZgg==https://sp.example.com/saml2/metadataurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransportalice
diff --git a/testdata/TestSPWithDefaultNamespace_idp_metadata b/testdata/TestSPWithDefaultNamespace_idp_metadata
new file mode 100644
index 00000000..faa6c89f
--- /dev/null
+++ b/testdata/TestSPWithDefaultNamespace_idp_metadata
@@ -0,0 +1 @@
+MIIDRTCCAi2gAwIBAgIJANke+OUVRk19MA0GCSqGSIb3DQEBBQUAMCAxHjAcBgNVBAMTFW15c2VydmljZS5leGFtcGxlLmNvbTAeFw0xNzA0MTkxOTU2MTNaFw0xODA0MTkxOTU2MTNaMCAxHjAcBgNVBAMTFW15c2VydmljZS5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ7tsAJqJ4rUZFT/5SjvoA1mpQBC+KidcehMsTFW/9l73cPnYNhtnNe+9S8n76eF2ASuEwAKN5xoXDP297y4ZOORnkouP8jiYZjqNHTckE9LevM8YOpTPVojhq+rq7hiQyMF6pJkBPgduolcsnBg188jn/oNmdmzIaS33QiNOZ6FGXLKt3/Fapscea0gq8a46wKhFFQmW8i+MGqdSSi255c05ZZL5H04plDNoGEvES5OsxSjbZ4+294K83nOXoGSEPfsO4XUTORlryis0p/f3aNUgooueeTphD9Go2pGHYvahjusx9ONbZ7egc07dJoIAVjgaMSv+UwqfpxjAU7018sCAwEAAaOBgTB/MB0GA1UdDgQWBBSYE9Nwp/eUqfRQ11rqwoowNFHNyTBQBgNVHSMESTBHgBSYE9Nwp/eUqfRQ11rqwoowNFHNyaEkpCIwIDEeMBwGA1UEAxMVbXlzZXJ2aWNlLmV4YW1wbGUuY29tggkA2R745RVGTX0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAVJmpMg1ZpDGweoCU4k66RVDpPzSuPJ+9H9L2jcaA38itDtXmG9IzdbOLpNF9fDbU60P421SgS0nF/s7zkxkYJWOoZaced/vUO6H9TdWEZay+uywAjvoZGwkZ9HxYMqKMVld4EwW/OwT67UVBdtgkSfI1O7ojqDOFx7U4+HJWxUEwGOc0pOPzNyLSYCsAkQt2CZU7dN72L96Ka8xxklNaVcUaUH+zOWF1JBamV9s6M2umcdBot8MO3m1zQTkXzBKM3f+Yvk+dRjO4TSW90h2oQqot8xrkPhy+DgOqJj3/lKmZXjqE5mAEhpQB0uVPekPvKN89hCnkPo2EvXKPf7VZgg==urn:oasis:names:tc:SAML:2.0:nameid-format:transient