Class: OmniAuth::Strategies::SAML

Inherits:
Object
  • Object
show all
Includes:
OmniAuth::Strategy
Defined in:
lib/omniauth/strategies/saml.rb,
lib/omniauth/strategies/saml/validation_error.rb

Defined Under Namespace

Classes: ValidationError

Instance Method Summary collapse

Instance Method Details

#callback_phaseObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/omniauth/strategies/saml.rb', line 34

def callback_phase
  unless request.params['SAMLResponse']
    raise OmniAuth::Strategies::SAML::ValidationError.new("SAML response missing")
  end

  # Call a fingerprint validation method if there's one
  if options.idp_cert_fingerprint_validator
    fingerprint_exists = options.idp_cert_fingerprint_validator[response_fingerprint]
    unless fingerprint_exists
      raise OmniAuth::Strategies::SAML::ValidationError.new("Non-existent fingerprint")
    end
    # id_cert_fingerprint becomes the given fingerprint if it exists
    options.idp_cert_fingerprint = fingerprint_exists
  end

  response = OneLogin::RubySaml::Response.new(request.params['SAMLResponse'], options)
  response.settings = OneLogin::RubySaml::Settings.new(options)
  response.attributes['fingerprint'] = options.idp_cert_fingerprint

  @name_id = response.name_id
  @attributes = response.attributes

  if @name_id.nil? || @name_id.empty?
    raise OmniAuth::Strategies::SAML::ValidationError.new("SAML response missing 'name_id'")
  end

  # will raise an error since we are not in soft mode
  response.soft = false
  response.is_valid?

  super
rescue OmniAuth::Strategies::SAML::ValidationError
  fail!(:invalid_ticket, $!)
rescue OneLogin::RubySaml::ValidationError
  fail!(:invalid_ticket, $!)
end

#other_phaseObject



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/omniauth/strategies/saml.rb', line 83

def other_phase
  if on_path?("#{request_path}/metadata")
    # omniauth does not set the strategy on the other_phase
    @env['omniauth.strategy'] ||= self
    setup_phase

    response = OneLogin::RubySaml::Metadata.new
    settings = OneLogin::RubySaml::Settings.new(options)
    if options.request_attributes.length > 0
      settings.attribute_consuming_service.service_name options.attribute_service_name
      options.request_attributes.each do |attribute|
        settings.attribute_consuming_service.add_attribute attribute
      end
    end
    Rack::Response.new(response.generate(settings), 200, { "Content-Type" => "application/xml" }).finish
  else
    call_app!
  end
end

#request_phaseObject



19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/omniauth/strategies/saml.rb', line 19

def request_phase
  options[:assertion_consumer_service_url] ||= callback_url
  runtime_request_parameters = options.delete(:idp_sso_target_url_runtime_params)

  additional_params = {}
  runtime_request_parameters.each_pair do |request_param_key, mapped_param_key|
    additional_params[mapped_param_key] = request.params[request_param_key.to_s] if request.params.has_key?(request_param_key.to_s)
  end if runtime_request_parameters

  authn_request = OneLogin::RubySaml::Authrequest.new
  settings = OneLogin::RubySaml::Settings.new(options)

  redirect(authn_request.create(settings, additional_params))
end

#response_fingerprintObject

Obtain an idp certificate fingerprint from the response.



72
73
74
75
76
77
78
79
80
81
# File 'lib/omniauth/strategies/saml.rb', line 72

def response_fingerprint
  response = request.params['SAMLResponse']
  response = (response =~ /^</) ? response : Base64.decode64(response)
  document = XMLSecurity::SignedDocument::new(response)
  cert_element = REXML::XPath.first(document, "//ds:X509Certificate", { "ds"=> 'http://www.w3.org/2000/09/xmldsig#' })
  base64_cert = cert_element.text
  cert_text = Base64.decode64(base64_cert)
  cert = OpenSSL::X509::Certificate.new(cert_text)
  Digest::SHA1.hexdigest(cert.to_der).upcase.scan(/../).join(':')
end