ruby-saml 0.4.5 → 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ruby-saml might be problematic. Click here for more details.
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/lib/onelogin/saml.rb +1 -0
- data/lib/onelogin/saml/response.rb +54 -19
- data/lib/onelogin/saml/validation_error.rb +7 -0
- data/lib/xml_security.rb +35 -21
- data/ruby-saml.gemspec +15 -4
- data/test/request_test.rb +33 -0
- data/test/{ruby-saml_test.rb → response_test.rb} +34 -56
- data/test/responses/adfs_response.xml.base64 +91 -0
- data/test/responses/open_saml_response.xml +56 -0
- data/test/responses/simple_saml_php.xml +71 -0
- data/test/settings_test.rb +23 -0
- data/test/test_helper.rb +10 -0
- data/test/xml_security_test.rb +1 -1
- metadata +29 -7
data/Rakefile
CHANGED
@@ -13,6 +13,7 @@ begin
|
|
13
13
|
gem.add_dependency("canonix","~> 0.1")
|
14
14
|
gem.add_dependency("uuid","~> 2.3")
|
15
15
|
gem.add_development_dependency "shoulda"
|
16
|
+
gem.add_development_dependency "ruby-debug"
|
16
17
|
gem.add_development_dependency "mocha"
|
17
18
|
#gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
19
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.6
|
data/lib/onelogin/saml.rb
CHANGED
@@ -2,48 +2,38 @@ require "xml_security"
|
|
2
2
|
require "time"
|
3
3
|
|
4
4
|
module Onelogin::Saml
|
5
|
+
|
5
6
|
class Response
|
6
7
|
ASSERTION = "urn:oasis:names:tc:SAML:2.0:assertion"
|
7
8
|
PROTOCOL = "urn:oasis:names:tc:SAML:2.0:protocol"
|
8
9
|
DSIG = "http://www.w3.org/2000/09/xmldsig#"
|
9
10
|
|
10
|
-
attr_accessor :
|
11
|
+
attr_accessor :options, :response, :document, :settings
|
11
12
|
|
12
|
-
def initialize(response)
|
13
|
+
def initialize(response, options = {})
|
13
14
|
raise ArgumentError.new("Response cannot be nil") if response.nil?
|
15
|
+
self.options = options
|
14
16
|
self.response = response
|
15
17
|
self.document = XMLSecurity::SignedDocument.new(Base64.decode64(response))
|
16
18
|
end
|
17
19
|
|
18
20
|
def is_valid?
|
19
|
-
|
20
|
-
|
21
|
-
return false if settings.idp_cert_fingerprint.nil?
|
22
|
-
return false if !check_conditions
|
21
|
+
validate(soft = true)
|
22
|
+
end
|
23
23
|
|
24
|
-
|
24
|
+
def validate!
|
25
|
+
validate(soft = false)
|
25
26
|
end
|
26
27
|
|
27
28
|
# The value of the user identifier as designated by the initialization request response
|
28
29
|
def name_id
|
29
30
|
@name_id ||= begin
|
30
31
|
node = REXML::XPath.first(document, "/p:Response/a:Assertion[@ID='#{document.signed_element_id[1,document.signed_element_id.size]}']/a:Subject/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
|
32
|
+
node ||= REXML::XPath.first(document, "/p:Response[@ID='#{document.signed_element_id[1,document.signed_element_id.size]}']/a:Assertion/a:Subject/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
|
31
33
|
node.nil? ? nil : node.text
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
35
|
-
def check_conditions
|
36
|
-
return true if conditions.nil?
|
37
|
-
|
38
|
-
not_before = parse_time(conditions, "NotBefore")
|
39
|
-
return false if not_before && Time.now.utc < not_before
|
40
|
-
|
41
|
-
not_on_or_after = parse_time(conditions, "NotOnOrAfter")
|
42
|
-
return false if not_on_or_after && Time.now.utc >= not_on_or_after
|
43
|
-
|
44
|
-
true
|
45
|
-
end
|
46
|
-
|
47
37
|
# A hash of alle the attributes with the response. Assuming there is only one value for each key
|
48
38
|
def attributes
|
49
39
|
@attr_statements ||= begin
|
@@ -84,6 +74,51 @@ module Onelogin::Saml
|
|
84
74
|
|
85
75
|
private
|
86
76
|
|
77
|
+
def validation_error(message)
|
78
|
+
raise ValidationError.new(message)
|
79
|
+
end
|
80
|
+
|
81
|
+
def validate(soft = true)
|
82
|
+
validate_response_state(soft) &&
|
83
|
+
validate_conditions(soft) &&
|
84
|
+
document.validate(settings.idp_cert_fingerprint, soft)
|
85
|
+
end
|
86
|
+
|
87
|
+
def validate_response_state(soft = true)
|
88
|
+
if response.empty?
|
89
|
+
return soft ? false : validation_error("Blank response")
|
90
|
+
end
|
91
|
+
|
92
|
+
if settings.nil?
|
93
|
+
return soft ? false : validation_error("No settings on response")
|
94
|
+
end
|
95
|
+
|
96
|
+
if settings.idp_cert_fingerprint.nil?
|
97
|
+
return soft ? false : validation_error("No fingerprint on settings")
|
98
|
+
end
|
99
|
+
|
100
|
+
true
|
101
|
+
end
|
102
|
+
|
103
|
+
def validate_conditions(soft = true)
|
104
|
+
return true if conditions.nil?
|
105
|
+
return true if options[:skip_conditions]
|
106
|
+
|
107
|
+
if not_before = parse_time(conditions, "NotBefore")
|
108
|
+
if Time.now.utc < not_before
|
109
|
+
return soft ? false : validation_error("Current time is earlier than NotBefore condition")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
if not_on_or_after = parse_time(conditions, "NotOnOrAfter")
|
114
|
+
if Time.now.utc >= not_on_or_after
|
115
|
+
return soft ? false : validation_error("Current time is on or after NotOnOrAfter condition")
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
true
|
120
|
+
end
|
121
|
+
|
87
122
|
def parse_time(node, attribute)
|
88
123
|
if node && node.attributes[attribute]
|
89
124
|
Time.parse(node.attributes[attribute])
|
data/lib/xml_security.rb
CHANGED
@@ -28,11 +28,12 @@ require "rexml/xpath"
|
|
28
28
|
require "openssl"
|
29
29
|
require "xmlcanonicalizer"
|
30
30
|
require "digest/sha1"
|
31
|
+
require "onelogin/saml/validation_error"
|
31
32
|
|
32
33
|
module XMLSecurity
|
33
34
|
|
34
35
|
class SignedDocument < REXML::Document
|
35
|
-
DSIG
|
36
|
+
DSIG = "http://www.w3.org/2000/09/xmldsig#"
|
36
37
|
|
37
38
|
attr_accessor :signed_element_id
|
38
39
|
|
@@ -41,7 +42,7 @@ module XMLSecurity
|
|
41
42
|
extract_signed_element_id
|
42
43
|
end
|
43
44
|
|
44
|
-
def validate
|
45
|
+
def validate(idp_cert_fingerprint, soft = true)
|
45
46
|
# get cert from response
|
46
47
|
base64_cert = self.elements["//ds:X509Certificate"].text
|
47
48
|
cert_text = Base64.decode64(base64_cert)
|
@@ -49,33 +50,44 @@ module XMLSecurity
|
|
49
50
|
|
50
51
|
# check cert matches registered idp cert
|
51
52
|
fingerprint = Digest::SHA1.hexdigest(cert.to_der)
|
52
|
-
valid_flag = fingerprint == idp_cert_fingerprint.gsub(/[^a-zA-Z0-9]/,"").downcase
|
53
53
|
|
54
|
-
|
54
|
+
if fingerprint != idp_cert_fingerprint.gsub(/[^a-zA-Z0-9]/,"").downcase
|
55
|
+
return soft ? false : (raise Onelogin::Saml::ValidationError.new("Fingerprint mismatch"))
|
56
|
+
end
|
55
57
|
|
56
|
-
validate_doc(base64_cert,
|
58
|
+
validate_doc(base64_cert, soft)
|
57
59
|
end
|
58
60
|
|
59
|
-
def validate_doc(base64_cert,
|
61
|
+
def validate_doc(base64_cert, soft = true)
|
60
62
|
# validate references
|
63
|
+
|
64
|
+
# check for inclusive namespaces
|
65
|
+
|
66
|
+
inclusive_namespaces = []
|
67
|
+
inclusive_namespace_element = REXML::XPath.first(self, "//ec:InclusiveNamespaces")
|
68
|
+
|
69
|
+
if inclusive_namespace_element
|
70
|
+
prefix_list = inclusive_namespace_element.attributes.get_attribute('PrefixList').value
|
71
|
+
inclusive_namespaces = prefix_list.split(" ")
|
72
|
+
end
|
61
73
|
|
62
74
|
# remove signature node
|
63
75
|
sig_element = REXML::XPath.first(self, "//ds:Signature", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"})
|
64
76
|
sig_element.remove
|
65
77
|
|
66
|
-
#check digests
|
67
|
-
REXML::XPath.each(sig_element, "//ds:Reference", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"}) do |
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
canoner
|
72
|
-
canon_hashed_element
|
73
|
-
hash
|
74
|
-
digest_value
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
78
|
+
# check digests
|
79
|
+
REXML::XPath.each(sig_element, "//ds:Reference", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"}) do |ref|
|
80
|
+
uri = ref.attributes.get_attribute("URI").value
|
81
|
+
hashed_element = REXML::XPath.first(self, "//[@ID='#{uri[1,uri.size]}']")
|
82
|
+
canoner = XML::Util::XmlCanonicalizer.new(false, true)
|
83
|
+
canoner.inclusive_namespaces = inclusive_namespaces if canoner.respond_to?(:inclusive_namespaces) && !inclusive_namespaces.empty?
|
84
|
+
canon_hashed_element = canoner.canonicalize(hashed_element)
|
85
|
+
hash = Base64.encode64(Digest::SHA1.digest(canon_hashed_element)).chomp
|
86
|
+
digest_value = REXML::XPath.first(ref, "//ds:DigestValue", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"}).text
|
87
|
+
|
88
|
+
if hash != digest_value
|
89
|
+
return soft ? false : (raise Onelogin::Saml::ValidationError.new("Digest mismatch"))
|
90
|
+
end
|
79
91
|
end
|
80
92
|
|
81
93
|
# verify signature
|
@@ -90,9 +102,11 @@ module XMLSecurity
|
|
90
102
|
cert_text = Base64.decode64(base64_cert)
|
91
103
|
cert = OpenSSL::X509::Certificate.new(cert_text)
|
92
104
|
|
93
|
-
|
105
|
+
if !cert.public_key.verify(OpenSSL::Digest::SHA1.new, signature, canon_string)
|
106
|
+
return soft ? false : (raise ValidationError.new("Key validation error"))
|
107
|
+
end
|
94
108
|
|
95
|
-
return
|
109
|
+
return true
|
96
110
|
end
|
97
111
|
|
98
112
|
private
|
data/ruby-saml.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ruby-saml}
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["OneLogin LLC"]
|
12
|
-
s.date = %q{2011-06-
|
12
|
+
s.date = %q{2011-06-28}
|
13
13
|
s.description = %q{SAML toolkit for Ruby on Rails}
|
14
14
|
s.email = %q{support@onelogin.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -27,16 +27,22 @@ Gem::Specification.new do |s|
|
|
27
27
|
"lib/onelogin/saml/authrequest.rb",
|
28
28
|
"lib/onelogin/saml/response.rb",
|
29
29
|
"lib/onelogin/saml/settings.rb",
|
30
|
+
"lib/onelogin/saml/validation_error.rb",
|
30
31
|
"lib/ruby-saml.rb",
|
31
32
|
"lib/xml_security.rb",
|
32
33
|
"ruby-saml.gemspec",
|
34
|
+
"test/request_test.rb",
|
35
|
+
"test/response_test.rb",
|
36
|
+
"test/responses/adfs_response.xml.base64",
|
33
37
|
"test/responses/certificate1",
|
38
|
+
"test/responses/open_saml_response.xml",
|
34
39
|
"test/responses/response1.xml.base64",
|
35
40
|
"test/responses/response2.xml.base64",
|
36
41
|
"test/responses/response3.xml.base64",
|
37
42
|
"test/responses/response4.xml.base64",
|
38
43
|
"test/responses/response5.xml.base64",
|
39
|
-
"test/
|
44
|
+
"test/responses/simple_saml_php.xml",
|
45
|
+
"test/settings_test.rb",
|
40
46
|
"test/test_helper.rb",
|
41
47
|
"test/xml_security_test.rb"
|
42
48
|
]
|
@@ -46,7 +52,9 @@ Gem::Specification.new do |s|
|
|
46
52
|
s.rubygems_version = %q{1.3.7}
|
47
53
|
s.summary = %q{SAML Ruby Tookit}
|
48
54
|
s.test_files = [
|
49
|
-
"test/
|
55
|
+
"test/request_test.rb",
|
56
|
+
"test/response_test.rb",
|
57
|
+
"test/settings_test.rb",
|
50
58
|
"test/test_helper.rb",
|
51
59
|
"test/xml_security_test.rb"
|
52
60
|
]
|
@@ -59,17 +67,20 @@ Gem::Specification.new do |s|
|
|
59
67
|
s.add_runtime_dependency(%q<canonix>, ["~> 0.1"])
|
60
68
|
s.add_runtime_dependency(%q<uuid>, ["~> 2.3"])
|
61
69
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
70
|
+
s.add_development_dependency(%q<ruby-debug>, [">= 0"])
|
62
71
|
s.add_development_dependency(%q<mocha>, [">= 0"])
|
63
72
|
else
|
64
73
|
s.add_dependency(%q<canonix>, ["~> 0.1"])
|
65
74
|
s.add_dependency(%q<uuid>, ["~> 2.3"])
|
66
75
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
76
|
+
s.add_dependency(%q<ruby-debug>, [">= 0"])
|
67
77
|
s.add_dependency(%q<mocha>, [">= 0"])
|
68
78
|
end
|
69
79
|
else
|
70
80
|
s.add_dependency(%q<canonix>, ["~> 0.1"])
|
71
81
|
s.add_dependency(%q<uuid>, ["~> 2.3"])
|
72
82
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
83
|
+
s.add_dependency(%q<ruby-debug>, [">= 0"])
|
73
84
|
s.add_dependency(%q<mocha>, [">= 0"])
|
74
85
|
end
|
75
86
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
|
2
|
+
|
3
|
+
class RequestTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "Authrequest" do
|
6
|
+
should "create the deflated SAMLRequest URL parameter" do
|
7
|
+
settings = Onelogin::Saml::Settings.new
|
8
|
+
settings.idp_sso_target_url = "http://stuff.com"
|
9
|
+
auth_url = Onelogin::Saml::Authrequest.new.create(settings)
|
10
|
+
assert auth_url =~ /^http:\/\/stuff\.com\?SAMLRequest=/
|
11
|
+
payload = CGI.unescape(auth_url.split("=").last)
|
12
|
+
decoded = Base64.decode64(payload)
|
13
|
+
|
14
|
+
zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
|
15
|
+
inflated = zstream.inflate(decoded)
|
16
|
+
zstream.finish
|
17
|
+
zstream.close
|
18
|
+
|
19
|
+
assert_match /^<samlp:AuthnRequest/, inflated
|
20
|
+
end
|
21
|
+
|
22
|
+
should "accept extra parameters" do
|
23
|
+
settings = Onelogin::Saml::Settings.new
|
24
|
+
settings.idp_sso_target_url = "http://stuff.com"
|
25
|
+
|
26
|
+
auth_url = Onelogin::Saml::Authrequest.new.create(settings, { :hello => "there" })
|
27
|
+
assert auth_url =~ /&hello=there$/
|
28
|
+
|
29
|
+
auth_url = Onelogin::Saml::Authrequest.new.create(settings, { :hello => nil })
|
30
|
+
assert auth_url =~ /&hello=$/
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -2,30 +2,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
|
|
2
2
|
|
3
3
|
class RubySamlTest < Test::Unit::TestCase
|
4
4
|
|
5
|
-
context "Settings" do
|
6
|
-
setup do
|
7
|
-
@settings = Onelogin::Saml::Settings.new
|
8
|
-
end
|
9
|
-
should "should provide getters and settings" do
|
10
|
-
accessors = [
|
11
|
-
:assertion_consumer_service_url, :issuer, :sp_name_qualifier, :sp_name_qualifier,
|
12
|
-
:idp_sso_target_url, :idp_cert_fingerprint, :name_identifier_format
|
13
|
-
]
|
14
|
-
|
15
|
-
accessors.each do |accessor|
|
16
|
-
value = Kernel.rand
|
17
|
-
@settings.send("#{accessor}=".to_sym, value)
|
18
|
-
assert_equal value, @settings.send(accessor)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
5
|
context "Response" do
|
24
|
-
should "provide setter for a logger" do
|
25
|
-
response = Onelogin::Saml::Response.new('')
|
26
|
-
assert response.logger = 'hello'
|
27
|
-
end
|
28
|
-
|
29
6
|
should "raise an exception when response is initialized with nil" do
|
30
7
|
assert_raises(ArgumentError) { Onelogin::Saml::Response.new(nil) }
|
31
8
|
end
|
@@ -39,6 +16,15 @@ class RubySamlTest < Test::Unit::TestCase
|
|
39
16
|
assert !response.name_id.nil?
|
40
17
|
end
|
41
18
|
|
19
|
+
context "#validate!" do
|
20
|
+
should "raise when encountering a condition that prevents the document from being valid" do
|
21
|
+
response = Onelogin::Saml::Response.new(response_document)
|
22
|
+
assert_raise(Onelogin::Saml::ValidationError) do
|
23
|
+
response.validate!
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
42
28
|
context "#is_valid?" do
|
43
29
|
should "return false when response is initialized with blank data" do
|
44
30
|
response = Onelogin::Saml::Response.new('')
|
@@ -52,7 +38,7 @@ class RubySamlTest < Test::Unit::TestCase
|
|
52
38
|
|
53
39
|
should "return true when the response is initialized with valid data" do
|
54
40
|
response = Onelogin::Saml::Response.new(response_document_4)
|
55
|
-
response.
|
41
|
+
response.stubs(:conditions).returns(nil)
|
56
42
|
assert !response.is_valid?
|
57
43
|
settings = Onelogin::Saml::Settings.new
|
58
44
|
assert !response.is_valid?
|
@@ -64,13 +50,22 @@ class RubySamlTest < Test::Unit::TestCase
|
|
64
50
|
|
65
51
|
should "not allow signature wrapping attack" do
|
66
52
|
response = Onelogin::Saml::Response.new(response_document_4)
|
67
|
-
response.
|
53
|
+
response.stubs(:conditions).returns(nil)
|
68
54
|
settings = Onelogin::Saml::Settings.new
|
69
55
|
settings.idp_cert_fingerprint = signature_fingerprint_1
|
70
56
|
response.settings = settings
|
71
57
|
assert response.is_valid?
|
72
58
|
assert response.name_id == "test@onelogin.com"
|
73
59
|
end
|
60
|
+
|
61
|
+
should_eventually "validate ADFS assertions" do
|
62
|
+
response = Onelogin::Saml::Response.new(fixture(:adfs_response))
|
63
|
+
response.stubs(:conditions).returns(nil)
|
64
|
+
settings = Onelogin::Saml::Settings.new
|
65
|
+
settings.idp_cert_fingerprint = "17:54:07:27:53:55:D1:93:67:A4:95:0A:6A:E4:D6:1E:FA:4A:94:1D"
|
66
|
+
response.settings = settings
|
67
|
+
assert response.validate!
|
68
|
+
end
|
74
69
|
end
|
75
70
|
|
76
71
|
context "#name_id" do
|
@@ -81,18 +76,28 @@ class RubySamlTest < Test::Unit::TestCase
|
|
81
76
|
response = Onelogin::Saml::Response.new(response_document_3)
|
82
77
|
assert_equal "someone@example.com", response.name_id
|
83
78
|
end
|
79
|
+
|
80
|
+
should_eventually "be extractable from an OpenSAML response" do
|
81
|
+
response = Onelogin::Saml::Response.new(fixture(:open_saml))
|
82
|
+
assert_equal "someone@example.org", response.name_id
|
83
|
+
end
|
84
|
+
|
85
|
+
should_eventually "be extractable from a Simple SAML PHP response" do
|
86
|
+
response = Onelogin::Saml::Response.new(fixture(:simple_saml_php))
|
87
|
+
assert_equal "someone@example.com", response.name_id
|
88
|
+
end
|
84
89
|
end
|
85
90
|
|
86
91
|
context "#check_conditions" do
|
87
92
|
should "check time conditions" do
|
88
93
|
response = Onelogin::Saml::Response.new(response_document)
|
89
|
-
assert !response.
|
94
|
+
assert !response.send(:validate_conditions, true)
|
90
95
|
response = Onelogin::Saml::Response.new(response_document_6)
|
91
|
-
assert response.
|
96
|
+
assert response.send(:validate_conditions, true)
|
92
97
|
time = Time.parse("2011-06-14T18:25:01.516Z")
|
93
98
|
Time.stubs(:now).returns(time)
|
94
99
|
response = Onelogin::Saml::Response.new(response_document_5)
|
95
|
-
assert response.
|
100
|
+
assert response.send(:validate_conditions, true)
|
96
101
|
end
|
97
102
|
end
|
98
103
|
|
@@ -133,34 +138,7 @@ class RubySamlTest < Test::Unit::TestCase
|
|
133
138
|
assert response.session_expires_at.nil?
|
134
139
|
end
|
135
140
|
end
|
136
|
-
end
|
137
|
-
|
138
|
-
context "Authrequest" do
|
139
|
-
should "create the deflated SAMLRequest URL parameter" do
|
140
|
-
settings = Onelogin::Saml::Settings.new
|
141
|
-
settings.idp_sso_target_url = "http://stuff.com"
|
142
|
-
auth_url = Onelogin::Saml::Authrequest.new.create(settings)
|
143
|
-
assert auth_url =~ /^http:\/\/stuff\.com\?SAMLRequest=/
|
144
|
-
payload = CGI.unescape(auth_url.split("=").last)
|
145
|
-
decoded = Base64.decode64(payload)
|
146
|
-
|
147
|
-
zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
|
148
|
-
inflated = zstream.inflate(decoded)
|
149
|
-
zstream.finish
|
150
|
-
zstream.close
|
151
|
-
|
152
|
-
assert_match /^<samlp:AuthnRequest/, inflated
|
153
|
-
end
|
154
|
-
|
155
|
-
should "accept extra parameters" do
|
156
|
-
settings = Onelogin::Saml::Settings.new
|
157
|
-
settings.idp_sso_target_url = "http://stuff.com"
|
158
141
|
|
159
|
-
auth_url = Onelogin::Saml::Authrequest.new.create(settings, { :hello => "there" })
|
160
|
-
assert auth_url =~ /&hello=there$/
|
161
|
-
|
162
|
-
auth_url = Onelogin::Saml::Authrequest.new.create(settings, { :hello => nil })
|
163
|
-
assert auth_url =~ /&hello=$/
|
164
|
-
end
|
165
142
|
end
|
143
|
+
|
166
144
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzYW1scDpSZXNwb25zZSB4bWxuczpz
|
2
|
+
YW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiBJ
|
3
|
+
RD0iXzAyNjNhMDdiLTIwNWYtNDc5Yy05MGZjLTc0OTU3MTVlY2JiZiIgVmVy
|
4
|
+
c2lvbj0iMi4wIiBJc3N1ZUluc3RhbnQ9IjIwMTEtMDYtMjJUMTI6NDk6MzAu
|
5
|
+
MzQ4WiIgRGVzdGluYXRpb249Imh0dHBzOi8vc29tZW9uZS5leGFtcGxlLmNv
|
6
|
+
bS9lbmRwb2ludCIgQ29uc2VudD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6
|
7
|
+
Mi4wOmNvbnNlbnQ6dW5zcGVjaWZpZWQiIEluUmVzcG9uc2VUbz0iX2ZjNGEz
|
8
|
+
NGIwLTdlZmItMDEyZS1jYWFlLTc4MmJjYjEzYmIzOCI+CiAgPElzc3VlciB4
|
9
|
+
bWxucz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+
|
10
|
+
aHR0cDovL2xvZ2luLmV4YW1wbGUuY29tL2lzc3VlcjwvSXNzdWVyPgogIDxz
|
11
|
+
YW1scDpTdGF0dXM+CiAgICA8c2FtbHA6U3RhdHVzQ29kZSBWYWx1ZT0idXJu
|
12
|
+
Om9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnN0YXR1czpTdWNjZXNzIi8+CiAg
|
13
|
+
PC9zYW1scDpTdGF0dXM+CiAgPEFzc2VydGlvbiB4bWxucz0idXJuOm9hc2lz
|
14
|
+
Om5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9Il83MjFiNGE1YS1k
|
15
|
+
N2UxLTQ4NjEtOTc1NC1hOWIxOTdiNmY5YWIiIElzc3VlSW5zdGFudD0iMjAx
|
16
|
+
MS0wNi0yMlQxMjo0OTozMC4zNDhaIiBWZXJzaW9uPSIyLjAiPgogICAgPElz
|
17
|
+
c3Vlcj5odHRwOi8vbG9naW4uZXhhbXBsZS5jb20vaXNzdWVyPC9Jc3N1ZXI+
|
18
|
+
CiAgICA8ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9y
|
19
|
+
Zy8yMDAwLzA5L3htbGRzaWcjIj4KICAgICAgPGRzOlNpZ25lZEluZm8+CiAg
|
20
|
+
ICAgICAgPGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJo
|
21
|
+
dHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4KICAg
|
22
|
+
ICAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3
|
23
|
+
dy53My5vcmcvMjAwMS8wNC94bWxkc2lnLW1vcmUjcnNhLXNoYTI1NiIvPgog
|
24
|
+
ICAgICAgIDxkczpSZWZlcmVuY2UgVVJJPSIjXzcyMWI0YTVhLWQ3ZTEtNDg2
|
25
|
+
MS05NzU0LWE5YjE5N2I2ZjlhYiI+CiAgICAgICAgICA8ZHM6VHJhbnNmb3Jt
|
26
|
+
cz4KICAgICAgICAgICAgPGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6
|
27
|
+
Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0
|
28
|
+
dXJlIi8+CiAgICAgICAgICAgIDxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJo
|
29
|
+
dHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4KICAg
|
30
|
+
ICAgICAgIDwvZHM6VHJhbnNmb3Jtcz4KICAgICAgICAgIDxkczpEaWdlc3RN
|
31
|
+
ZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3ht
|
32
|
+
bGVuYyNzaGEyNTYiLz4KICAgICAgICAgIDxkczpEaWdlc3RWYWx1ZT52NTN3
|
33
|
+
cW80ZllESzhVY3JPVWNPV2cyemxKL2NIVnVtWVMwS2pycm5WdUprPTwvZHM6
|
34
|
+
RGlnZXN0VmFsdWU+CiAgICAgICAgPC9kczpSZWZlcmVuY2U+CiAgICAgIDwv
|
35
|
+
ZHM6U2lnbmVkSW5mbz4KICAgICAgPGRzOlNpZ25hdHVyZVZhbHVlPlowOXBl
|
36
|
+
d1k3ekZ2OTFobjkwbHgwRUVubE1HTkw5elVKWk14SVI2cW9mTFpPWk1sVG5Y
|
37
|
+
TjV6RnNmKzFYUFBJWVpMdzVsQ0dqanRtZE5seGR2NzJ6TkZsTVROUnFaN0lp
|
38
|
+
SXd2azVHUk0zenZBV3NOT1k2ZEI0YzVxamU0UkhxL2ZySkdCZ04vZ2VWeFZt
|
39
|
+
bjNMWmQ1WmNrdWh1UzFzN0ZKQW9MVWNaRUxKL25jZ1JEZGdqQUUrcjhHdGFO
|
40
|
+
a3U0VVRCUkdBZnRsMFBXbUFTMDdsbGU2bGFTVVBSQmRCRE5sVlN6R0FQT3lY
|
41
|
+
UDE2ZUkxOWJvbllMaGpiOHVoY0N0bWdicnJhbkpVVGxZc1htcnhvaGNGdW4r
|
42
|
+
eWZxVFdXd2l4OW1SUXRBdEFFOW5nSUUwVkRkTC9reFR0NktOb1B6d2tlajVW
|
43
|
+
eFNMRkFncTJ1M3JaTWN1WUdadTFIUT09PC9kczpTaWduYXR1cmVWYWx1ZT4K
|
44
|
+
ICAgICAgPEtleUluZm8geG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAv
|
45
|
+
MDkveG1sZHNpZyMiPgogICAgICAgIDxkczpYNTA5RGF0YT4KICAgICAgICAg
|
46
|
+
IDxkczpYNTA5Q2VydGlmaWNhdGU+TUlJQzVEQ0NBY3lnQXdJQkFnSVFOQlRr
|
47
|
+
dDdxaWNhcEtOc0lYTWNrOHhUQU5CZ2txaGtpRzl3MEJBUXNGQURBdU1Td3dL
|
48
|
+
Z1lEVlFRREV5TkJSRVpUSUZOcFoyNXBibWNnTFNCc2IyZHBiaTVrY21WemIz
|
49
|
+
VnlZMlZ6TG1OdmJUQWVGdzB4TVRBMk1UQXhPRFUyTURGYUZ3MHhNakEyTURr
|
50
|
+
eE9EVTJNREZhTUM0eExEQXFCZ05WQkFNVEkwRkVSbE1nVTJsbmJtbHVaeUF0
|
51
|
+
SUd4dloybHVMbVJ5WlhOdmRYSmpaWE11WTI5dE1JSUJJakFOQmdrcWhraUc5
|
52
|
+
dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBcTdBTURHbkJISUd3dDlLUHRM
|
53
|
+
RDBNMEVYR3VabldHQW1iNXAyRkRjRnp0SkhPSThXWVBxZVJwaHpWU0VrZ1h0
|
54
|
+
UEloNUp4M2VsUzZoVm43SFZqMld2eklENmpwQjQ1bzhpRGs4UFdnaTE0ZnhH
|
55
|
+
V0U1bzFQaUI4WHJlMWM1dnMySUc1YVBXSUQ1dUM2YkQwWGduTDk1TWdPOUhH
|
56
|
+
UFBTUVJGbnVqS05xekZRZHRvQkpJSmF3QWVEL2kveHM3RmpGazl4MWZBMEV5
|
57
|
+
TENuaCtlYWZmSXBvcmIrMXh4VzJENkQzbVJUZ2ZIeFhyV1I4VzRqSG5pZ2da
|
58
|
+
aHFkRGhVeHZFYWlRRlRiSU4yRCt6eUI3YVF3UUNIU0ZwZXJCYytSNUZsbGdu
|
59
|
+
R0FhK3NqYjZnMUZYYmVobUVHd1NheHdSWklEQWhqSVFtYTV3WDV5V0pEeEZ6
|
60
|
+
UjRwc1RlRlJRSURBUUFCTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFCekFQ
|
61
|
+
QzJRUStVdHZrcVFZMm8vam9IR3RudUx5Zmt3ZDc2NERjR0RsY1lLVktFYURD
|
62
|
+
dm5KeDNneXdSVU9ERVJoRGh1Zkpid3I3T29YVmRodzcwTnRURU11Z0pGcjI5
|
63
|
+
U2d4bjNDaVRpeVBGU0RHang5MTFhYkt4dEpTQkludkkwMEFqWCtWbElaaG95
|
64
|
+
ODNZWU9SWEZjeWIrVXZoMnIyU1pVM0FDTnA4TTNjWlI2SjFFREJoUEtZd0VF
|
65
|
+
VWs4TlRNbVpMM3ZXanFMWldUeVRUaFRyUUYvbEg5UENsdzlPMjl1d2lmaXEy
|
66
|
+
WHpTeVNyMy9QSHh6cE1Sa0w5YzRFaTQ1UURtYWdlckFVUndlcTVwVVc4QzNV
|
67
|
+
QVVqTExWY1hrLzJwZXZaRU43MFlndDVwMmZBZ3M4NE9KaERSS2lIR3BhcmlF
|
68
|
+
bWo0THNKR1pzcDdxRkpwbjErTWlqUmU8L2RzOlg1MDlDZXJ0aWZpY2F0ZT4K
|
69
|
+
ICAgICAgICA8L2RzOlg1MDlEYXRhPgogICAgICA8L0tleUluZm8+CiAgICA8
|
70
|
+
L2RzOlNpZ25hdHVyZT4KICAgIDxTdWJqZWN0PgogICAgICA8TmFtZUlEIEZv
|
71
|
+
cm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6MS4xOm5hbWVpZC1mb3Jt
|
72
|
+
YXQ6ZW1haWxBZGRyZXNzIj5oZWxsb0BleGFtcGxlLmNvbTwvTmFtZUlEPgog
|
73
|
+
ICAgICA8U3ViamVjdENvbmZpcm1hdGlvbiBNZXRob2Q9InVybjpvYXNpczpu
|
74
|
+
YW1lczp0YzpTQU1MOjIuMDpjbTpiZWFyZXIiPgogICAgICAgIDxTdWJqZWN0
|
75
|
+
Q29uZmlybWF0aW9uRGF0YSBJblJlc3BvbnNlVG89Il9mYzRhMzRiMC03ZWZi
|
76
|
+
LTAxMmUtY2FhZS03ODJiY2IxM2JiMzgiIE5vdE9uT3JBZnRlcj0iMjAxMS0w
|
77
|
+
Ni0yMlQxMjo1NDozMC4zNDhaIiBSZWNpcGllbnQ9Imh0dHBzOi8vc29tZW9u
|
78
|
+
ZS5leGFtcGxlLmNvbS9lbmRwb2ludCIvPgogICAgICA8L1N1YmplY3RDb25m
|
79
|
+
aXJtYXRpb24+CiAgICA8L1N1YmplY3Q+CiAgICA8Q29uZGl0aW9ucyBOb3RC
|
80
|
+
ZWZvcmU9IjIwMTEtMDYtMjJUMTI6NDk6MzAuMzMyWiIgTm90T25PckFmdGVy
|
81
|
+
PSIyMDExLTA2LTIyVDEzOjQ5OjMwLjMzMloiPgogICAgICA8QXVkaWVuY2VS
|
82
|
+
ZXN0cmljdGlvbj4KICAgICAgICA8QXVkaWVuY2U+ZXhhbXBsZS5jb208L0F1
|
83
|
+
ZGllbmNlPgogICAgICA8L0F1ZGllbmNlUmVzdHJpY3Rpb24+CiAgICA8L0Nv
|
84
|
+
bmRpdGlvbnM+CiAgICA8QXV0aG5TdGF0ZW1lbnQgQXV0aG5JbnN0YW50PSIy
|
85
|
+
MDExLTA2LTIyVDEyOjQ5OjMwLjExMloiIFNlc3Npb25JbmRleD0iXzcyMWI0
|
86
|
+
YTVhLWQ3ZTEtNDg2MS05NzU0LWE5YjE5N2I2ZjlhYiI+CiAgICAgIDxBdXRo
|
87
|
+
bkNvbnRleHQ+CiAgICAgICAgPEF1dGhuQ29udGV4dENsYXNzUmVmPnVybjpv
|
88
|
+
YXNpczpuYW1lczp0YzpTQU1MOjIuMDphYzpjbGFzc2VzOlBhc3N3b3JkUHJv
|
89
|
+
dGVjdGVkVHJhbnNwb3J0PC9BdXRobkNvbnRleHRDbGFzc1JlZj4KICAgICAg
|
90
|
+
PC9BdXRobkNvbnRleHQ+CiAgICA8L0F1dGhuU3RhdGVtZW50PgogIDwvQXNz
|
91
|
+
ZXJ0aW9uPgo8L3NhbWxwOlJlc3BvbnNlPgo=
|
@@ -0,0 +1,56 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xs="http://www.w3.org/2001/XMLSchema" Destination="https://example.hello.com/access/saml" ID="jVFQbyEpSfUwqhZtJtarIaGoshwuAQMDwLoiMhzJXsv" InResponseTo="cfeooghajnhofcmogakmlhpkohnmikicnfhdnjlc" IssueInstant="2011-06-21T13:54:38.661Z" Version="2.0">
|
3
|
+
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://idm.orademo.com</saml2:Issuer>
|
4
|
+
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
5
|
+
<ds:SignedInfo>
|
6
|
+
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
7
|
+
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
8
|
+
<ds:Reference URI="#jVFQbyEpSfUwqhZtJtarIaGoshwuAQMDwLoiMhzJXsv">
|
9
|
+
<ds:Transforms>
|
10
|
+
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
11
|
+
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
|
12
|
+
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs"/>
|
13
|
+
</ds:Transform>
|
14
|
+
</ds:Transforms>
|
15
|
+
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
16
|
+
<ds:DigestValue>uHuSry39P16Yh7srS32xESmj4Lw=</ds:DigestValue>
|
17
|
+
</ds:Reference>
|
18
|
+
</ds:SignedInfo>
|
19
|
+
<ds:SignatureValue>fdghdfggfd=</ds:SignatureValue>
|
20
|
+
<ds:KeyInfo>
|
21
|
+
<ds:X509Data>
|
22
|
+
<ds:X509Certificate>dfghjkl</ds:X509Certificate>
|
23
|
+
</ds:X509Data>
|
24
|
+
</ds:KeyInfo>
|
25
|
+
</ds:Signature>
|
26
|
+
<saml2p:Status>
|
27
|
+
<saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
|
28
|
+
</saml2p:Status>
|
29
|
+
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="emmCjammnYdAbMWDuMAJeZvQIMBayeeYqqwvQoDclKE" IssueInstant="2011-06-21T13:54:38.676Z" Version="2.0">
|
30
|
+
<saml2:Issuer>https://idm.orademo.com</saml2:Issuer>
|
31
|
+
<saml2:Subject>
|
32
|
+
<saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" NameQualifier="idp.example.org">someone@example.org</saml2:NameID>
|
33
|
+
<saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
|
34
|
+
<saml2:SubjectConfirmationData InResponseTo="cfeooghajnhofcmogakmlhpkohnmikicnfhdnjlc" NotOnOrAfter="2011-06-21T14:09:38.676Z" Recipient="https://example.hello.com/access/saml"/>
|
35
|
+
</saml2:SubjectConfirmation>
|
36
|
+
</saml2:Subject>
|
37
|
+
<saml2:Conditions NotBefore="2011-06-21T13:54:38.683Z" NotOnOrAfter="2011-06-21T14:09:38.683Z">
|
38
|
+
<saml2:AudienceRestriction>
|
39
|
+
<saml2:Audience>hello.com</saml2:Audience>
|
40
|
+
</saml2:AudienceRestriction>
|
41
|
+
</saml2:Conditions>
|
42
|
+
<saml2:AuthnStatement AuthnInstant="2011-06-21T13:54:38.685Z" SessionIndex="perdkjfskdjfksdiertusfsdfsddeurtherukjdfgkdffg">
|
43
|
+
<saml2:AuthnContext>
|
44
|
+
<saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
|
45
|
+
</saml2:AuthnContext>
|
46
|
+
</saml2:AuthnStatement>
|
47
|
+
<saml2:AttributeStatement>
|
48
|
+
<saml2:Attribute Name="FirstName">
|
49
|
+
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Someone</saml2:AttributeValue>
|
50
|
+
</saml2:Attribute>
|
51
|
+
<saml2:Attribute Name="LastName">
|
52
|
+
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Special</saml2:AttributeValue>
|
53
|
+
</saml2:Attribute>
|
54
|
+
</saml2:AttributeStatement>
|
55
|
+
</saml2:Assertion>
|
56
|
+
</saml2p:Response>
|
@@ -0,0 +1,71 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="pfxc32aed67-820f-4296-0c20-205a10dd5787" Version="2.0" IssueInstant="2011-06-17T14:54:14Z" Destination="https://example.hello.com/access/saml" InResponseTo="_57bcbf70-7b1f-012e-c821-782bcb13bb38">
|
3
|
+
<saml:Issuer>https://federate.example.net/saml/saml2/idp/metadata.php</saml:Issuer>
|
4
|
+
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
5
|
+
<ds:SignedInfo>
|
6
|
+
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
7
|
+
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
8
|
+
<ds:Reference URI="#pfxc32aed67-820f-4296-0c20-205a10dd5787">
|
9
|
+
<ds:Transforms>
|
10
|
+
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
11
|
+
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
12
|
+
</ds:Transforms>
|
13
|
+
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
14
|
+
<ds:DigestValue>dVJ592k5xPjCHBCMiJ8eZkPUiT8=</ds:DigestValue>
|
15
|
+
</ds:Reference>
|
16
|
+
</ds:SignedInfo>
|
17
|
+
<ds:SignatureValue>LHNK1FJfcOIUuWVKJmGABQ+W98+pQ==</ds:SignatureValue>
|
18
|
+
<ds:KeyInfo>
|
19
|
+
<ds:X509Data>
|
20
|
+
<ds:X509Certificate>MIIQmS6WmmIht3k=</ds:X509Certificate>
|
21
|
+
</ds:X509Data>
|
22
|
+
</ds:KeyInfo>
|
23
|
+
</ds:Signature>
|
24
|
+
<samlp:Status>
|
25
|
+
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
|
26
|
+
</samlp:Status>
|
27
|
+
<saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="pfx7841991c-c73f-4035-e2ee-c170c0e1d3e4" Version="2.0" IssueInstant="2011-06-17T14:54:14Z">
|
28
|
+
<saml:Issuer>https://federate.example.net/saml/saml2/idp/metadata.php</saml:Issuer>
|
29
|
+
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
30
|
+
<ds:SignedInfo>
|
31
|
+
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
32
|
+
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
33
|
+
<ds:Reference URI="#pfx7841991c-c73f-4035-e2ee-c170c0e1d3e4">
|
34
|
+
<ds:Transforms>
|
35
|
+
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
36
|
+
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
37
|
+
</ds:Transforms>
|
38
|
+
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
39
|
+
<ds:DigestValue>mi0IAultZkpsZa1XxGx9X4iAPQg=</ds:DigestValue>
|
40
|
+
</ds:Reference>
|
41
|
+
</ds:SignedInfo>
|
42
|
+
<ds:SignatureValue>LqkW39SOYbttYxlGhIBw==</ds:SignatureValue>
|
43
|
+
<ds:KeyInfo>
|
44
|
+
<ds:X509Data>
|
45
|
+
<ds:X509Certificate>MIIGmmIht3k=</ds:X509Certificate>
|
46
|
+
</ds:X509Data>
|
47
|
+
</ds:KeyInfo>
|
48
|
+
</ds:Signature>
|
49
|
+
<saml:Subject>
|
50
|
+
<saml:NameID SPNameQualifier="hello.com" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">someone@example.com</saml:NameID>
|
51
|
+
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
|
52
|
+
<saml:SubjectConfirmationData NotOnOrAfter="2011-06-17T14:59:14Z" Recipient="https://example.hello.com/access/saml" InResponseTo="_57bcbf70-7b1f-012e-c821-782bcb13bb38"/>
|
53
|
+
</saml:SubjectConfirmation>
|
54
|
+
</saml:Subject>
|
55
|
+
<saml:Conditions NotBefore="2011-06-17T14:53:44Z" NotOnOrAfter="2011-06-17T14:59:14Z">
|
56
|
+
<saml:AudienceRestriction>
|
57
|
+
<saml:Audience>hello.com</saml:Audience>
|
58
|
+
</saml:AudienceRestriction>
|
59
|
+
</saml:Conditions>
|
60
|
+
<saml:AuthnStatement AuthnInstant="2011-06-17T14:54:07Z" SessionNotOnOrAfter="2011-06-17T22:54:14Z" SessionIndex="_51be37965feb5579d803141076936dc2e9d1d98ebf">
|
61
|
+
<saml:AuthnContext>
|
62
|
+
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
|
63
|
+
</saml:AuthnContext>
|
64
|
+
</saml:AuthnStatement>
|
65
|
+
<saml:AttributeStatement>
|
66
|
+
<saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
67
|
+
<saml:AttributeValue xsi:type="xs:string">someone@example.com</saml:AttributeValue>
|
68
|
+
</saml:Attribute>
|
69
|
+
</saml:AttributeStatement>
|
70
|
+
</saml:Assertion>
|
71
|
+
</samlp:Response>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
|
2
|
+
|
3
|
+
class SettingsTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "Settings" do
|
6
|
+
setup do
|
7
|
+
@settings = Onelogin::Saml::Settings.new
|
8
|
+
end
|
9
|
+
should "should provide getters and settings" do
|
10
|
+
accessors = [
|
11
|
+
:assertion_consumer_service_url, :issuer, :sp_name_qualifier, :sp_name_qualifier,
|
12
|
+
:idp_sso_target_url, :idp_cert_fingerprint, :name_identifier_format
|
13
|
+
]
|
14
|
+
|
15
|
+
accessors.each do |accessor|
|
16
|
+
value = Kernel.rand
|
17
|
+
@settings.send("#{accessor}=".to_sym, value)
|
18
|
+
assert_equal value, @settings.send(accessor)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -2,12 +2,22 @@ require 'rubygems'
|
|
2
2
|
require 'test/unit'
|
3
3
|
require 'shoulda'
|
4
4
|
require 'mocha'
|
5
|
+
require 'ruby-debug'
|
5
6
|
|
6
7
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
8
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
9
|
require 'ruby-saml'
|
9
10
|
|
10
11
|
class Test::Unit::TestCase
|
12
|
+
def fixture(document, base64 = true)
|
13
|
+
response = Dir.glob(File.join(File.dirname(__FILE__), "responses", "#{document}*")).first
|
14
|
+
if base64 && response =~ /\.xml$/
|
15
|
+
Base64.encode64(File.read(response))
|
16
|
+
else
|
17
|
+
File.read(response)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
11
21
|
def response_document
|
12
22
|
@response_document ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response1.xml.base64'))
|
13
23
|
end
|
data/test/xml_security_test.rb
CHANGED
@@ -10,7 +10,7 @@ class XmlSecurityTest < Test::Unit::TestCase
|
|
10
10
|
|
11
11
|
should "should run validate without throwing NS related exceptions" do
|
12
12
|
base64cert = @document.elements["//ds:X509Certificate"].text
|
13
|
-
@document.validate_doc(base64cert,
|
13
|
+
@document.validate_doc(base64cert, true)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-saml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 0.4.
|
9
|
+
- 6
|
10
|
+
version: 0.4.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- OneLogin LLC
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-06-
|
18
|
+
date: 2011-06-28 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -63,7 +63,7 @@ dependencies:
|
|
63
63
|
type: :development
|
64
64
|
version_requirements: *id003
|
65
65
|
- !ruby/object:Gem::Dependency
|
66
|
-
name:
|
66
|
+
name: ruby-debug
|
67
67
|
prerelease: false
|
68
68
|
requirement: &id004 !ruby/object:Gem::Requirement
|
69
69
|
none: false
|
@@ -76,6 +76,20 @@ dependencies:
|
|
76
76
|
version: "0"
|
77
77
|
type: :development
|
78
78
|
version_requirements: *id004
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
name: mocha
|
81
|
+
prerelease: false
|
82
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
type: :development
|
92
|
+
version_requirements: *id005
|
79
93
|
description: SAML toolkit for Ruby on Rails
|
80
94
|
email: support@onelogin.com
|
81
95
|
executables: []
|
@@ -96,16 +110,22 @@ files:
|
|
96
110
|
- lib/onelogin/saml/authrequest.rb
|
97
111
|
- lib/onelogin/saml/response.rb
|
98
112
|
- lib/onelogin/saml/settings.rb
|
113
|
+
- lib/onelogin/saml/validation_error.rb
|
99
114
|
- lib/ruby-saml.rb
|
100
115
|
- lib/xml_security.rb
|
101
116
|
- ruby-saml.gemspec
|
117
|
+
- test/request_test.rb
|
118
|
+
- test/response_test.rb
|
119
|
+
- test/responses/adfs_response.xml.base64
|
102
120
|
- test/responses/certificate1
|
121
|
+
- test/responses/open_saml_response.xml
|
103
122
|
- test/responses/response1.xml.base64
|
104
123
|
- test/responses/response2.xml.base64
|
105
124
|
- test/responses/response3.xml.base64
|
106
125
|
- test/responses/response4.xml.base64
|
107
126
|
- test/responses/response5.xml.base64
|
108
|
-
- test/
|
127
|
+
- test/responses/simple_saml_php.xml
|
128
|
+
- test/settings_test.rb
|
109
129
|
- test/test_helper.rb
|
110
130
|
- test/xml_security_test.rb
|
111
131
|
has_rdoc: true
|
@@ -143,6 +163,8 @@ signing_key:
|
|
143
163
|
specification_version: 3
|
144
164
|
summary: SAML Ruby Tookit
|
145
165
|
test_files:
|
146
|
-
- test/
|
166
|
+
- test/request_test.rb
|
167
|
+
- test/response_test.rb
|
168
|
+
- test/settings_test.rb
|
147
169
|
- test/test_helper.rb
|
148
170
|
- test/xml_security_test.rb
|