forked from SAML-Toolkits/ruby-saml
/
authrequest.rb
73 lines (62 loc) · 2.48 KB
/
authrequest.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
61
62
63
64
65
66
67
68
69
70
71
72
73
require "base64"
require "uuid"
require "zlib"
require "cgi"
require "rexml/document"
require "rexml/xpath"
module Onelogin::Saml
include REXML
class Authrequest
def create(settings, params = {})
uuid = "_" + UUID.new.generate
time = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
# Create AuthnRequest root element using REXML
request_doc = REXML::Document.new
root = request_doc.add_element "samlp:AuthnRequest", { "xmlns:samlp" => "urn:oasis:names:tc:SAML:2.0:protocol" }
root.attributes['ID'] = uuid
root.attributes['IssueInstant'] = time
root.attributes['Version'] = "2.0"
# Conditionally defined elements based on settings
if settings.assertion_consumer_service_url != nil
root.attributes["AssertionConsumerServiceURL"] = settings.assertion_consumer_service_url
end
if settings.issuer != nil
issuer = root.add_element "saml:Issuer", { "xmlns:saml" => "urn:oasis:names:tc:SAML:2.0:assertion" }
issuer.text = settings.issuer
end
if settings.name_identifier_format != nil
root.add_element "samlp:NameIDPolicy", {
"xmlns:samlp" => "urn:oasis:names:tc:SAML:2.0:protocol",
# Might want to make AllowCreate a setting?
"AllowCreate" => "true",
"Format" => settings.name_identifier_format
}
end
# BUG fix here -- if an authn_context is defined, add the tags with an "exact"
# match required for authentication to succeed. If this is not defined,
# the IdP will choose default rules for authentication. (Shibboleth IdP)
if settings.authn_context != nil
requested_context = root.add_element "samlp:RequestedAuthnContext", {
"xmlns:samlp" => "urn:oasis:names:tc:SAML:2.0:protocol",
"Comparison" => "exact",
}
class_ref = requested_context.add_element "saml:AuthnContextClassRef", {
"xmlns:saml" => "urn:oasis:names:tc:SAML:2.0:assertion",
}
class_ref.text = settings.authn_context
end
request = ""
request_doc.write(request)
Logging.debug "Created AuthnRequest: #{request}"
deflated_request = Zlib::Deflate.deflate(request, 9)[2..-5]
base64_request = Base64.encode64(deflated_request)
encoded_request = CGI.escape(base64_request)
params_prefix = (settings.idp_sso_target_url =~ /\?/) ? '&' : '?'
request_params = "#{params_prefix}SAMLRequest=#{encoded_request}"
params.each_pair do |key, value|
request_params << "&#{key}=#{CGI.escape(value.to_s)}"
end
settings.idp_sso_target_url + request_params
end
end
end