@@ -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
0 commit comments