Class: OneLogin::RubySaml::IdpMetadataParser

Inherits:
Object
  • Object
show all
Includes:
SamlMetadata::Vocabulary
Defined in:
lib/onelogin/ruby-saml/idp_metadata_parser.rb

Overview

Auxiliary class to retrieve and parse the Identity Provider Metadata

This class does not validate in any way the URL that is introduced, make sure to validate it properly before use it in a parse_remote method. Read the ‘Security warning` section of the README.md file to get more info

Defined Under Namespace

Modules: SamlMetadata Classes: IdpMetadata

Constant Summary

Constants included from SamlMetadata::Vocabulary

SamlMetadata::Vocabulary::DSIG, SamlMetadata::Vocabulary::METADATA, SamlMetadata::Vocabulary::NAME_FORMAT, SamlMetadata::Vocabulary::SAML_ASSERTION

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#documentObject (readonly)

Returns the value of attribute document.



37
38
39
# File 'lib/onelogin/ruby-saml/idp_metadata_parser.rb', line 37

def document
  @document
end

#optionsObject (readonly)

Returns the value of attribute options.



39
40
41
# File 'lib/onelogin/ruby-saml/idp_metadata_parser.rb', line 39

def options
  @options
end

#responseObject (readonly)

Returns the value of attribute response.



38
39
40
# File 'lib/onelogin/ruby-saml/idp_metadata_parser.rb', line 38

def response
  @response
end

Class Method Details

.get_idps(metadata_document, only_entity_id = nil) ⇒ Object

fetch IdP descriptors from a metadata document



42
43
44
45
46
47
48
49
# File 'lib/onelogin/ruby-saml/idp_metadata_parser.rb', line 42

def self.get_idps(, only_entity_id=nil)
  path = "//md:EntityDescriptor#{only_entity_id && '[@entityID="' + only_entity_id + '"]'}/md:IDPSSODescriptor"
  REXML::XPath.match(
    ,
    path,
    SamlMetadata::NAMESPACE
  )
end

Instance Method Details

#get_idp_metadata(url, validate_cert) ⇒ REXML::document

Retrieve the remote IdP metadata from the URL or a cached copy.

Parameters:

  • url (String)

    Url where the XML of the Identity Provider Metadata is published.

  • validate_cert (Boolean)

    If true and the URL is HTTPs, the cert of the domain is checked.

Returns:

  • (REXML::document)

    Parsed XML IdP metadata

Raises:

  • (HttpError)

    Failure to fetch remote IdP metadata



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/onelogin/ruby-saml/idp_metadata_parser.rb', line 194

def (url, validate_cert)
  uri = URI.parse(url)
  raise ArgumentError.new("url must begin with http or https") unless /^https?/ =~ uri.scheme
  http = Net::HTTP.new(uri.host, uri.port)

  if uri.scheme == "https"
    http.use_ssl = true
    # Most IdPs will probably use self signed certs
    http.verify_mode = validate_cert ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE

    # Net::HTTP in Ruby 1.8 did not set the default certificate store
    # automatically when VERIFY_PEER was specified.
    if RUBY_VERSION < '1.9' && !http.ca_file && !http.ca_path && !http.cert_store
      http.cert_store = OpenSSL::SSL::SSLContext::DEFAULT_CERT_STORE
    end
  end

  get = Net::HTTP::Get.new(uri.request_uri)
  get.basic_auth uri.user, uri.password if uri.user
  @response = http.request(get)
  return response.body if response.is_a? Net::HTTPSuccess

  raise OneLogin::RubySaml::HttpError.new(
    "Failed to fetch idp metadata: #{response.code}: #{response.message}"
  )
end

#parse(idp_metadata, options = {}) ⇒ OneLogin::RubySaml::Settings

Parse the Identity Provider metadata and update the settings with the IdP values

Parameters:

  • idp_metadata (String)
  • options (Hash) (defaults to: {})

    :settings to provide the OneLogin::RubySaml::Settings object or an hash for Settings overrides

Options Hash (options):

  • :settings (OneLogin::RubySaml::Settings, Hash)

    the OneLogin::RubySaml::Settings object which gets the parsed metadata merged into or an hash for Settings overrides.

  • :entity_id (String, nil)

    when this is given, the entity descriptor for this ID is used. When omitted, the first entity descriptor is used.

  • :sso_binding (String, Array<String>, nil)

    an ordered list of bindings to detect the single signon URL. The first binding in the list that is included in the metadata will be used.

  • :slo_binding (String, Array<String>, nil)

    an ordered list of bindings to detect the single logout URL. The first binding in the list that is included in the metadata will be used.

  • :name_id_format (String, Array<String>, nil)

    an ordered list of NameIDFormats to detect a desired value. The first NameIDFormat in the list that is included in the metadata will be used.

Returns:



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/onelogin/ruby-saml/idp_metadata_parser.rb', line 121

def parse(, options = {})
   = parse_to_hash(, options)

  unless [:cache_duration].nil?
    cache_valid_until_timestamp = OneLogin::RubySaml::Utils.parse_duration([:cache_duration])
    unless cache_valid_until_timestamp.nil?
      if [:valid_until].nil? || cache_valid_until_timestamp < Time.parse([:valid_until], Time.now.utc).to_i
        [:valid_until] = Time.at(cache_valid_until_timestamp).utc.strftime("%Y-%m-%dT%H:%M:%SZ")
      end
    end
  end
  # Remove the cache_duration because on the settings
  # we only gonna suppot valid_until 
  .delete(:cache_duration)

  settings = options[:settings]

  if settings.nil?
    OneLogin::RubySaml::Settings.new()
  elsif settings.is_a?(Hash)
    OneLogin::RubySaml::Settings.new(settings.merge())
  else
    (settings, )
  end
end

#parse_remote(url, validate_cert = true, options = {}) ⇒ OneLogin::RubySaml::Settings

Parse the Identity Provider metadata and update the settings with the IdP values

Parameters:

  • url (String)

    Url where the XML of the Identity Provider Metadata is published.

  • validate_cert (Boolean) (defaults to: true)

    If true and the URL is HTTPs, the cert of the domain is checked.

  • options (Hash) (defaults to: {})

    options used for parsing the metadata and the returned Settings instance

Options Hash (options):

  • :settings (OneLogin::RubySaml::Settings, Hash)

    the OneLogin::RubySaml::Settings object which gets the parsed metadata merged into or an hash for Settings overrides.

  • :entity_id (String, nil)

    when this is given, the entity descriptor for this ID is used. When omitted, the first entity descriptor is used.

  • :sso_binding (String, Array<String>, nil)

    an ordered list of bindings to detect the single signon URL. The first binding in the list that is included in the metadata will be used.

  • :slo_binding (String, Array<String>, nil)

    an ordered list of bindings to detect the single logout URL. The first binding in the list that is included in the metadata will be used.

  • :name_id_format (String, Array<String>, nil)

    an ordered list of NameIDFormats to detect a desired value. The first NameIDFormat in the list that is included in the metadata will be used.

Returns:

Raises:

  • (HttpError)

    Failure to fetch remote IdP metadata



67
68
69
70
# File 'lib/onelogin/ruby-saml/idp_metadata_parser.rb', line 67

def parse_remote(url, validate_cert = true, options = {})
   = (url, validate_cert)
  parse(, options)
end

#parse_remote_to_array(url, validate_cert = true, options = {}) ⇒ Array<Hash>

Parse all Identity Provider metadata and return the results as Array

Parameters:

  • url (String)

    Url where the XML of the Identity Provider Metadata is published.

  • validate_cert (Boolean) (defaults to: true)

    If true and the URL is HTTPs, the cert of the domain is checked.

  • options (Hash) (defaults to: {})

    options used for parsing the metadata

Options Hash (options):

  • :entity_id (String, nil)

    when this is given, the entity descriptor for this ID is used. When omitted, all found IdPs are returned.

  • :sso_binding (String, Array<String>, nil)

    an ordered list of bindings to detect the single signon URL. The first binding in the list that is included in the metadata will be used.

  • :slo_binding (String, Array<String>, nil)

    an ordered list of bindings to detect the single logout URL. The first binding in the list that is included in the metadata will be used.

  • :name_id_format (String, Array<String>, nil)

    an ordered list of NameIDFormats to detect a desired value. The first NameIDFormat in the list that is included in the metadata will be used.

Returns:

  • (Array<Hash>)

Raises:

  • (HttpError)

    Failure to fetch remote IdP metadata



104
105
106
107
# File 'lib/onelogin/ruby-saml/idp_metadata_parser.rb', line 104

def parse_remote_to_array(url, validate_cert = true, options = {})
   = (url, validate_cert)
  parse_to_array(, options)
end

#parse_remote_to_hash(url, validate_cert = true, options = {}) ⇒ Hash

Parse the Identity Provider metadata and return the results as Hash

Parameters:

  • url (String)

    Url where the XML of the Identity Provider Metadata is published.

  • validate_cert (Boolean) (defaults to: true)

    If true and the URL is HTTPs, the cert of the domain is checked.

  • options (Hash) (defaults to: {})

    options used for parsing the metadata

Options Hash (options):

  • :entity_id (String, nil)

    when this is given, the entity descriptor for this ID is used. When omitted, the first entity descriptor is used.

  • :sso_binding (String, Array<String>, nil)

    an ordered list of bindings to detect the single signon URL. The first binding in the list that is included in the metadata will be used.

  • :slo_binding (String, Array<String>, nil)

    an ordered list of bindings to detect the single logout URL. The first binding in the list that is included in the metadata will be used.

  • :name_id_format (String, Array<String>, nil)

    an ordered list of NameIDFormats to detect a desired value. The first NameIDFormat in the list that is included in the metadata will be used.

Returns:

  • (Hash)

Raises:

  • (HttpError)

    Failure to fetch remote IdP metadata



86
87
88
# File 'lib/onelogin/ruby-saml/idp_metadata_parser.rb', line 86

def parse_remote_to_hash(url, validate_cert = true, options = {})
  parse_remote_to_array(url, validate_cert, options)[0]
end

#parse_to_array(idp_metadata, options = {}) ⇒ Array<Hash>

Parse all Identity Provider metadata and return the results as Array

Parameters:

  • idp_metadata (String)
  • options (Hash) (defaults to: {})

    options used for parsing the metadata and the returned Settings instance

Options Hash (options):

  • :entity_id (String, nil)

    when this is given, the entity descriptor for this ID is used. When omitted, all found IdPs are returned.

  • :sso_binding (String, Array<String>, nil)

    an ordered list of bindings to detect the single signon URL. The first binding in the list that is included in the metadata will be used.

  • :slo_binding (String, Array<String>, nil)

    an ordered list of bindings to detect the single logout URL. The first binding in the list that is included in the metadata will be used.

  • :name_id_format (String, Array<String>, nil)

    an ordered list of NameIDFormats to detect a desired value. The first NameIDFormat in the list that is included in the metadata will be used.

Returns:

  • (Array<Hash>)


173
174
175
# File 'lib/onelogin/ruby-saml/idp_metadata_parser.rb', line 173

def parse_to_array(, options = {})
  (, options).map { |idp_md| idp_md.to_hash(options) }
end

#parse_to_hash(idp_metadata, options = {}) ⇒ Hash

Parse the Identity Provider metadata and return the results as Hash

Parameters:

  • idp_metadata (String)
  • options (Hash) (defaults to: {})

    options used for parsing the metadata and the returned Settings instance

Options Hash (options):

  • :entity_id (String, nil)

    when this is given, the entity descriptor for this ID is used. When omitted, the first entity descriptor is used.

  • :sso_binding (String, Array<String>, nil)

    an ordered list of bindings to detect the single signon URL. The first binding in the list that is included in the metadata will be used.

  • :slo_binding (String, Array<String>, nil)

    an ordered list of bindings to detect the single logout URL. The first binding in the list that is included in the metadata will be used.

  • :name_id_format (String, Array<String>, nil)

    an ordered list of NameIDFormats to detect a desired value. The first NameIDFormat in the list that is included in the metadata will be used.

Returns:

  • (Hash)


158
159
160
# File 'lib/onelogin/ruby-saml/idp_metadata_parser.rb', line 158

def parse_to_hash(, options = {})
  parse_to_array(, options)[0]
end

#parse_to_idp_metadata_array(idp_metadata, options = {}) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
# File 'lib/onelogin/ruby-saml/idp_metadata_parser.rb', line 177

def (, options = {})
  @document = REXML::Document.new()
  @options = options

  idpsso_descriptors = self.class.get_idps(@document, options[:entity_id])
  if !idpsso_descriptors.any?
    raise ArgumentError.new("idp_metadata must contain an IDPSSODescriptor element")
  end

  idpsso_descriptors.map {|id| IdpMetadata.new(id, id.parent.attributes["entityID"])}
end