Skip to content

Commit 96094d8

Browse files
committed
See SAML-Toolkits#460.Fix bug on idp_metadata_parser: When a XML with multiple descriptos, the first entityDescriptor contained a SPSSODescriptor, the parser returned no element instead the first entityDescriptor with a IDPSSODescriptor
1 parent dea8136 commit 96094d8

File tree

2 files changed

+31
-27
lines changed

2 files changed

+31
-27
lines changed

lib/onelogin/ruby-saml/idp_metadata_parser.rb

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -164,34 +164,32 @@ def entity_descriptor
164164
end
165165

166166
def entity_descriptor_path
167-
path = "//md:EntityDescriptor"
168-
entity_id = options[:entity_id]
169-
return path unless entity_id
167+
path = "//md:EntityDescriptor"
168+
entity_id = options[:entity_id]
169+
return path unless entity_id
170170
path << "[@entityID=\"#{entity_id}\"]"
171171
end
172172

173173
def idpsso_descriptor
174-
unless entity_descriptor.nil?
175-
return REXML::XPath.first(
176-
entity_descriptor,
177-
"md:IDPSSODescriptor",
178-
namespace
179-
)
180-
end
174+
REXML::XPath.first(
175+
document,
176+
entity_descriptor_path << "/md:IDPSSODescriptor",
177+
namespace
178+
)
181179
end
182180

183181
# @return [String|nil] IdP Entity ID value if exists
184182
#
185183
def idp_entity_id
186-
entity_descriptor.attributes["entityID"]
184+
idpsso_descriptor.parent.attributes["entityID"]
187185
end
188186

189187
# @return [String|nil] IdP Name ID Format value if exists
190188
#
191189
def idp_name_id_format
192190
node = REXML::XPath.first(
193-
entity_descriptor,
194-
"md:IDPSSODescriptor/md:NameIDFormat",
191+
idpsso_descriptor,
192+
"md:NameIDFormat",
195193
namespace
196194
)
197195
Utils.element_text(node)
@@ -202,8 +200,8 @@ def idp_name_id_format
202200
#
203201
def single_signon_service_binding(binding_priority = nil)
204202
nodes = REXML::XPath.match(
205-
entity_descriptor,
206-
"md:IDPSSODescriptor/md:SingleSignOnService/@Binding",
203+
idpsso_descriptor,
204+
"md:SingleSignOnService/@Binding",
207205
namespace
208206
)
209207
if binding_priority
@@ -221,8 +219,8 @@ def single_signon_service_url(options = {})
221219
binding = single_signon_service_binding(options[:sso_binding])
222220
unless binding.nil?
223221
node = REXML::XPath.first(
224-
entity_descriptor,
225-
"md:IDPSSODescriptor/md:SingleSignOnService[@Binding=\"#{binding}\"]/@Location",
222+
idpsso_descriptor,
223+
"md:SingleSignOnService[@Binding=\"#{binding}\"]/@Location",
226224
namespace
227225
)
228226
return node.value if node
@@ -234,8 +232,8 @@ def single_signon_service_url(options = {})
234232
#
235233
def single_logout_service_binding(binding_priority = nil)
236234
nodes = REXML::XPath.match(
237-
entity_descriptor,
238-
"md:IDPSSODescriptor/md:SingleLogoutService/@Binding",
235+
idpsso_descriptor,
236+
"md:SingleLogoutService/@Binding",
239237
namespace
240238
)
241239
if binding_priority
@@ -253,8 +251,8 @@ def single_logout_service_url(options = {})
253251
binding = single_logout_service_binding(options[:slo_binding])
254252
unless binding.nil?
255253
node = REXML::XPath.first(
256-
entity_descriptor,
257-
"md:IDPSSODescriptor/md:SingleLogoutService[@Binding=\"#{binding}\"]/@Location",
254+
idpsso_descriptor,
255+
"md:SingleLogoutService[@Binding=\"#{binding}\"]/@Location",
258256
namespace
259257
)
260258
return node.value if node
@@ -266,14 +264,14 @@ def single_logout_service_url(options = {})
266264
def certificates
267265
@certificates ||= begin
268266
signing_nodes = REXML::XPath.match(
269-
entity_descriptor,
270-
"md:IDPSSODescriptor/md:KeyDescriptor[not(contains(@use, 'encryption'))]/ds:KeyInfo/ds:X509Data/ds:X509Certificate",
267+
idpsso_descriptor,
268+
"md:KeyDescriptor[not(contains(@use, 'encryption'))]/ds:KeyInfo/ds:X509Data/ds:X509Certificate",
271269
namespace
272270
)
273271

274272
encryption_nodes = REXML::XPath.match(
275-
entity_descriptor,
276-
"md:IDPSSODescriptor/md:KeyDescriptor[not(contains(@use, 'signing'))]/ds:KeyInfo/ds:X509Data/ds:X509Certificate",
273+
idpsso_descriptor,
274+
"md:KeyDescriptor[not(contains(@use, 'signing'))]/ds:KeyInfo/ds:X509Data/ds:X509Certificate",
277275
namespace
278276
)
279277

@@ -315,8 +313,8 @@ def fingerprint(certificate, fingerprint_algorithm = XMLSecurity::Document::SHA1
315313
#
316314
def attribute_names
317315
nodes = REXML::XPath.match(
318-
entity_descriptor,
319-
"md:IDPSSODescriptor/saml:Attribute/@Name",
316+
idpsso_descriptor,
317+
"saml:Attribute/@Name",
320318
namespace
321319
)
322320
nodes.map(&:value)

test/metadata/idp_multiple_descriptors.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<md:EntitiesDescriptor validUntil="2014-04-17T18:02:33.910Z" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
3+
<md:EntityDescriptor entityID="https://biz.example.com/app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="md:EntityDescriptorType">
4+
<md:SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
5+
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
6+
<md:AssertionConsumerService isDefault="true" index="1" binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" location="https://biz.example.com/app/sso"></md:AssertionConsumerService>
7+
</md:SPSSODescriptor>
8+
</md:EntityDescriptor>
39
<md:EntityDescriptor entityID="https://foo.example.com/access/saml/idp.xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="md:EntityDescriptorType">
410
<md:IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
511
<md:KeyDescriptor use="signing">

0 commit comments

Comments
 (0)