class Samlsso::Logoutresponse

Attributes

document[R]
options[R]
response[R]
settings[RW]

For API compability, this is mutable.

Public Class Methods

new(response, settings = nil, options = {}) click to toggle source

In order to validate that the response matches a given request, append the option:

:matches_request_id => REQUEST_ID

It will validate that the logout response matches the ID of the request. You can also do this yourself through the in_response_to accessor.

# File lib/samlsso/logoutresponse.rb, line 21
def initialize(response, settings = nil, options = {})
  raise ArgumentError.new("Logoutresponse cannot be nil") if response.nil?
  self.settings = settings

  @options = options
  @response = decode_raw_saml(response)
  @document = XMLSecurity::SignedDocument.new(@response)
end

Public Instance Methods

in_response_to() click to toggle source
# File lib/samlsso/logoutresponse.rb, line 47
def in_response_to
  @in_response_to ||= begin
    node = REXML::XPath.first(document, "/p:LogoutResponse", { "p" => PROTOCOL, "a" => ASSERTION })
    node.nil? ? nil : node.attributes['InResponseTo']
  end
end
issuer() click to toggle source
# File lib/samlsso/logoutresponse.rb, line 54
def issuer
  @issuer ||= begin
    node = REXML::XPath.first(document, "/p:LogoutResponse/a:Issuer", { "p" => PROTOCOL, "a" => ASSERTION })
    node ||= REXML::XPath.first(document, "/p:LogoutResponse/a:Assertion/a:Issuer", { "p" => PROTOCOL, "a" => ASSERTION })
    node.nil? ? nil : node.text
  end
end
status_code() click to toggle source
# File lib/samlsso/logoutresponse.rb, line 62
def status_code
  @status_code ||= begin
    node = REXML::XPath.first(document, "/p:LogoutResponse/p:Status/p:StatusCode", { "p" => PROTOCOL, "a" => ASSERTION })
    node.nil? ? nil : node.attributes["Value"]
  end
end
success?(soft = true) click to toggle source
# File lib/samlsso/logoutresponse.rb, line 40
def success?(soft = true)
  unless status_code == "urn:oasis:names:tc:SAML:2.0:status:Success"
    return soft ? false : validation_error("Bad status code. Expected <urn:oasis:names:tc:SAML:2.0:status:Success>, but was: <#@status_code> ")
  end
  true
end
validate(soft = true) click to toggle source
# File lib/samlsso/logoutresponse.rb, line 34
def validate(soft = true)
  return false unless valid_saml?(document, soft) && valid_state?(soft)

  valid_in_response_to?(soft) && valid_issuer?(soft) && success?(soft)
end
validate!() click to toggle source
# File lib/samlsso/logoutresponse.rb, line 30
def validate!
  validate(false)
end

Private Instance Methods

valid_in_response_to?(soft = true) click to toggle source
# File lib/samlsso/logoutresponse.rb, line 91
def valid_in_response_to?(soft = true)
  return true unless self.options.has_key? :matches_request_id

  unless self.options[:matches_request_id] == in_response_to
    return soft ? false : validation_error("Response does not match the request ID, expected: <#{self.options[:matches_request_id]}>, but was: <#{in_response_to}>")
  end

  true
end
valid_issuer?(soft = true) click to toggle source
# File lib/samlsso/logoutresponse.rb, line 101
def valid_issuer?(soft = true)
  return true if self.settings.idp_entity_id.nil? or self.issuer.nil?

  unless URI.parse(self.issuer) == URI.parse(self.settings.idp_entity_id)
    return soft ? false : validation_error("Doesn't match the issuer, expected: <#{self.settings.issuer}>, but was: <#{issuer}>")
  end
  true
end
valid_state?(soft = true) click to toggle source
# File lib/samlsso/logoutresponse.rb, line 71
def valid_state?(soft = true)
  if response.empty?
    return soft ? false : validation_error("Blank response")
  end

  if settings.nil?
    return soft ? false : validation_error("No settings on response")
  end

  if settings.issuer.nil?
    return soft ? false : validation_error("No issuer in settings")
  end

  if settings.idp_cert_fingerprint.nil? && settings.idp_cert.nil?
    return soft ? false : validation_error("No fingerprint or certificate on settings")
  end

  true
end