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



27
28
29
30
31
32
33
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
# File 'lib/omniauth/strategies/saml.rb', line 27

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

  response.validate!

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

#other_phaseObject



74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/omniauth/strategies/saml.rb', line 74

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)
    Rack::Response.new(response.generate(settings), 200, { "Content-Type" => "application/xml" }).finish
  else
    call_app!
  end
end

#request_phaseObject



12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/omniauth/strategies/saml.rb', line 12

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.



63
64
65
66
67
68
69
70
71
72
# File 'lib/omniauth/strategies/saml.rb', line 63

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