ruby-saml 0.8.9 → 0.8.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ruby-saml might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/Gemfile +9 -1
- data/lib/onelogin/ruby-saml/authrequest.rb +82 -17
- data/lib/onelogin/ruby-saml/logoutrequest.rb +90 -18
- data/lib/onelogin/ruby-saml/settings.rb +73 -12
- data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +157 -0
- data/lib/onelogin/ruby-saml/utils.rb +79 -0
- data/lib/onelogin/ruby-saml/version.rb +1 -1
- data/lib/ruby-saml.rb +2 -1
- data/lib/xml_security.rb +151 -28
- data/test/certificates/ruby-saml.crt +14 -0
- data/test/certificates/ruby-saml.key +15 -0
- data/test/logoutrequest_test.rb +176 -41
- data/test/logoutresponse_test.rb +2 -1
- data/test/request_test.rb +100 -37
- data/test/response_test.rb +1 -1
- data/test/slo_logoutresponse_test.rb +226 -0
- data/test/test_helper.rb +37 -1
- metadata +10 -4
data/test/logoutresponse_test.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
|
2
2
|
require 'rexml/document'
|
3
3
|
require 'responses/logoutresponse_fixtures'
|
4
|
-
|
4
|
+
|
5
|
+
class LogoutResponseTest < Test::Unit::TestCase
|
5
6
|
|
6
7
|
context "Logoutresponse" do
|
7
8
|
context "#new" do
|
data/test/request_test.rb
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
|
2
2
|
|
3
|
-
class RequestTest < Test
|
3
|
+
class RequestTest < Minitest::Test
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
describe "Authrequest" do
|
6
|
+
let(:settings) { OneLogin::RubySaml::Settings.new }
|
7
|
+
|
8
|
+
before do
|
8
9
|
settings.idp_sso_target_url = "http://example.com"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "create the deflated SAMLRequest URL parameter" do
|
9
13
|
auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
|
10
14
|
assert auth_url =~ /^http:\/\/example\.com\?SAMLRequest=/
|
11
15
|
payload = CGI.unescape(auth_url.split("=").last)
|
@@ -19,9 +23,7 @@ class RequestTest < Test::Unit::TestCase
|
|
19
23
|
assert_match /^<samlp:AuthnRequest/, inflated
|
20
24
|
end
|
21
25
|
|
22
|
-
|
23
|
-
settings = OneLogin::RubySaml::Settings.new
|
24
|
-
settings.idp_sso_target_url = "http://example.com"
|
26
|
+
it "create the deflated SAMLRequest URL parameter including the Destination" do
|
25
27
|
auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
|
26
28
|
payload = CGI.unescape(auth_url.split("=").last)
|
27
29
|
decoded = Base64.decode64(payload)
|
@@ -34,10 +36,8 @@ class RequestTest < Test::Unit::TestCase
|
|
34
36
|
assert_match /<samlp:AuthnRequest[^<]* Destination='http:\/\/example.com'/, inflated
|
35
37
|
end
|
36
38
|
|
37
|
-
|
38
|
-
settings = OneLogin::RubySaml::Settings.new
|
39
|
+
it "create the SAMLRequest URL parameter without deflating" do
|
39
40
|
settings.compress_request = false
|
40
|
-
settings.idp_sso_target_url = "http://example.com"
|
41
41
|
auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
|
42
42
|
assert auth_url =~ /^http:\/\/example\.com\?SAMLRequest=/
|
43
43
|
payload = CGI.unescape(auth_url.split("=").last)
|
@@ -46,9 +46,7 @@ class RequestTest < Test::Unit::TestCase
|
|
46
46
|
assert_match /^<samlp:AuthnRequest/, decoded
|
47
47
|
end
|
48
48
|
|
49
|
-
|
50
|
-
settings = OneLogin::RubySaml::Settings.new
|
51
|
-
settings.idp_sso_target_url = "http://example.com"
|
49
|
+
it "create the SAMLRequest URL parameter with IsPassive" do
|
52
50
|
settings.passive = true
|
53
51
|
auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
|
54
52
|
assert auth_url =~ /^http:\/\/example\.com\?SAMLRequest=/
|
@@ -63,9 +61,7 @@ class RequestTest < Test::Unit::TestCase
|
|
63
61
|
assert_match /<samlp:AuthnRequest[^<]* IsPassive='true'/, inflated
|
64
62
|
end
|
65
63
|
|
66
|
-
|
67
|
-
settings = OneLogin::RubySaml::Settings.new
|
68
|
-
settings.idp_sso_target_url = "http://example.com"
|
64
|
+
it "create the SAMLRequest URL parameter with ProtocolBinding" do
|
69
65
|
settings.protocol_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
70
66
|
auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
|
71
67
|
assert auth_url =~ /^http:\/\/example\.com\?SAMLRequest=/
|
@@ -80,9 +76,7 @@ class RequestTest < Test::Unit::TestCase
|
|
80
76
|
assert_match /<samlp:AuthnRequest[^<]* ProtocolBinding='urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'/, inflated
|
81
77
|
end
|
82
78
|
|
83
|
-
|
84
|
-
settings = OneLogin::RubySaml::Settings.new
|
85
|
-
settings.idp_sso_target_url = "http://example.com"
|
79
|
+
it "create the SAMLRequest URL parameter with ForceAuthn" do
|
86
80
|
settings.force_authn = true
|
87
81
|
auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
|
88
82
|
assert auth_url =~ /^http:\/\/example\.com\?SAMLRequest=/
|
@@ -96,9 +90,7 @@ class RequestTest < Test::Unit::TestCase
|
|
96
90
|
assert_match /<samlp:AuthnRequest[^<]* ForceAuthn='true'/, inflated
|
97
91
|
end
|
98
92
|
|
99
|
-
|
100
|
-
settings = OneLogin::RubySaml::Settings.new
|
101
|
-
settings.idp_sso_target_url = "http://example.com"
|
93
|
+
it "create the SAMLRequest URL parameter with NameID Format" do
|
102
94
|
settings.name_identifier_format = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
|
103
95
|
auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
|
104
96
|
assert auth_url =~ /^http:\/\/example\.com\?SAMLRequest=/
|
@@ -113,9 +105,7 @@ class RequestTest < Test::Unit::TestCase
|
|
113
105
|
assert_match /<samlp:NameIDPolicy[^<]* Format='urn:oasis:names:tc:SAML:2.0:nameid-format:transient'/, inflated
|
114
106
|
end
|
115
107
|
|
116
|
-
|
117
|
-
settings = OneLogin::RubySaml::Settings.new
|
118
|
-
settings.idp_sso_target_url = "http://example.com"
|
108
|
+
it "create the SAMLRequest URL parameter with Subject" do
|
119
109
|
settings.name_identifier_value_requested = "testuser@example.com"
|
120
110
|
settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
|
121
111
|
auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
|
@@ -132,10 +122,7 @@ class RequestTest < Test::Unit::TestCase
|
|
132
122
|
assert inflated.include?("<saml:SubjectConfirmation Method='urn:oasis:names:tc:SAML:2.0:cm:bearer'/>")
|
133
123
|
end
|
134
124
|
|
135
|
-
|
136
|
-
settings = OneLogin::RubySaml::Settings.new
|
137
|
-
settings.idp_sso_target_url = "http://example.com"
|
138
|
-
|
125
|
+
it "accept extra parameters" do
|
139
126
|
auth_url = OneLogin::RubySaml::Authrequest.new.create(settings, { :hello => "there" })
|
140
127
|
assert auth_url =~ /&hello=there$/
|
141
128
|
|
@@ -143,24 +130,100 @@ class RequestTest < Test::Unit::TestCase
|
|
143
130
|
assert auth_url =~ /&hello=$/
|
144
131
|
end
|
145
132
|
|
146
|
-
|
147
|
-
|
148
|
-
settings = OneLogin::RubySaml::Settings.new
|
149
|
-
settings.idp_sso_target_url = "http://example.com"
|
150
|
-
|
133
|
+
describe "when the target url doesn't contain a query string" do
|
134
|
+
it "create the SAMLRequest parameter correctly" do
|
151
135
|
auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
|
152
136
|
assert auth_url =~ /^http:\/\/example.com\?SAMLRequest/
|
153
137
|
end
|
154
138
|
end
|
155
139
|
|
156
|
-
|
157
|
-
|
158
|
-
settings = OneLogin::RubySaml::Settings.new
|
140
|
+
describe "when the target url contains a query string" do
|
141
|
+
it "create the SAMLRequest parameter correctly" do
|
159
142
|
settings.idp_sso_target_url = "http://example.com?field=value"
|
160
143
|
|
161
144
|
auth_url = OneLogin::RubySaml::Authrequest.new.create(settings)
|
162
145
|
assert auth_url =~ /^http:\/\/example.com\?field=value&SAMLRequest/
|
163
146
|
end
|
164
147
|
end
|
148
|
+
|
149
|
+
describe "#create_params when the settings indicate to sign (embebed) the request" do
|
150
|
+
before do
|
151
|
+
settings.compress_request = false
|
152
|
+
settings.idp_sso_target_url = "http://example.com?field=value"
|
153
|
+
settings.security[:authn_requests_signed] = true
|
154
|
+
settings.security[:embed_sign] = true
|
155
|
+
settings.certificate = ruby_saml_cert_text
|
156
|
+
settings.private_key = ruby_saml_key_text
|
157
|
+
end
|
158
|
+
|
159
|
+
it "create a signed request" do
|
160
|
+
params = OneLogin::RubySaml::Authrequest.new.create_params(settings)
|
161
|
+
request_xml = Base64.decode64(params["SAMLRequest"])
|
162
|
+
assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], request_xml
|
163
|
+
assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], request_xml
|
164
|
+
end
|
165
|
+
|
166
|
+
it "create a signed request with 256 digest and signature methods" do
|
167
|
+
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
|
168
|
+
settings.security[:digest_method] = XMLSecurity::Document::SHA512
|
169
|
+
|
170
|
+
params = OneLogin::RubySaml::Authrequest.new.create_params(settings)
|
171
|
+
|
172
|
+
request_xml = Base64.decode64(params["SAMLRequest"])
|
173
|
+
assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], request_xml
|
174
|
+
assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'/>], request_xml
|
175
|
+
assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2001/04/xmlenc#sha512'/>], request_xml
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
describe "#create_params when the settings indicate to sign the request" do
|
180
|
+
let(:cert) { OpenSSL::X509::Certificate.new(ruby_saml_cert_text) }
|
181
|
+
|
182
|
+
before do
|
183
|
+
settings.compress_request = false
|
184
|
+
settings.idp_sso_target_url = "http://example.com?field=value"
|
185
|
+
settings.security[:authn_requests_signed] = true
|
186
|
+
settings.security[:embed_sign] = false
|
187
|
+
settings.certificate = ruby_saml_cert_text
|
188
|
+
settings.private_key = ruby_saml_key_text
|
189
|
+
end
|
190
|
+
|
191
|
+
it "create a signature parameter with RSA_SHA1 and validate it" do
|
192
|
+
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
|
193
|
+
|
194
|
+
params = OneLogin::RubySaml::Authrequest.new.create_params(settings, :RelayState => 'http://example.com')
|
195
|
+
assert params['SAMLRequest']
|
196
|
+
assert params[:RelayState]
|
197
|
+
assert params['Signature']
|
198
|
+
assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA1
|
199
|
+
|
200
|
+
query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}"
|
201
|
+
query_string << "&RelayState=#{CGI.escape(params[:RelayState])}"
|
202
|
+
query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}"
|
203
|
+
|
204
|
+
signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
|
205
|
+
assert_equal signature_algorithm, OpenSSL::Digest::SHA1
|
206
|
+
|
207
|
+
assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
|
208
|
+
end
|
209
|
+
|
210
|
+
it "create a signature parameter with RSA_SHA256 and validate it" do
|
211
|
+
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
|
212
|
+
|
213
|
+
params = OneLogin::RubySaml::Authrequest.new.create_params(settings, :RelayState => 'http://example.com')
|
214
|
+
assert params['Signature']
|
215
|
+
assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA256
|
216
|
+
|
217
|
+
query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}"
|
218
|
+
query_string << "&RelayState=#{CGI.escape(params[:RelayState])}"
|
219
|
+
query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}"
|
220
|
+
|
221
|
+
signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
|
222
|
+
assert_equal signature_algorithm, OpenSSL::Digest::SHA256
|
223
|
+
assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
165
227
|
end
|
228
|
+
|
166
229
|
end
|
data/test/response_test.rb
CHANGED
@@ -0,0 +1,226 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
|
2
|
+
|
3
|
+
class SloLogoutresponseTest < Minitest::Test
|
4
|
+
|
5
|
+
describe "SloLogoutresponse" do
|
6
|
+
|
7
|
+
let(:settings) { OneLogin::RubySaml::Settings.new }
|
8
|
+
|
9
|
+
before do
|
10
|
+
settings.idp_slo_target_url = "http://unauth.com/logout"
|
11
|
+
settings.name_identifier_value = "f00f00"
|
12
|
+
settings.compress_request = true
|
13
|
+
settings.certificate = ruby_saml_cert_text
|
14
|
+
settings.private_key = ruby_saml_key_text
|
15
|
+
end
|
16
|
+
|
17
|
+
it "create the deflated SAMLResponse URL parameter" do
|
18
|
+
unauth_url = OneLogin::RubySaml::SloLogoutresponse.new.create(settings)
|
19
|
+
assert_match /^http:\/\/unauth\.com\/logout\?SAMLResponse=/, unauth_url
|
20
|
+
|
21
|
+
inflated = decode_saml_response_payload(unauth_url)
|
22
|
+
assert_match /^<samlp:LogoutResponse/, inflated
|
23
|
+
end
|
24
|
+
|
25
|
+
it "support additional params" do
|
26
|
+
unauth_url = OneLogin::RubySaml::SloLogoutresponse.new.create(settings, nil, nil, { :hello => nil })
|
27
|
+
assert_match /&hello=$/, unauth_url
|
28
|
+
|
29
|
+
unauth_url = OneLogin::RubySaml::SloLogoutresponse.new.create(settings, nil, nil, { :foo => "bar" })
|
30
|
+
assert_match /&foo=bar$/, unauth_url
|
31
|
+
|
32
|
+
unauth_url = OneLogin::RubySaml::SloLogoutresponse.new.create(settings, nil, nil, { :RelayState => "http://idp.example.com" })
|
33
|
+
assert_match /&RelayState=http%3A%2F%2Fidp.example.com$/, unauth_url
|
34
|
+
end
|
35
|
+
|
36
|
+
it "RelayState cases" do
|
37
|
+
unauth_url = OneLogin::RubySaml::SloLogoutresponse.new.create(settings, nil, nil, { :RelayState => nil })
|
38
|
+
assert !unauth_url.include?('RelayState')
|
39
|
+
|
40
|
+
unauth_url = OneLogin::RubySaml::SloLogoutresponse.new.create(settings, nil, nil, { :RelayState => "http://example.com" })
|
41
|
+
assert unauth_url.include?('&RelayState=http%3A%2F%2Fexample.com')
|
42
|
+
|
43
|
+
unauth_url = OneLogin::RubySaml::SloLogoutresponse.new.create(settings, nil, nil, { 'RelayState' => nil })
|
44
|
+
assert !unauth_url.include?('RelayState')
|
45
|
+
|
46
|
+
unauth_url = OneLogin::RubySaml::SloLogoutresponse.new.create(settings, nil, nil, { 'RelayState' => "http://example.com" })
|
47
|
+
assert unauth_url.include?('&RelayState=http%3A%2F%2Fexample.com')
|
48
|
+
end
|
49
|
+
|
50
|
+
it "set InResponseTo to the ID from the logout request" do
|
51
|
+
unauth_url = OneLogin::RubySaml::SloLogoutresponse.new.create(settings, '_c0348950-935b-0131-1060-782bcb56fcaa')
|
52
|
+
|
53
|
+
inflated = decode_saml_response_payload(unauth_url)
|
54
|
+
assert_match /InResponseTo='_c0348950-935b-0131-1060-782bcb56fcaa'/, inflated
|
55
|
+
end
|
56
|
+
|
57
|
+
it "set a custom successful logout message on the response" do
|
58
|
+
unauth_url = OneLogin::RubySaml::SloLogoutresponse.new.create(settings, nil, "Custom Logout Message")
|
59
|
+
|
60
|
+
inflated = decode_saml_response_payload(unauth_url)
|
61
|
+
assert_match /<samlp:StatusMessage>Custom Logout Message<\/samlp:StatusMessage>/, inflated
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "when the settings indicate to sign (embedded) logout response" do
|
65
|
+
|
66
|
+
before do
|
67
|
+
settings.compress_response = false
|
68
|
+
settings.security[:logout_responses_signed] = true
|
69
|
+
settings.security[:embed_sign] = true
|
70
|
+
end
|
71
|
+
|
72
|
+
it "doesn't sign through create_xml_document" do
|
73
|
+
unauth_res = OneLogin::RubySaml::SloLogoutresponse.new
|
74
|
+
inflated = unauth_res.create_xml_document(settings).to_s
|
75
|
+
|
76
|
+
refute_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], inflated
|
77
|
+
refute_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], inflated
|
78
|
+
refute_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], inflated
|
79
|
+
end
|
80
|
+
|
81
|
+
it "sign unsigned request" do
|
82
|
+
unauth_res = OneLogin::RubySaml::SloLogoutresponse.new
|
83
|
+
unauth_res_doc = unauth_res.create_xml_document(settings)
|
84
|
+
inflated = unauth_res_doc.to_s
|
85
|
+
|
86
|
+
refute_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], inflated
|
87
|
+
refute_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], inflated
|
88
|
+
refute_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], inflated
|
89
|
+
|
90
|
+
inflated = unauth_res.sign_document(unauth_res_doc, settings).to_s
|
91
|
+
|
92
|
+
assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], inflated
|
93
|
+
assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], inflated
|
94
|
+
assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], inflated
|
95
|
+
end
|
96
|
+
|
97
|
+
it "signs through create_logout_response_xml_doc" do
|
98
|
+
unauth_res = OneLogin::RubySaml::SloLogoutresponse.new
|
99
|
+
inflated = unauth_res.create_logout_response_xml_doc(settings).to_s
|
100
|
+
|
101
|
+
assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], inflated
|
102
|
+
assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], inflated
|
103
|
+
assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], inflated
|
104
|
+
end
|
105
|
+
|
106
|
+
it "create a signed logout response" do
|
107
|
+
params = OneLogin::RubySaml::SloLogoutresponse.new.create_params(settings, nil, "Custom Logout Message")
|
108
|
+
|
109
|
+
response_xml = Base64.decode64(params["SAMLResponse"])
|
110
|
+
assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], response_xml
|
111
|
+
assert_match /<ds:SignatureMethod Algorithm='http:\/\/www.w3.org\/2000\/09\/xmldsig#rsa-sha1'\/>/, response_xml
|
112
|
+
assert_match /<ds:DigestMethod Algorithm='http:\/\/www.w3.org\/2000\/09\/xmldsig#sha1'\/>/, response_xml
|
113
|
+
end
|
114
|
+
|
115
|
+
it "create a signed logout response with 256 digest and signature methods" do
|
116
|
+
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
|
117
|
+
settings.security[:digest_method] = XMLSecurity::Document::SHA256
|
118
|
+
|
119
|
+
params = OneLogin::RubySaml::SloLogoutresponse.new.create_params(settings, nil, "Custom Logout Message")
|
120
|
+
|
121
|
+
response_xml = Base64.decode64(params["SAMLResponse"])
|
122
|
+
assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], response_xml
|
123
|
+
assert_match /<ds:SignatureMethod Algorithm='http:\/\/www.w3.org\/2001\/04\/xmldsig-more#rsa-sha256'\/>/, response_xml
|
124
|
+
assert_match /<ds:DigestMethod Algorithm='http:\/\/www.w3.org\/2001\/04\/xmlenc#sha256'\/>/, response_xml
|
125
|
+
end
|
126
|
+
|
127
|
+
it "create a signed logout response with 512 digest and signature method RSA_SHA384" do
|
128
|
+
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA384
|
129
|
+
settings.security[:digest_method] = XMLSecurity::Document::SHA512
|
130
|
+
|
131
|
+
params = OneLogin::RubySaml::SloLogoutresponse.new.create_params(settings, nil, "Custom Logout Message")
|
132
|
+
|
133
|
+
response_xml = Base64.decode64(params["SAMLResponse"])
|
134
|
+
assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], response_xml
|
135
|
+
assert_match /<ds:SignatureMethod Algorithm='http:\/\/www.w3.org\/2001\/04\/xmldsig-more#rsa-sha384'\/>/, response_xml
|
136
|
+
assert_match /<ds:DigestMethod Algorithm='http:\/\/www.w3.org\/2001\/04\/xmlenc#sha512'\/>/, response_xml
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "#create_params when the settings indicate to sign the logout response" do
|
141
|
+
|
142
|
+
let(:cert) { OpenSSL::X509::Certificate.new(ruby_saml_cert_text) }
|
143
|
+
|
144
|
+
before do
|
145
|
+
settings.compress_response = false
|
146
|
+
settings.security[:logout_responses_signed] = true
|
147
|
+
settings.security[:embed_sign] = false
|
148
|
+
end
|
149
|
+
|
150
|
+
it "create a signature parameter with RSA_SHA1 and validate it" do
|
151
|
+
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
|
152
|
+
|
153
|
+
params = OneLogin::RubySaml::SloLogoutresponse.new.create_params(settings, nil, "Custom Logout Message", :RelayState => 'http://example.com')
|
154
|
+
assert params['SAMLResponse']
|
155
|
+
assert params[:RelayState]
|
156
|
+
assert params['Signature']
|
157
|
+
assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA1
|
158
|
+
|
159
|
+
query_string = "SAMLResponse=#{CGI.escape(params['SAMLResponse'])}"
|
160
|
+
query_string << "&RelayState=#{CGI.escape(params[:RelayState])}"
|
161
|
+
query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}"
|
162
|
+
|
163
|
+
signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
|
164
|
+
assert_equal signature_algorithm, OpenSSL::Digest::SHA1
|
165
|
+
assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "create a signature parameter with RSA_SHA256 /SHA256 and validate it" do
|
169
|
+
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
|
170
|
+
|
171
|
+
params = OneLogin::RubySaml::SloLogoutresponse.new.create_params(settings, nil, "Custom Logout Message", :RelayState => 'http://example.com')
|
172
|
+
assert params['SAMLResponse']
|
173
|
+
assert params[:RelayState]
|
174
|
+
assert params['Signature']
|
175
|
+
|
176
|
+
assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA256
|
177
|
+
|
178
|
+
query_string = "SAMLResponse=#{CGI.escape(params['SAMLResponse'])}"
|
179
|
+
query_string << "&RelayState=#{CGI.escape(params[:RelayState])}"
|
180
|
+
query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}"
|
181
|
+
|
182
|
+
signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
|
183
|
+
assert_equal signature_algorithm, OpenSSL::Digest::SHA256
|
184
|
+
assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
|
185
|
+
end
|
186
|
+
|
187
|
+
it "create a signature parameter with RSA_SHA384 / SHA384 and validate it" do
|
188
|
+
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA384
|
189
|
+
|
190
|
+
params = OneLogin::RubySaml::SloLogoutresponse.new.create_params(settings, nil, "Custom Logout Message", :RelayState => 'http://example.com')
|
191
|
+
assert params['SAMLResponse']
|
192
|
+
assert params[:RelayState]
|
193
|
+
assert params['Signature']
|
194
|
+
|
195
|
+
assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA384
|
196
|
+
|
197
|
+
query_string = "SAMLResponse=#{CGI.escape(params['SAMLResponse'])}"
|
198
|
+
query_string << "&RelayState=#{CGI.escape(params[:RelayState])}"
|
199
|
+
query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}"
|
200
|
+
|
201
|
+
signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
|
202
|
+
assert_equal signature_algorithm, OpenSSL::Digest::SHA384
|
203
|
+
assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
|
204
|
+
end
|
205
|
+
|
206
|
+
it "create a signature parameter with RSA_SHA512 / SHA512 and validate it" do
|
207
|
+
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA512
|
208
|
+
|
209
|
+
params = OneLogin::RubySaml::SloLogoutresponse.new.create_params(settings, nil, "Custom Logout Message", :RelayState => 'http://example.com')
|
210
|
+
assert params['SAMLResponse']
|
211
|
+
assert params[:RelayState]
|
212
|
+
assert params['Signature']
|
213
|
+
|
214
|
+
assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA512
|
215
|
+
|
216
|
+
query_string = "SAMLResponse=#{CGI.escape(params['SAMLResponse'])}"
|
217
|
+
query_string << "&RelayState=#{CGI.escape(params[:RelayState])}"
|
218
|
+
query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}"
|
219
|
+
|
220
|
+
signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
|
221
|
+
assert_equal signature_algorithm, OpenSSL::Digest::SHA512
|
222
|
+
assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|