class OneLogin::RubySaml::IdpMetadataParser

Auxiliary class to retrieve and parse the Identity Provider Metadata

Constants

DSIG
METADATA

Attributes

document[R]
response[R]

Public Instance Methods

parse(idp_metadata) click to toggle source

Parse the Identity Provider metadata and update the settings with the IdP values @param idp_metadata [String]

# File lib/onelogin/ruby-saml/idp_metadata_parser.rb, line 39
def parse(idp_metadata)
  @document = REXML::Document.new(idp_metadata)

  OneLogin::RubySaml::Settings.new.tap do |settings|
    settings.idp_entity_id = idp_entity_id
    settings.name_identifier_format = idp_name_id_format
    settings.idp_sso_target_url = single_signon_service_url
    settings.idp_slo_target_url = single_logout_service_url
    settings.idp_cert_fingerprint = fingerprint
  end
end
parse_remote(url, validate_cert = true) click to toggle source

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

@param (see IdpMetadataParser#get_idp_metadata) @return (see IdpMetadataParser#get_idp_metadata) @raise (see IdpMetadataParser#get_idp_metadata)

# File lib/onelogin/ruby-saml/idp_metadata_parser.rb, line 31
def parse_remote(url, validate_cert = true)
  idp_metadata = get_idp_metadata(url, validate_cert)
  parse(idp_metadata)
end

Private Instance Methods

certificate() click to toggle source

@return [String|nil] X509Certificate if exists

# File lib/onelogin/ruby-saml/idp_metadata_parser.rb, line 138
def certificate
  @certificate ||= begin
    node = REXML::XPath.first(
      document,
      "/md:EntityDescriptor/md:IDPSSODescriptor/md:KeyDescriptor[@use='signing']/ds:KeyInfo/ds:X509Data/ds:X509Certificate",
      { "md" => METADATA, "ds" => DSIG }
    )
    Base64.decode64(node.text) if node
  end
end
fingerprint() click to toggle source

@return [String|nil] the SHA-1 fingerpint of the X509Certificate if it exists

# File lib/onelogin/ruby-saml/idp_metadata_parser.rb, line 151
def fingerprint
  @fingerprint ||= begin
    if certificate
      cert = OpenSSL::X509::Certificate.new(certificate)
      Digest::SHA1.hexdigest(cert.to_der).upcase.scan(/../).join(":")
    end
  end
end
get_idp_metadata(url, validate_cert) click to toggle source

Retrieve the remote IdP metadata from the URL or a cached copy. @param url [String] Url where the XML of the Identity Provider Metadata is published. @param validate_cert [Boolean] If true and the URL is HTTPs, the cert of the domain is checked. @return [REXML::document] Parsed XML IdP metadata @raise [HttpError] Failure to fetch remote IdP metadata

# File lib/onelogin/ruby-saml/idp_metadata_parser.rb, line 58
def get_idp_metadata(url, validate_cert)
  uri = URI.parse(url)
  if uri.scheme == "http"
    response = Net::HTTP.get_response(uri)
    meta_text = response.body
  elsif uri.scheme == "https"
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    # Most IdPs will probably use self signed certs
    if validate_cert
      http.verify_mode = OpenSSL::SSL::VERIFY_PEER

      # 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
    else
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE
    end
    get = Net::HTTP::Get.new(uri.request_uri)
    response = http.request(get)
    meta_text = response.body
  else
    raise ArgumentError.new("url must begin with http or https")
  end

  unless response.is_a? Net::HTTPSuccess
    raise OneLogin::RubySaml::HttpError.new("Failed to fetch idp metadata")
  end

  meta_text
end
idp_entity_id() click to toggle source

@return [String|nil] IdP Entity ID value if exists

# File lib/onelogin/ruby-saml/idp_metadata_parser.rb, line 94
def idp_entity_id
  node = REXML::XPath.first(
    document,
    "/md:EntityDescriptor/@entityID",
    { "md" => METADATA }
  )
  node.value if node
end
idp_name_id_format() click to toggle source

@return [String|nil] IdP Name ID Format value if exists

# File lib/onelogin/ruby-saml/idp_metadata_parser.rb, line 105
def idp_name_id_format
  node = REXML::XPath.first(
    document,
    "/md:EntityDescriptor/md:IDPSSODescriptor/md:NameIDFormat",
    { "md" => METADATA }
  )
  node.text if node
end
single_logout_service_url() click to toggle source

@return [String|nil] SingleLogoutService endpoint if exists

# File lib/onelogin/ruby-saml/idp_metadata_parser.rb, line 127
def single_logout_service_url
  node = REXML::XPath.first(
    document,
    "/md:EntityDescriptor/md:IDPSSODescriptor/md:SingleLogoutService/@Location",
    { "md" => METADATA }
  )
  node.value if node
end
single_signon_service_url() click to toggle source

@return [String|nil] SingleSignOnService endpoint if exists

# File lib/onelogin/ruby-saml/idp_metadata_parser.rb, line 116
def single_signon_service_url
  node = REXML::XPath.first(
    document,
    "/md:EntityDescriptor/md:IDPSSODescriptor/md:SingleSignOnService/@Location",
    { "md" => METADATA }
  )
  node.value if node
end