Module: SamlCamel::SamlHelpers

Extended by:
ActiveSupport::Concern
Included in:
SamlController
Defined in:
app/controllers/concerns/saml_camel/saml_helpers.rb

Constant Summary collapse

SP_SETTINGS =
JSON.parse(File.read("saml/#{Rails.env}/settings.json"))

Instance Method Summary collapse

Instance Method Details

#expired_session?Boolean

Make it so sp sessions only last 1 hour, sp_session is set on a succesfull saml response. We check that the session time is less than in hour if so we refresh, otherwise we delete the session



37
38
39
40
41
42
43
44
# File 'app/controllers/concerns/saml_camel/saml_helpers.rb', line 37

def expired_session?
  if session[:sp_session]
    if (Time.now - Time.parse(session[:sp_session])) < 1.hour
      session[:sp_session] = Time.now
      return true
    end
  end
end

#saml_protectObject

saml_protect is what is called in the app. it initiates the saml request if there is no active session, or if a user has been idle for over an hour TODO re-factor in future



49
50
51
52
53
# File 'app/controllers/concerns/saml_camel/saml_helpers.rb', line 49

def saml_protect
    not_expired = expired_session?
    saml_request(request) unless (session[:saml_success] || session[:sp_session] || not_expired) #keeps us from looping, and maintains sp session
    session[:saml_success] = nil
end

#saml_request(host_request) ⇒ Object

this generates a call to the idp, which will then be returned to the consume action the in saml_contorller



9
10
11
12
13
14
15
16
17
18
19
20
# File 'app/controllers/concerns/saml_camel/saml_helpers.rb', line 9

def saml_request(host_request)
  relay_state = SecureRandom.base64.chomp.gsub( /\n/, '' ) #set relay state to secure against replay attack
  request = OneLogin::RubySaml::Authrequest.new

  #store relay state, ip address and original url request in memory to be used for verification and redirect after response
  permit_key = session[:session_id].to_sym
  Rails.cache.fetch(permit_key, expires_in: 5.minutes) do
    {ip_address: host_request.remote_ip, relay_state: relay_state, redirect_url:  host_request.url }
  end
  saml_request_url = request.create(SamlCamel::Transaction.saml_settings) + "&RelayState=#{Rails.cache.fetch(permit_key)[:relay_state]}"
  redirect_to(saml_request_url)
end

#valid_state(param_relay_state, remote_ip) ⇒ Object

validates the user ip address and relay state given to IDP. Prevents Replay Attacks.



24
25
26
27
28
29
30
31
32
# File 'app/controllers/concerns/saml_camel/saml_helpers.rb', line 24

def valid_state(param_relay_state, remote_ip)
  permit_key = session[:session_id].to_sym
  saml_cache = Rails.cache.fetch(permit_key)
  stored_relay = saml_cache[:relay_state]
  stored_ip = saml_cache[:ip_address]

  SamlCamel::Logging.saml_state({stored_relay: stored_relay, request_relay: param_relay_state, stored_ip: stored_ip, remote_ip: remote_ip})
  param_relay_state == stored_relay && remote_ip == stored_ip
end