Skip to content

Commit 18fb134

Browse files
author
Dmitry Stolyarov
committed
Implement binding parsing in idp_metadata_parser
1 parent 45665ba commit 18fb134

2 files changed

Lines changed: 54 additions & 10 deletions

File tree

lib/onelogin/ruby-saml/idp_metadata_parser.rb

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,28 @@ class IdpMetadataParser
2626
# IdP values
2727
#
2828
# @param (see IdpMetadataParser#get_idp_metadata)
29+
# @param options [Hash] :settings to provide the OneLogin::RubySaml::Settings object
2930
# @return (see IdpMetadataParser#get_idp_metadata)
3031
# @raise (see IdpMetadataParser#get_idp_metadata)
31-
def parse_remote(url, validate_cert = true)
32+
def parse_remote(url, validate_cert = true, options = {})
3233
idp_metadata = get_idp_metadata(url, validate_cert)
33-
parse(idp_metadata)
34+
parse(idp_metadata, options)
3435
end
3536

3637
# Parse the Identity Provider metadata and update the settings with the IdP values
3738
# @param idp_metadata [String]
39+
# @param options [Hash] :settings to provide the OneLogin::RubySaml::Settings object
3840
#
39-
def parse(idp_metadata)
41+
def parse(idp_metadata, options = {})
4042
@document = REXML::Document.new(idp_metadata)
4143

42-
OneLogin::RubySaml::Settings.new.tap do |settings|
44+
(options[:settings] || OneLogin::RubySaml::Settings.new).tap do |settings|
4345
settings.idp_entity_id = idp_entity_id
4446
settings.name_identifier_format = idp_name_id_format
45-
settings.idp_sso_target_url = single_signon_service_url
46-
settings.idp_slo_target_url = single_logout_service_url
47+
settings.idp_sso_target_binding ||= single_signon_service_binding(settings.idp_sso_target_parse_binding_priority)
48+
settings.idp_sso_target_url = single_signon_service_url(settings.idp_sso_target_binding)
49+
settings.idp_slo_target_binding ||= single_logout_service_binding(settings.idp_slo_target_parse_binding_priority)
50+
settings.idp_slo_target_url = single_logout_service_url(settings.idp_slo_target_binding)
4751
settings.idp_cert = certificate_base64
4852
settings.idp_cert_fingerprint = fingerprint
4953
end
@@ -112,23 +116,59 @@ def idp_name_id_format
112116
node.text if node
113117
end
114118

119+
# @param binding_priority [Array]
120+
# @return [String|nil] SingleSignOnService binding if exists
121+
#
122+
def single_signon_service_binding(binding_priority = nil)
123+
nodes = REXML::XPath.match(
124+
document,
125+
"/md:EntityDescriptor/md:IDPSSODescriptor/md:SingleSignOnService/@Binding",
126+
{ "md" => METADATA }
127+
)
128+
if binding_priority
129+
values = nodes.map(&:value)
130+
binding_priority.detect{ |binding| values.include? binding }
131+
else
132+
nodes.first.value if nodes.any?
133+
end
134+
end
135+
136+
# @param binding [String]
115137
# @return [String|nil] SingleSignOnService endpoint if exists
116138
#
117-
def single_signon_service_url
139+
def single_signon_service_url(binding = nil)
118140
node = REXML::XPath.first(
119141
document,
120-
"/md:EntityDescriptor/md:IDPSSODescriptor/md:SingleSignOnService/@Location",
142+
"/md:EntityDescriptor/md:IDPSSODescriptor/md:SingleSignOnService#{"[@Binding='#{binding}']" if binding}/@Location",
121143
{ "md" => METADATA }
122144
)
123145
node.value if node
124146
end
125147

148+
# @param binding_priority [Array]
149+
# @return [String|nil] SingleLogoutService binding if exists
150+
#
151+
def single_logout_service_binding(binding_priority = nil)
152+
nodes = REXML::XPath.match(
153+
document,
154+
"/md:EntityDescriptor/md:IDPSSODescriptor/md:SingleLogoutService/@Binding",
155+
{ "md" => METADATA }
156+
)
157+
if binding_priority
158+
values = nodes.map(&:value)
159+
binding_priority.detect{ |binding| values.include? binding }
160+
else
161+
nodes.first.value if nodes.any?
162+
end
163+
end
164+
165+
# @param binding [String]
126166
# @return [String|nil] SingleLogoutService endpoint if exists
127167
#
128-
def single_logout_service_url
168+
def single_logout_service_url(binding = nil)
129169
node = REXML::XPath.first(
130170
document,
131-
"/md:EntityDescriptor/md:IDPSSODescriptor/md:SingleLogoutService/@Location",
171+
"/md:EntityDescriptor/md:IDPSSODescriptor/md:SingleLogoutService#{"[@Binding='#{binding}']" if binding}/@Location",
132172
{ "md" => METADATA }
133173
)
134174
node.value if node

lib/onelogin/ruby-saml/settings.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ def initialize(overrides = {})
2323

2424
# IdP Data
2525
attr_accessor :idp_entity_id
26+
attr_accessor :idp_sso_target_parse_binding_priority
27+
attr_accessor :idp_sso_target_binding
2628
attr_accessor :idp_sso_target_url
29+
attr_accessor :idp_slo_target_parse_binding_priority
30+
attr_accessor :idp_slo_target_binding
2731
attr_accessor :idp_slo_target_url
2832
attr_accessor :idp_cert
2933
attr_accessor :idp_cert_fingerprint

0 commit comments

Comments
 (0)