Class: OmniAuth::Strategies::SAML::ServiceTicketValidator

Inherits:
CAS::ServiceTicketValidator
  • Object
show all
Defined in:
lib/omni_auth/strategies/saml/service_ticket_validator.rb

Constant Summary collapse

ART_TEMPLATE =
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
"<SOAP-ENV:Header/><SOAP-ENV:Body>" +
"<samlp:Request IssueInstant=\"%s\" RequestID=\"%s\" MajorVersion=\"1\" MinorVersion=\"1\" xmlns:samlp=\"urn:oasis:names:tc:SAML:1.0:protocol\">" +
"<samlp:AssertionArtifact>%s</samlp:AssertionArtifact>" +
"</samlp:Request>" +
"</SOAP-ENV:Body>" +
"</SOAP-ENV:Envelope>"
NAME_ID_XPATH =
'./samla:Assertion/samla:AuthenticationStatement/samla:Subject/samla:NameIdentifier'
AFFIL_VALUE_XPATH =
'./samla:Assertion/samla:AttributeStatement/samla:Attribute[@AttributeName=\'affiliation\']/samla:AttributeValue'

Instance Method Summary collapse

Constructor Details

#initialize(strategy, options, return_to_url, ticket) ⇒ ServiceTicketValidator

Returns a new instance of ServiceTicketValidator.



18
19
20
21
22
# File 'lib/omni_auth/strategies/saml/service_ticket_validator.rb', line 18

def initialize(strategy, options, return_to_url, ticket)
  super
  @ticket = ticket
  @ticket_host = URI(return_to_url).host
end

Instance Method Details

#find_authentication_success(body) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/omni_auth/strategies/saml/service_ticket_validator.rb', line 30

def find_authentication_success(body)
  return nil if body.nil? || body == ''
  begin
    doc = Nokogiri::XML(body)
    begin
      prefix = nil
      doc.xpath('//sprot:Response',SAML_NS).each do |n|
        n.namespace_definitions.each do |ns|
          if ns.href == 'urn:oasis:names:tc:SAML:1.0:protocol'
            prefix = ns.prefix
          end
          prefix ||= n.namespace.prefix
        end
      end
      prefix = prefix + ':' if prefix
      xpath = '//sprot:Response/sprot:Status/sprot:StatusCode[@Value=\'' + prefix + 'Success\']/../..'
      doc.xpath(xpath, SAML_NS)
    rescue Nokogiri::XML::XPath::SyntaxError
      doc.xpath('//Response/Status/StatusCode[@Value=\'Success\']/../..')
    end
  rescue Nokogiri::XML::XPath::SyntaxError
    nil
  end
end

#get_service_request_bodyObject



54
55
56
# File 'lib/omni_auth/strategies/saml/service_ticket_validator.rb', line 54

def get_service_request_body
  ART_TEMPLATE % [Time.now.utc.iso8601(3), SecureRandom.hex(16), @ticket]
end

#get_service_response_bodyObject

retrieves the ‘<sprot:Response>` XML from the CAS server



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/omni_auth/strategies/saml/service_ticket_validator.rb', line 58

def get_service_response_body
  result = ''
  http = Net::HTTP.new(@uri.host, @uri.port)
  http.use_ssl = @uri.port == 443 || @uri.instance_of?(URI::HTTPS)
  if http.use_ssl?
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @options.disable_ssl_verification?
    http.ca_path = @options.ca_path
  end
  http.start do |c|
    body = get_service_request_body
    headers = {
      "Content-Type"=>"text/xml",
      "Content-Length" => body.size.to_s,
      'SOAPAction' => "http://www.oasis-open.org/committees/security"
    }
    response = c.post "#{@uri.path}?#{@uri.query}", body, headers
    result = response.body
  end
  result
end

#parse_user_info(node) ⇒ Object



23
24
25
26
27
28
29
# File 'lib/omni_auth/strategies/saml/service_ticket_validator.rb', line 23

def (node)
  return nil if node.nil?
  {}.tap do |hash|
    node.xpath(NAME_ID_XPATH, SAML_NS).each {|n| hash['user'] = n.text }
    hash['affiliations'] = node.xpath(AFFIL_VALUE_XPATH, SAML_NS).inject([]) {|m,v| m << v.text; m}
  end
end