Class: Identizer::Handlers::Saml

Inherits:
Base
  • Object
show all
Defined in:
lib/identizer/handlers/saml.rb

Overview

A real SAML 2.0 IdP: signed metadata, an SSO endpoint that handles SP- and IdP-initiated requests, and a signed-Response auto-POST back to the SP’s assertion consumer service. Signing is done by Identizer::Saml (nokogiri), required lazily so it is only loaded when actually producing a Response.

Constant Summary collapse

EMAIL_FORMAT =
"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
MAX_AUTHN_REQUEST =

reject oversized SAMLRequest (deflate-bomb guard)

100_000

Instance Method Summary collapse

Methods inherited from Base

#initialize

Methods included from Responses

#amz_json, #escape_html, #html, #json, #no_content, #not_found, #notice_page, #redirect, #xml

Constructor Details

This class inherits a constructor from Identizer::Handlers::Base

Instance Method Details

#finish(request) ⇒ Object

Validate the login and POST a signed SAML Response back to the SP.



32
33
34
35
36
37
38
39
40
41
42
# File 'lib/identizer/handlers/saml.rb', line 32

def finish(request)
  email = request.params["email"].to_s.strip
  return saml_error("Invalid credentials") unless request.params["password"] == config.shared_password
  return saml_error("Unknown user: #{escape_html(email)}") unless store.emails.include?(email)

  acs = request.params["acs"].to_s
  return saml_error("ACS not allowed: #{escape_html(acs)}") unless config.acs_allowed?(acs)

  response = build_response(store.identity_for(email), acs, request)
  html(auto_post(acs, response, request.params["relay_state"].to_s))
end

#metadata(request) ⇒ Object



16
17
18
19
20
# File 'lib/identizer/handlers/saml.rb', line 16

def (request)
  headers = {}
  headers["content-disposition"] = "attachment; filename=\"identizer-metadata.xml\"" if request.params["download"]
  xml(, headers: headers)
end

#sso(request) ⇒ Object

SP-initiated (a SAMLRequest) or IdP-initiated (?acs=…): show the login form.



23
24
25
26
27
28
29
# File 'lib/identizer/handlers/saml.rb', line 23

def sso(request)
  context = authn_context(request)
  return json(400, { error: "no AssertionConsumerServiceURL" }) if context[:acs].to_s.empty?
  return saml_error("ACS not allowed: #{escape_html(context[:acs])}") unless config.acs_allowed?(context[:acs])

  (request.script_name, context)
end