Class: Rack::Shibboleth::Resolver

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/shibboleth/resolver.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(assertion, opts) ⇒ Resolver

Creates a new resolver for the specified assertion document which was decoded from a response to the IdP

Parameters:

  • assertion (LibXML::XML::Document)

    the parsed version of the xml received from the IdP

  • opts (Hash)

    options specified to Rack::Shibboleth


35
36
37
38
# File 'lib/rack/shibboleth/resolver.rb', line 35

def initialize assertion, opts
  @doc  = assertion
  @opts = opts
end

Class Method Details

.from_response(resp, private_key, opts) ⇒ Rack::Shibboleth::Resolver, false

Creates a new Resolver from the IdP's response, using the given private key to decrypt the response.

Parameters:

  • resp (String)

    the 'SAMLResponse' value from the IdP

  • private_key (OpenSSL::PKey::RSA)

    the private key which will be used to decrypt the response

Returns:

  • (Rack::Shibboleth::Resolver, false)

    either the resolver object for the specified response or false if the response could not be decode and/or verified


17
18
19
20
21
22
23
24
25
26
27
# File 'lib/rack/shibboleth/resolver.rb', line 17

def self.from_response resp, private_key, opts
  return nil if resp.nil?
  xml = Base64.decode64 resp
  shib_response = Shibboleth::Response.new xml

  assertion = shib_response.decode private_key
  if assertion
    resolver = Resolver.new assertion, opts
    resolver.valid? ? resolver : nil
  end
end

Instance Method Details

#attributesHash

Extracts the attributes from the response.

Returns:

  • (Hash)

    the key values are the FriendlyNames of each of the attributes as strings and the value is the value listed as a string


86
87
88
89
90
91
92
93
94
95
96
# File 'lib/rack/shibboleth/resolver.rb', line 86

def attributes
  attributes = @doc.find('//saml2:Attribute')
  hash = {}

  attributes.each do |el|
    hash[el['FriendlyName']] =
      el.find_first('.//saml2:AttributeValue').content
  end

  hash
end

#conditionsHash

Extracts the conditions under which this response is valid.

Returns:

  • (Hash)

    with the following keys: :after - [Time] the response is only valid after this time :before - [Time] the response is only valid before this time :audience - [String] the response is only meant for this

    audience specified by their entity name
    

71
72
73
74
75
76
77
78
79
# File 'lib/rack/shibboleth/resolver.rb', line 71

def conditions
  conditions = @doc.find_first('//saml2:Conditions')
  audience = conditions.find_first('.//saml2:Audience')
  {
    :after => Time.parse(conditions['NotBefore']),
    :before => Time.parse(conditions['NotOnOrAfter']),
    :audience => audience.content
  }
end

#issuedTime

The exact time that the response was issued at

Returns:

  • (Time)

    the time this response was issued at


53
54
55
# File 'lib/rack/shibboleth/resolver.rb', line 53

def issued
  Time.parse @doc.find_first('//saml2:Assertion')['IssueInstant']
end

#issuerString

The entity name of the IdP who issued the response

Returns:

  • (String)

    the entity name of the Idp


60
61
62
# File 'lib/rack/shibboleth/resolver.rb', line 60

def issuer
  @doc.find_first('//saml2:Issuer').content
end

#valid?Boolean

Tests whether this response from the IdP is valid based on the conditions specified.

Returns:

  • (Boolean)

    true if the resolver has valid attributes.


44
45
46
47
48
# File 'lib/rack/shibboleth/resolver.rb', line 44

def valid?
  conds = conditions
  conds[:after] <= Time.now && Time.now <= conds[:before] &&
    conds[:audience] == @opts[:issuer]
end