ruby-saml 1.0.0 → 1.1.0
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.
- data/.travis.yml +7 -0
- data/README.md +17 -3
- data/Rakefile +0 -14
- data/changelog.md +11 -0
- data/lib/onelogin/ruby-saml/authrequest.rb +11 -2
- data/lib/onelogin/ruby-saml/response.rb +31 -14
- data/lib/onelogin/ruby-saml/saml_message.rb +1 -1
- data/lib/onelogin/ruby-saml/version.rb +1 -1
- data/lib/xml_security.rb +68 -58
- data/ruby-saml.gemspec +11 -3
- data/test/response_test.rb +104 -6
- data/test/responses/response_with_ds_namespace_at_the_root.xml.base64 +1 -0
- data/test/responses/response_without_reference_uri.xml.base64 +1 -0
- data/test/responses/signed_nameid_in_atts.xml +47 -0
- data/test/responses/signed_unqual_nameid_in_atts.xml +47 -0
- data/test/responses/valid_response_without_x509certificate.xml.base64 +1 -0
- data/test/test_helper.rb +13 -0
- data/test/xml_security_test.rb +11 -5
- metadata +82 -34
- checksums.yaml +0 -7
data/.travis.yml
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
sudo: false
|
1
2
|
language: ruby
|
2
3
|
rvm:
|
3
4
|
- 1.8.7
|
@@ -6,6 +7,8 @@ rvm:
|
|
6
7
|
- 2.1.5
|
7
8
|
- 2.2.0
|
8
9
|
- ree
|
10
|
+
- jruby-1.7.21
|
11
|
+
- jruby-9.0.0.0
|
9
12
|
gemfile:
|
10
13
|
- Gemfile
|
11
14
|
- gemfiles/nokogiri-1.5.gemfile
|
@@ -15,3 +18,7 @@ matrix:
|
|
15
18
|
gemfile: Gemfile
|
16
19
|
- rvm: ree
|
17
20
|
gemfile: Gemfile
|
21
|
+
- rvm: jruby-9.0.0.0
|
22
|
+
gemfile: gemfiles/nokogiri-1.5.gemfile
|
23
|
+
- rvm: jruby-1.7.21
|
24
|
+
gemfile: gemfiles/nokogiri-1.5.gemfile
|
data/README.md
CHANGED
@@ -1,14 +1,18 @@
|
|
1
|
-
# Ruby SAML [](http://travis-ci.org/onelogin/ruby-saml)
|
1
|
+
# Ruby SAML [](http://travis-ci.org/onelogin/ruby-saml) [](https://coveralls.io/r/onelogin/ruby-saml?branch=master%0A) [](http://badge.fury.io/rb/ruby-saml)
|
2
2
|
|
3
3
|
|
4
|
+
## Updating from 1.0.x to 1.1.X
|
5
|
+
|
6
|
+
Version `1.1` adds some improvements on signature validation and solves some namespace conflicts.
|
7
|
+
|
8
|
+
For more details, please review [the changelog](changelog.md).
|
9
|
+
|
4
10
|
## Updating from 0.9.x to 1.0.X
|
5
11
|
|
6
12
|
Version `1.0` is a recommended update for all Ruby SAML users as it includes security fixes.
|
7
13
|
|
8
14
|
Version `1.0` adds security improvements like entity expansion limitation, more SAML message validations, and other important improvements like decrypt support.
|
9
15
|
|
10
|
-
For more details, please review [the changelog](changelog.md).
|
11
|
-
|
12
16
|
### Important Changes
|
13
17
|
Please note the `get_idp_metadata` method raises an exception when it is not able to fetch the idp metadata, so review your integration if you are using this functionality.
|
14
18
|
|
@@ -31,6 +35,8 @@ We created a demo project for Rails4 that uses the latest version of this librar
|
|
31
35
|
* 1.9.x
|
32
36
|
* 2.1.x
|
33
37
|
* 2.2.x
|
38
|
+
* JRuby 1.7.19
|
39
|
+
* JRuby 9.0.0.0
|
34
40
|
|
35
41
|
## Adding Features, Pull Requests
|
36
42
|
* Fork the repository
|
@@ -164,6 +170,13 @@ def saml_settings
|
|
164
170
|
end
|
165
171
|
```
|
166
172
|
|
173
|
+
Some assertion validations can be skipped by passing parameters to OneLogin::RubySaml::Response.new(). For example, you can skip the Conditions validation or the SubjectConfirmation validations by initializing the response with different options:
|
174
|
+
|
175
|
+
```ruby
|
176
|
+
response = OneLogin::RubySaml::Response.new(params[:SAMLResponse], {skip_conditions: true}) # skips conditions
|
177
|
+
response = OneLogin::RubySaml::Response.new(params[:SAMLResponse], {skip_subject_confirmation: true}) # skips subject confirmation
|
178
|
+
```
|
179
|
+
|
167
180
|
What's left at this point, is to wrap it all up in a controller and point the initialization and consumption URLs in OneLogin at that. A full controller example could look like this:
|
168
181
|
|
169
182
|
```ruby
|
@@ -394,6 +407,7 @@ Service Provider.
|
|
394
407
|
|
395
408
|
Notice that this toolkit uses 'settings.certificate' and 'settings.private_key' for the sign and the decrypt process.
|
396
409
|
|
410
|
+
Enable/disable the soft mode by the settings.soft parameter. When is set false, the saml validations errors will raise an exception.
|
397
411
|
|
398
412
|
## Decrypting
|
399
413
|
|
data/Rakefile
CHANGED
@@ -25,17 +25,3 @@ end
|
|
25
25
|
task :test
|
26
26
|
|
27
27
|
task :default => :test
|
28
|
-
|
29
|
-
# require 'rake/rdoctask'
|
30
|
-
# Rake::RDocTask.new do |rdoc|
|
31
|
-
# if File.exist?('VERSION')
|
32
|
-
# version = File.read('VERSION')
|
33
|
-
# else
|
34
|
-
# version = ""
|
35
|
-
# end
|
36
|
-
|
37
|
-
# rdoc.rdoc_dir = 'rdoc'
|
38
|
-
# rdoc.title = "ruby-saml #{version}"
|
39
|
-
# rdoc.rdoc_files.include('README*')
|
40
|
-
# rdoc.rdoc_files.include('lib/**/*.rb')
|
41
|
-
#end
|
data/changelog.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# RubySaml Changelog
|
2
2
|
|
3
|
+
### 1.1.0 (October 27, 2015)
|
4
|
+
* [#273](https://github.com/onelogin/ruby-saml/pull/273) Support SAMLResponse without ds:x509certificate
|
5
|
+
* [#270](https://github.com/onelogin/ruby-saml/pull/270) Allow SAML elements to come from any namespace (at decryption process)
|
6
|
+
* [#261](https://github.com/onelogin/ruby-saml/pull/261) Allow validate_subject_confirmation Response validation to be skipped
|
7
|
+
* [#258](https://github.com/onelogin/ruby-saml/pull/258) Fix allowed_clock_drift on the validate_session_expiration test
|
8
|
+
* [#256](https://github.com/onelogin/ruby-saml/pull/256) Separate the create_authentication_xml_doc in two methods.
|
9
|
+
* [#255](https://github.com/onelogin/ruby-saml/pull/255) Refactor validate signature.
|
10
|
+
* [#254](https://github.com/onelogin/ruby-saml/pull/254) Handle empty URI references
|
11
|
+
* [#251](https://github.com/onelogin/ruby-saml/pull/251) Support qualified and unqualified NameID in attributes
|
12
|
+
* [#234](https://github.com/onelogin/ruby-saml/pull/234) Add explicit support for JRuby
|
13
|
+
|
3
14
|
### 1.0.0 (June 30, 2015)
|
4
15
|
* [#247](https://github.com/onelogin/ruby-saml/pull/247) Avoid entity expansion (XEE attacks)
|
5
16
|
* [#246](https://github.com/onelogin/ruby-saml/pull/246) Fix bug generating Logout Response (issuer was at wrong order)
|
@@ -87,6 +87,11 @@ module OneLogin
|
|
87
87
|
# @return [String] The SAMLRequest String.
|
88
88
|
#
|
89
89
|
def create_authentication_xml_doc(settings)
|
90
|
+
document = create_xml_document(settings)
|
91
|
+
sign_document(document, settings)
|
92
|
+
end
|
93
|
+
|
94
|
+
def create_xml_document(settings)
|
90
95
|
time = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
|
91
96
|
|
92
97
|
request_doc = XMLSecurity::Document.new
|
@@ -141,14 +146,18 @@ module OneLogin
|
|
141
146
|
end
|
142
147
|
end
|
143
148
|
|
149
|
+
request_doc
|
150
|
+
end
|
151
|
+
|
152
|
+
def sign_document(document, settings)
|
144
153
|
# embed signature
|
145
154
|
if settings.security[:authn_requests_signed] && settings.private_key && settings.certificate && settings.security[:embed_sign]
|
146
155
|
private_key = settings.get_sp_key
|
147
156
|
cert = settings.get_sp_cert
|
148
|
-
|
157
|
+
document.sign_document(private_key, cert, settings.security[:signature_method], settings.security[:digest_method])
|
149
158
|
end
|
150
159
|
|
151
|
-
|
160
|
+
document
|
152
161
|
end
|
153
162
|
|
154
163
|
end
|
@@ -36,7 +36,8 @@ module OneLogin
|
|
36
36
|
# @param options [Hash] :settings to provide the OneLogin::RubySaml::Settings object
|
37
37
|
# Or some options for the response validation process like skip the conditions validation
|
38
38
|
# with the :skip_conditions, or allow a clock_drift when checking dates with :allowed_clock_drift
|
39
|
-
# or :matches_request_id that will validate that the response matches the ID of the request
|
39
|
+
# or :matches_request_id that will validate that the response matches the ID of the request,
|
40
|
+
# or skip the subject confirmation validation with the :skip_subject_confirmation option
|
40
41
|
def initialize(response, options = {})
|
41
42
|
@errors = []
|
42
43
|
|
@@ -94,6 +95,7 @@ module OneLogin
|
|
94
95
|
|
95
96
|
alias_method :nameid, :name_id
|
96
97
|
|
98
|
+
|
97
99
|
# Gets the SessionIndex from the AuthnStatement.
|
98
100
|
# Could be used to be stored in the local session in order
|
99
101
|
# to be used in a future Logout Request that the SP could
|
@@ -131,12 +133,22 @@ module OneLogin
|
|
131
133
|
stmt_element.elements.each do |attr_element|
|
132
134
|
name = attr_element.attributes["Name"]
|
133
135
|
values = attr_element.elements.collect{|e|
|
134
|
-
|
135
|
-
|
136
|
-
|
136
|
+
if (e.elements.nil? || e.elements.size == 0)
|
137
|
+
# SAMLCore requires that nil AttributeValues MUST contain xsi:nil XML attribute set to "true" or "1"
|
138
|
+
# otherwise the value is to be regarded as empty.
|
139
|
+
["true", "1"].include?(e.attributes['xsi:nil']) ? nil : e.text.to_s
|
140
|
+
# explicitly support saml2:NameID with saml2:NameQualifier if supplied in attributes
|
141
|
+
# this is useful for allowing eduPersonTargetedId to be passed as an opaque identifier to use to
|
142
|
+
# identify the subject in an SP rather than email or other less opaque attributes
|
143
|
+
# NameQualifier, if present is prefixed with a "/" to the value
|
144
|
+
else
|
145
|
+
REXML::XPath.match(e,'a:NameID', { "a" => ASSERTION }).collect{|n|
|
146
|
+
(n.attributes['NameQualifier'] ? n.attributes['NameQualifier'] +"/" : '') + n.text.to_s
|
147
|
+
}
|
148
|
+
end
|
137
149
|
}
|
138
150
|
|
139
|
-
attributes.add(name, values)
|
151
|
+
attributes.add(name, values.flatten)
|
140
152
|
end
|
141
153
|
|
142
154
|
attributes
|
@@ -316,11 +328,9 @@ module OneLogin
|
|
316
328
|
|
317
329
|
# Validates that the SAML Response provided in the initialization is not empty,
|
318
330
|
# also check that the setting and the IdP cert were also provided
|
319
|
-
# @
|
320
|
-
# @return [Boolean] True if the required info is found, otherwise False if soft=True
|
321
|
-
# @raise [ValidationError] if soft == false and validation fails
|
331
|
+
# @return [Boolean] True if the required info is found, false otherwise
|
322
332
|
#
|
323
|
-
def validate_response_state
|
333
|
+
def validate_response_state
|
324
334
|
return append_error("Blank response") if response.nil? || response.empty?
|
325
335
|
|
326
336
|
return append_error("No settings on response") if settings.nil?
|
@@ -504,7 +514,7 @@ module OneLogin
|
|
504
514
|
return true if session_expires_at.nil?
|
505
515
|
|
506
516
|
now = Time.now.utc
|
507
|
-
unless session_expires_at
|
517
|
+
unless (session_expires_at + allowed_clock_drift) > now
|
508
518
|
error_msg = "The attributes have expired, based on the SessionNotOnOrAfter of the AttributeStatement of this Response"
|
509
519
|
return append_error(error_msg)
|
510
520
|
end
|
@@ -513,12 +523,14 @@ module OneLogin
|
|
513
523
|
end
|
514
524
|
|
515
525
|
# Validates if exists valid SubjectConfirmation (If the response was initialized with the :allowed_clock_drift option,
|
516
|
-
# timimg validation are relaxed by the allowed_clock_drift value
|
526
|
+
# timimg validation are relaxed by the allowed_clock_drift value. If the response was initialized with the
|
527
|
+
# :skip_subject_confirmation option, this validation is skipped)
|
517
528
|
# If fails, the error is added to the errors array
|
518
529
|
# @return [Boolean] True if exists a valid SubjectConfirmation, otherwise False if soft=True
|
519
530
|
# @raise [ValidationError] if soft == false and validation fails
|
520
531
|
#
|
521
532
|
def validate_subject_confirmation
|
533
|
+
return true if options[:skip_subject_confirmation]
|
522
534
|
valid_subject_confirmation = false
|
523
535
|
|
524
536
|
subject_confirmation_nodes = xpath_from_signed_assertion('/a:Subject/a:SubjectConfirmation')
|
@@ -560,6 +572,7 @@ module OneLogin
|
|
560
572
|
#
|
561
573
|
def validate_signature
|
562
574
|
fingerprint = settings.get_fingerprint
|
575
|
+
idp_cert = settings.get_idp_cert
|
563
576
|
|
564
577
|
# If the response contains the signature, and the assertion was encrypted, validate the original SAML Response
|
565
578
|
# otherwise, review if the decrypted assertion contains a signature
|
@@ -571,7 +584,11 @@ module OneLogin
|
|
571
584
|
)
|
572
585
|
doc = (response_signed || decrypted_document.nil?) ? document : decrypted_document
|
573
586
|
|
574
|
-
|
587
|
+
opts = {}
|
588
|
+
opts[:fingerprint_alg] = settings.idp_cert_fingerprint_algorithm
|
589
|
+
opts[:cert] = idp_cert
|
590
|
+
|
591
|
+
unless fingerprint && doc.validate_document(fingerprint, @soft, opts)
|
575
592
|
error_msg = "Invalid Signature on SAML Response"
|
576
593
|
return append_error(error_msg)
|
577
594
|
end
|
@@ -676,7 +693,7 @@ module OneLogin
|
|
676
693
|
# @return [REXML::Document] The decrypted EncryptedAssertion element
|
677
694
|
#
|
678
695
|
def decrypt_assertion(encrypted_assertion_node)
|
679
|
-
decrypt_element(encrypted_assertion_node, /(.*<\/(
|
696
|
+
decrypt_element(encrypted_assertion_node, /(.*<\/(\w+:)?Assertion>)/m)
|
680
697
|
end
|
681
698
|
|
682
699
|
# Decrypts an EncryptedID element
|
@@ -684,7 +701,7 @@ module OneLogin
|
|
684
701
|
# @return [REXML::Document] The decrypted EncrypedtID element
|
685
702
|
#
|
686
703
|
def decrypt_nameid(encryptedid_node)
|
687
|
-
decrypt_element(encryptedid_node, /(.*<\/(
|
704
|
+
decrypt_element(encryptedid_node, /(.*<\/(\w+:)?NameID>)/m)
|
688
705
|
end
|
689
706
|
|
690
707
|
# Decrypt an element
|
@@ -23,7 +23,7 @@ module OneLogin
|
|
23
23
|
# @return [Nokogiri::XML::Schema] Gets the schema object of the SAML 2.0 Protocol schema
|
24
24
|
#
|
25
25
|
def self.schema
|
26
|
-
|
26
|
+
Mutex.new.synchronize do
|
27
27
|
Dir.chdir(File.expand_path("../../../schemas", __FILE__)) do
|
28
28
|
::Nokogiri::XML::Schema(File.read("saml-schema-protocol-2.0.xsd"))
|
29
29
|
end
|
data/lib/xml_security.rb
CHANGED
@@ -199,77 +199,98 @@ module XMLSecurity
|
|
199
199
|
"//ds:X509Certificate",
|
200
200
|
{ "ds"=>DSIG }
|
201
201
|
)
|
202
|
-
|
203
|
-
|
204
|
-
|
202
|
+
|
203
|
+
if cert_element
|
204
|
+
base64_cert = cert_element.text
|
205
|
+
cert_text = Base64.decode64(base64_cert)
|
206
|
+
cert = OpenSSL::X509::Certificate.new(cert_text)
|
207
|
+
|
208
|
+
if options[:fingerprint_alg]
|
209
|
+
fingerprint_alg = XMLSecurity::BaseDocument.new.algorithm(options[:fingerprint_alg]).new
|
205
210
|
else
|
206
|
-
|
211
|
+
fingerprint_alg = OpenSSL::Digest::SHA1.new
|
207
212
|
end
|
208
|
-
|
209
|
-
base64_cert = cert_element.text
|
210
|
-
cert_text = Base64.decode64(base64_cert)
|
211
|
-
cert = OpenSSL::X509::Certificate.new(cert_text)
|
213
|
+
fingerprint = fingerprint_alg.hexdigest(cert.to_der)
|
212
214
|
|
213
|
-
|
214
|
-
|
215
|
+
# check cert matches registered idp cert
|
216
|
+
if fingerprint != idp_cert_fingerprint.gsub(/[^a-zA-Z0-9]/,"").downcase
|
217
|
+
@errors << "Fingerprint mismatch"
|
218
|
+
return soft ? false : (raise OneLogin::RubySaml::ValidationError.new("Fingerprint mismatch"))
|
219
|
+
end
|
215
220
|
else
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
221
|
+
if options[:cert]
|
222
|
+
base64_cert = Base64.encode64(options[:cert].to_pem)
|
223
|
+
else
|
224
|
+
if soft
|
225
|
+
return false
|
226
|
+
else
|
227
|
+
raise OneLogin::RubySaml::ValidationError.new("Certificate element missing in response (ds:X509Certificate) and not cert provided at settings")
|
228
|
+
end
|
229
|
+
end
|
224
230
|
end
|
225
|
-
|
226
231
|
validate_signature(base64_cert, soft)
|
227
232
|
end
|
228
233
|
|
229
234
|
def validate_signature(base64_cert, soft = true)
|
230
|
-
# validate references
|
231
|
-
|
232
|
-
# check for inclusive namespaces
|
233
|
-
inclusive_namespaces = extract_inclusive_namespaces
|
234
235
|
|
235
236
|
document = Nokogiri.parse(self.to_s) do |options|
|
236
237
|
options = XMLSecurity::BaseDocument::NOKOGIRI_OPTIONS
|
237
238
|
end
|
238
239
|
|
239
|
-
# create a
|
240
|
+
# create a rexml document
|
240
241
|
@working_copy ||= REXML::Document.new(self.to_s).root
|
241
242
|
|
242
|
-
#
|
243
|
-
|
244
|
-
element = REXML::XPath.first(
|
243
|
+
# get signature node
|
244
|
+
sig_element = REXML::XPath.first(
|
245
245
|
@working_copy,
|
246
246
|
"//ds:Signature",
|
247
247
|
{"ds"=>DSIG}
|
248
|
-
|
249
|
-
element.remove
|
250
|
-
end
|
248
|
+
)
|
251
249
|
|
252
|
-
#
|
253
|
-
|
254
|
-
|
255
|
-
"
|
250
|
+
# signature method
|
251
|
+
sig_alg_value = REXML::XPath.first(
|
252
|
+
sig_element,
|
253
|
+
"./ds:SignedInfo/ds:SignatureMethod",
|
256
254
|
{"ds"=>DSIG}
|
257
255
|
)
|
258
|
-
|
259
|
-
|
256
|
+
signature_algorithm = algorithm(sig_alg_value)
|
257
|
+
|
258
|
+
# get signature
|
259
|
+
base64_signature = REXML::XPath.first(
|
260
|
+
sig_element,
|
261
|
+
"./ds:SignatureValue",
|
262
|
+
{"ds" => DSIG}
|
263
|
+
).text
|
264
|
+
signature = Base64.decode64(base64_signature)
|
265
|
+
|
266
|
+
# canonicalization method
|
260
267
|
canon_algorithm = canon_algorithm REXML::XPath.first(
|
261
|
-
|
262
|
-
'
|
268
|
+
sig_element,
|
269
|
+
'./ds:SignedInfo/ds:CanonicalizationMethod',
|
263
270
|
'ds' => DSIG
|
264
271
|
)
|
272
|
+
|
273
|
+
noko_sig_element = document.at_xpath('//ds:Signature', 'ds' => DSIG)
|
274
|
+
noko_signed_info_element = noko_sig_element.at_xpath('./ds:SignedInfo', 'ds' => DSIG)
|
275
|
+
|
276
|
+
# Handle when no URI
|
277
|
+
noko_signed_info_reference_element_uri_attr = noko_signed_info_element.at_xpath('./ds:Reference', 'ds' => DSIG).attributes["URI"]
|
278
|
+
if (noko_signed_info_reference_element_uri_attr.value.empty?)
|
279
|
+
noko_signed_info_reference_element_uri_attr.value = "##{document.root.attribute('ID')}"
|
280
|
+
end
|
281
|
+
|
265
282
|
canon_string = noko_signed_info_element.canonicalize(canon_algorithm)
|
266
283
|
noko_sig_element.remove
|
267
284
|
|
285
|
+
# get inclusive namespaces
|
286
|
+
inclusive_namespaces = extract_inclusive_namespaces
|
287
|
+
|
268
288
|
# check digests
|
269
|
-
REXML::XPath.each(
|
289
|
+
REXML::XPath.each(sig_element, "//ds:Reference", {"ds"=>DSIG}) do |ref|
|
270
290
|
uri = ref.attributes.get_attribute("URI").value
|
271
291
|
|
272
|
-
hashed_element = document.at_xpath("//*[@ID=$uri]", nil, { 'uri' => uri[1..-1] })
|
292
|
+
hashed_element = uri.empty? ? document : document.at_xpath("//*[@ID=$uri]", nil, { 'uri' => uri[1..-1] })
|
293
|
+
# hashed_element = document.at_xpath("//*[@ID=$uri]", nil, { 'uri' => uri[1..-1] })
|
273
294
|
canon_algorithm = canon_algorithm REXML::XPath.first(
|
274
295
|
ref,
|
275
296
|
'//ds:CanonicalizationMethod',
|
@@ -296,26 +317,11 @@ module XMLSecurity
|
|
296
317
|
end
|
297
318
|
end
|
298
319
|
|
299
|
-
base64_signature = REXML::XPath.first(
|
300
|
-
@sig_element,
|
301
|
-
"//ds:SignatureValue",
|
302
|
-
{"ds" => DSIG}
|
303
|
-
).text
|
304
|
-
|
305
|
-
signature = Base64.decode64(base64_signature)
|
306
|
-
|
307
320
|
# get certificate object
|
308
321
|
cert_text = Base64.decode64(base64_cert)
|
309
322
|
cert = OpenSSL::X509::Certificate.new(cert_text)
|
310
323
|
|
311
|
-
# signature
|
312
|
-
sig_alg_value = REXML::XPath.first(
|
313
|
-
signed_info_element,
|
314
|
-
"//ds:SignatureMethod",
|
315
|
-
{"ds"=>DSIG}
|
316
|
-
)
|
317
|
-
signature_algorithm = algorithm(sig_alg_value)
|
318
|
-
|
324
|
+
# verify signature
|
319
325
|
unless cert.public_key.verify(signature_algorithm.new, signature, canon_string)
|
320
326
|
@errors << "Key validation error"
|
321
327
|
return soft ? false : (raise OneLogin::RubySaml::ValidationError.new("Key validation error"))
|
@@ -336,7 +342,11 @@ module XMLSecurity
|
|
336
342
|
"//ds:Signature/ds:SignedInfo/ds:Reference",
|
337
343
|
{"ds"=>DSIG}
|
338
344
|
)
|
339
|
-
|
345
|
+
|
346
|
+
return nil if reference_element.nil?
|
347
|
+
|
348
|
+
sei = reference_element.attribute("URI").value[1..-1]
|
349
|
+
sei.nil? ? self.root.attribute("ID") : sei
|
340
350
|
end
|
341
351
|
|
342
352
|
def extract_inclusive_namespaces
|
@@ -349,7 +359,7 @@ module XMLSecurity
|
|
349
359
|
prefix_list = element.attributes.get_attribute("PrefixList").value
|
350
360
|
prefix_list.split(" ")
|
351
361
|
else
|
352
|
-
|
362
|
+
nil
|
353
363
|
end
|
354
364
|
end
|
355
365
|
|
data/ruby-saml.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.license = 'MIT'
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"LICENSE",
|
16
|
-
|
16
|
+
"README.md"
|
17
17
|
]
|
18
18
|
s.files = `git ls-files`.split("\n")
|
19
19
|
s.homepage = %q{http://github.com/onelogin/ruby-saml}
|
@@ -30,7 +30,12 @@ Gem::Specification.new do |s|
|
|
30
30
|
# Because runtime dependencies are determined at build time, we cannot make
|
31
31
|
# Nokogiri's version dependent on the Ruby version, even though we would
|
32
32
|
# have liked to constrain Ruby 1.8.7 to install only the 1.5.x versions.
|
33
|
-
|
33
|
+
if defined?(JRUBY_VERSION)
|
34
|
+
s.add_runtime_dependency('nokogiri', '>= 1.6.0')
|
35
|
+
s.add_runtime_dependency('jruby-openssl', '>= 0.9.8')
|
36
|
+
else
|
37
|
+
s.add_runtime_dependency('nokogiri', '>= 1.5.10')
|
38
|
+
end
|
34
39
|
|
35
40
|
s.add_development_dependency('minitest', '~> 5.5')
|
36
41
|
s.add_development_dependency('mocha', '~> 0.14')
|
@@ -40,7 +45,10 @@ Gem::Specification.new do |s|
|
|
40
45
|
s.add_development_dependency('systemu', '~> 2')
|
41
46
|
s.add_development_dependency('timecop', '<= 0.6.0')
|
42
47
|
|
43
|
-
if
|
48
|
+
if defined?(JRUBY_VERSION)
|
49
|
+
# All recent versions of JRuby play well with pry
|
50
|
+
s.add_development_dependency('pry')
|
51
|
+
elsif RUBY_VERSION < '1.9'
|
44
52
|
# 1.8.7
|
45
53
|
s.add_development_dependency('ruby-debug', '~> 0.10.4')
|
46
54
|
elsif RUBY_VERSION < '2.0'
|
data/test/response_test.rb
CHANGED
@@ -9,11 +9,14 @@ class RubySamlTest < Minitest::Test
|
|
9
9
|
let(:settings) { OneLogin::RubySaml::Settings.new }
|
10
10
|
let(:response) { OneLogin::RubySaml::Response.new(response_document_without_recipient) }
|
11
11
|
let(:response_without_attributes) { OneLogin::RubySaml::Response.new(response_document_without_attributes) }
|
12
|
+
let(:response_without_reference_uri) { OneLogin::RubySaml::Response.new(response_document_without_reference_uri) }
|
12
13
|
let(:response_with_signed_assertion) { OneLogin::RubySaml::Response.new(response_document_with_signed_assertion) }
|
14
|
+
let(:response_with_ds_namespace_at_the_root) { OneLogin::RubySaml::Response.new(response_document_with_ds_namespace_at_the_root)}
|
13
15
|
let(:response_unsigned) { OneLogin::RubySaml::Response.new(response_document_unsigned) }
|
14
16
|
let(:response_wrapped) { OneLogin::RubySaml::Response.new(response_document_wrapped) }
|
15
17
|
let(:response_multiple_attr_values) { OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values)) }
|
16
18
|
let(:response_valid_signed) { OneLogin::RubySaml::Response.new(response_document_valid_signed) }
|
19
|
+
let(:response_valid_signed_without_x509certificate) { OneLogin::RubySaml::Response.new(response_document_valid_signed_without_x509certificate) }
|
17
20
|
let(:response_no_id) { OneLogin::RubySaml::Response.new(read_invalid_response("no_id.xml.base64")) }
|
18
21
|
let(:response_no_version) { OneLogin::RubySaml::Response.new(read_invalid_response("no_saml2.xml.base64")) }
|
19
22
|
let(:response_multi_assertion) { OneLogin::RubySaml::Response.new(read_invalid_response("multiple_assertions.xml.base64")) }
|
@@ -55,7 +58,7 @@ class RubySamlTest < Minitest::Test
|
|
55
58
|
|
56
59
|
describe "Prevent XEE attack" do
|
57
60
|
before do
|
58
|
-
@response = OneLogin::RubySaml::Response.new(fixture(:attackxee))
|
61
|
+
@response = OneLogin::RubySaml::Response.new(fixture(:attackxee))
|
59
62
|
end
|
60
63
|
|
61
64
|
it "false when evil attack vector is present, soft = true" do
|
@@ -384,6 +387,15 @@ class RubySamlTest < Minitest::Test
|
|
384
387
|
response_no_version.is_valid?
|
385
388
|
assert_includes response_no_version.errors, "Unsupported SAML version"
|
386
389
|
end
|
390
|
+
|
391
|
+
it "return true when a nil URI is given in the ds:Reference" do
|
392
|
+
|
393
|
+
response_without_reference_uri.stubs(:conditions).returns(nil)
|
394
|
+
response_without_reference_uri.settings = settings
|
395
|
+
response_without_reference_uri.settings.idp_cert_fingerprint = "19:4D:97:E4:D8:C9:C8:CF:A4:B7:21:E5:EE:49:7F:D9:66:0E:52:13"
|
396
|
+
assert response_without_reference_uri.is_valid?
|
397
|
+
assert_empty response_without_reference_uri.errors
|
398
|
+
end
|
387
399
|
end
|
388
400
|
end
|
389
401
|
|
@@ -409,7 +421,7 @@ class RubySamlTest < Minitest::Test
|
|
409
421
|
assert response_valid_signed.send(:validate_issuer)
|
410
422
|
|
411
423
|
response_valid_signed.settings.idp_entity_id = 'https://app.onelogin.com/saml2'
|
412
|
-
assert response_valid_signed.send(:validate_issuer)
|
424
|
+
assert response_valid_signed.send(:validate_issuer)
|
413
425
|
end
|
414
426
|
|
415
427
|
it "return false when the issuer of the Message does not match the IdP entityId" do
|
@@ -491,7 +503,7 @@ class RubySamlTest < Minitest::Test
|
|
491
503
|
response = OneLogin::RubySaml::Response.new(response_document_valid_signed, :settings => settings, :matches_request_id => "_fc4a34b0-7efb-012e-caae-782bcb13bb38")
|
492
504
|
assert response.send(:validate_in_response_to)
|
493
505
|
assert_empty response.errors
|
494
|
-
end
|
506
|
+
end
|
495
507
|
|
496
508
|
it "return true when no Request ID is provided for checking" do
|
497
509
|
response = OneLogin::RubySaml::Response.new(response_document_valid_signed, :settings => settings)
|
@@ -606,6 +618,27 @@ class RubySamlTest < Minitest::Test
|
|
606
618
|
assert !response_invalid_subjectconfirmation_noa.send(:validate_subject_confirmation)
|
607
619
|
assert_includes response_invalid_subjectconfirmation_noa.errors, "A valid SubjectConfirmation was not found on this Response"
|
608
620
|
end
|
621
|
+
|
622
|
+
it "return true when the skip_subject_confirmation option is passed and the subject confirmation is valid" do
|
623
|
+
opts = {}
|
624
|
+
opts[:skip_subject_confirmation] = true
|
625
|
+
response_with_skip = OneLogin::RubySaml::Response.new(response_document_valid_signed, opts)
|
626
|
+
response_with_skip.settings = settings
|
627
|
+
response_with_skip.settings.assertion_consumer_service_url = 'recipient'
|
628
|
+
Time.expects(:now).times(0) # ensures the test isn't run and thus Time.now.utc is never called within the test
|
629
|
+
assert response_with_skip.send(:validate_subject_confirmation)
|
630
|
+
assert_empty response_with_skip.errors
|
631
|
+
end
|
632
|
+
|
633
|
+
it "return true when the skip_subject_confirmation option is passed and the response has an invalid subject confirmation" do
|
634
|
+
opts = {}
|
635
|
+
opts[:skip_subject_confirmation] = true
|
636
|
+
response_with_skip = OneLogin::RubySaml::Response.new(read_invalid_response("invalid_subjectconfirmation_noa.xml.base64"), opts)
|
637
|
+
response_with_skip.settings = settings
|
638
|
+
Time.expects(:now).times(0) # ensures the test isn't run and thus Time.now.utc is never called within the test
|
639
|
+
assert response_with_skip.send(:validate_subject_confirmation)
|
640
|
+
assert_empty response_with_skip.errors
|
641
|
+
end
|
609
642
|
end
|
610
643
|
|
611
644
|
describe "#validate_session_expiration" do
|
@@ -620,6 +653,18 @@ class RubySamlTest < Minitest::Test
|
|
620
653
|
assert !response.send(:validate_session_expiration)
|
621
654
|
assert_includes response.errors, "The attributes have expired, based on the SessionNotOnOrAfter of the AttributeStatement of this Response"
|
622
655
|
end
|
656
|
+
|
657
|
+
it "returns true when the session has expired, but is still within the allowed_clock_drift" do
|
658
|
+
drift = (Time.now - Time.parse("2010-11-19T21:57:37Z")) * 60 # seconds ago that this assertion expired
|
659
|
+
drift += 10 # add a buffer of 10 seconds to make sure the test passes
|
660
|
+
opts = {}
|
661
|
+
opts[:allowed_clock_drift] = drift
|
662
|
+
|
663
|
+
response_with_drift = OneLogin::RubySaml::Response.new(response_document_without_recipient, opts)
|
664
|
+
response_with_drift.settings = settings
|
665
|
+
assert response_with_drift.send(:validate_session_expiration)
|
666
|
+
assert_empty response_with_drift.errors
|
667
|
+
end
|
623
668
|
end
|
624
669
|
|
625
670
|
describe "#validate_signature" do
|
@@ -630,6 +675,13 @@ class RubySamlTest < Minitest::Test
|
|
630
675
|
assert_empty response_valid_signed.errors
|
631
676
|
end
|
632
677
|
|
678
|
+
it "return true when the signature is valid and ds namespace is at the root" do
|
679
|
+
settings.idp_cert_fingerprint = '5614657ab692b960480389723a36446a5fe1f7ec'
|
680
|
+
response_with_ds_namespace_at_the_root.settings = settings
|
681
|
+
assert response_with_ds_namespace_at_the_root.send(:validate_signature)
|
682
|
+
assert_empty response_with_ds_namespace_at_the_root.errors
|
683
|
+
end
|
684
|
+
|
633
685
|
it "return false when no fingerprint" do
|
634
686
|
settings.idp_cert_fingerprint = nil
|
635
687
|
settings.idp_cert = nil
|
@@ -644,6 +696,30 @@ class RubySamlTest < Minitest::Test
|
|
644
696
|
assert !response.send(:validate_signature)
|
645
697
|
assert_includes response.errors, "Invalid Signature on SAML Response"
|
646
698
|
end
|
699
|
+
|
700
|
+
it "return false when no X509Certificate and not cert provided at settings" do
|
701
|
+
settings.idp_cert_fingerprint = ruby_saml_cert_fingerprint
|
702
|
+
settings.idp_cert = nil
|
703
|
+
response_valid_signed_without_x509certificate.settings = settings
|
704
|
+
assert !response_valid_signed_without_x509certificate.send(:validate_signature)
|
705
|
+
assert_includes response_valid_signed_without_x509certificate.errors, "Invalid Signature on SAML Response"
|
706
|
+
end
|
707
|
+
|
708
|
+
it "return false when no X509Certificate and the cert provided at settings mismatches" do
|
709
|
+
settings.idp_cert_fingerprint = nil
|
710
|
+
settings.idp_cert = signature_1
|
711
|
+
response_valid_signed_without_x509certificate.settings = settings
|
712
|
+
assert !response_valid_signed_without_x509certificate.send(:validate_signature)
|
713
|
+
assert_includes response_valid_signed_without_x509certificate.errors, "Invalid Signature on SAML Response"
|
714
|
+
end
|
715
|
+
|
716
|
+
it "return true when no X509Certificate and the cert provided at settings matches" do
|
717
|
+
settings.idp_cert_fingerprint = nil
|
718
|
+
settings.idp_cert = ruby_saml_cert_text
|
719
|
+
response_valid_signed_without_x509certificate.settings = settings
|
720
|
+
assert response_valid_signed_without_x509certificate.send(:validate_signature)
|
721
|
+
assert_empty response_valid_signed_without_x509certificate.errors
|
722
|
+
end
|
647
723
|
end
|
648
724
|
|
649
725
|
describe "#nameid" do
|
@@ -888,7 +964,7 @@ class RubySamlTest < Minitest::Test
|
|
888
964
|
it 'is not possible when encryptID inside the assertion but no private key' do
|
889
965
|
response_encrypted_nameid.settings = settings
|
890
966
|
assert_raises(OneLogin::RubySaml::ValidationError, "An EncryptedID found and no SP private key found on the settings to decrypt it") do
|
891
|
-
assert_equal "test@onelogin.com", response_encrypted_nameid.nameid
|
967
|
+
assert_equal "test@onelogin.com", response_encrypted_nameid.nameid
|
892
968
|
end
|
893
969
|
end
|
894
970
|
|
@@ -1007,7 +1083,7 @@ class RubySamlTest < Minitest::Test
|
|
1007
1083
|
describe "check right settings" do
|
1008
1084
|
|
1009
1085
|
it "is not possible to decrypt the assertion if no private key" do
|
1010
|
-
response = OneLogin::RubySaml::Response.new(signed_message_encrypted_unsigned_assertion, :settings => settings)
|
1086
|
+
response = OneLogin::RubySaml::Response.new(signed_message_encrypted_unsigned_assertion, :settings => settings)
|
1011
1087
|
|
1012
1088
|
encrypted_assertion_node = REXML::XPath.first(
|
1013
1089
|
response.document,
|
@@ -1023,7 +1099,7 @@ class RubySamlTest < Minitest::Test
|
|
1023
1099
|
end
|
1024
1100
|
|
1025
1101
|
it "is possible to decrypt the assertion if private key" do
|
1026
|
-
response = OneLogin::RubySaml::Response.new(signed_message_encrypted_unsigned_assertion, :settings => settings)
|
1102
|
+
response = OneLogin::RubySaml::Response.new(signed_message_encrypted_unsigned_assertion, :settings => settings)
|
1027
1103
|
|
1028
1104
|
encrypted_assertion_node = REXML::XPath.first(
|
1029
1105
|
response.document,
|
@@ -1090,5 +1166,27 @@ class RubySamlTest < Minitest::Test
|
|
1090
1166
|
assert_equal "_ce3d2948b4cf20146dee0a0b3dd6f69b6cf86f62d7", response.nameid
|
1091
1167
|
end
|
1092
1168
|
end
|
1169
|
+
|
1170
|
+
end
|
1171
|
+
describe "test qualified name id in attributes" do
|
1172
|
+
|
1173
|
+
it "parsed the nameid" do
|
1174
|
+
response = OneLogin::RubySaml::Response.new(read_response("signed_nameid_in_atts.xml"), :settings => settings)
|
1175
|
+
response.settings.idp_cert_fingerprint = 'c51985d947f1be57082025050846eb27f6cab783'
|
1176
|
+
assert_empty response.errors
|
1177
|
+
assert_equal "test", response.attributes[:uid]
|
1178
|
+
assert_equal "http://idp.example.com/metadata.php/ZdrjpwEdw22vKoxWAbZB78/gQ7s=", response.attributes.single('urn:oid:1.3.6.1.4.1.5923.1.1.1.10')
|
1179
|
+
end
|
1180
|
+
end
|
1181
|
+
|
1182
|
+
describe "test unqualified name id in attributes" do
|
1183
|
+
|
1184
|
+
it "parsed the nameid" do
|
1185
|
+
response = OneLogin::RubySaml::Response.new(read_response("signed_unqual_nameid_in_atts.xml"), :settings => settings)
|
1186
|
+
response.settings.idp_cert_fingerprint = 'c51985d947f1be57082025050846eb27f6cab783'
|
1187
|
+
assert_empty response.errors
|
1188
|
+
assert_equal "test", response.attributes[:uid]
|
1189
|
+
assert_equal "ZdrjpwEdw22vKoxWAbZB78/gQ7s=", response.attributes.single('urn:oid:1.3.6.1.4.1.5923.1.1.1.10')
|
1190
|
+
end
|
1093
1191
|
end
|
1094
1192
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiDQp4bWxuczpkcz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyIgeG1sbnM6c2FtbD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9Il84ZThkYzVmNjlhOThjYzRjMWZmMzQyN2U1Y2UzNDYwNmZkNjcyZjkxZTYiIFZlcnNpb249IjIuMCIgSXNzdWVJbnN0YW50PSIyMDE0LTA3LTE3VDAxOjAxOjQ4WiIgRGVzdGluYXRpb249Imh0dHA6Ly9zcC5leGFtcGxlLmNvbS9kZW1vMS9pbmRleC5waHA/YWNzIiBJblJlc3BvbnNlVG89Ik9ORUxPR0lOXzRmZWUzYjA0NjM5NWM0ZTc1MTAxMWU5N2Y4OTAwYjUyNzNkNTY2ODUiPg0KICA8c2FtbDpJc3N1ZXI+aHR0cDovL2lkcC5leGFtcGxlLmNvbS9tZXRhZGF0YS5waHA8L3NhbWw6SXNzdWVyPg0KICA8c2FtbHA6U3RhdHVzPg0KICAgIDxzYW1scDpTdGF0dXNDb2RlIFZhbHVlPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6c3RhdHVzOlN1Y2Nlc3MiLz4NCiAgPC9zYW1scDpTdGF0dXM+DQogIDxzYW1sOkFzc2VydGlvbiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIElEPSJwZng2YzViMTVjYy02YzY4LTljMWYtY2QzNy05ZTFmYTFkMmU3YTAiIFZlcnNpb249IjIuMCIgSXNzdWVJbnN0YW50PSIyMDE0LTA3LTE3VDAxOjAxOjQ4WiI+DQogICAgPHNhbWw6SXNzdWVyPmh0dHA6Ly9pZHAuZXhhbXBsZS5jb20vbWV0YWRhdGEucGhwPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlPg0KICA8ZHM6U2lnbmVkSW5mbz48ZHM6Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPg0KICAgIDxkczpTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjcnNhLXNoYTEiLz4NCiAgPGRzOlJlZmVyZW5jZSBVUkk9IiNwZng2YzViMTVjYy02YzY4LTljMWYtY2QzNy05ZTFmYTFkMmU3YTAiPjxkczpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L2RzOlRyYW5zZm9ybXM+PGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNzaGExIi8+PGRzOkRpZ2VzdFZhbHVlPmlHdENJcGpyZ09Hc2FDY0lFOEtwSWEzVzZnVT08L2RzOkRpZ2VzdFZhbHVlPjwvZHM6UmVmZXJlbmNlPjwvZHM6U2lnbmVkSW5mbz48ZHM6U2lnbmF0dXJlVmFsdWU+T0RIU2tzUkl1ZEc3b2s0KzRUZitPRnA0UFJ4Ukc3d3BERGdyVDZwQk5ZbUFKNUN2dFk5UlczRldHYlJtZ2NoSjdhYW9sQ3ViekQ5Qkk4Y01nb3V6ZGErdjcrZ1k4THloVUNmV2RSd0gvSzZlVmYvZUtldjk3aUQ1YVA1TTU1MCtCZ0NVaHVWNFg0MlpUbFhkdjBVKzRDQ1VYWnFuLzRjczBxNXhkeTBoM0JzPTwvZHM6U2lnbmF0dXJlVmFsdWU+DQo8ZHM6S2V5SW5mbz48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlDYWpDQ0FkT2dBd0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUTBGQURCU01Rc3dDUVlEVlFRR0V3SjFjekVUTUJFR0ExVUVDQXdLUTJGc2FXWnZjbTVwWVRFVk1CTUdBMVVFQ2d3TVQyNWxiRzluYVc0Z1NXNWpNUmN3RlFZRFZRUUREQTV6Y0M1bGVHRnRjR3hsTG1OdmJUQWVGdzB4TkRBM01UY3hOREV5TlRaYUZ3MHhOVEEzTVRjeE5ERXlOVFphTUZJeEN6QUpCZ05WQkFZVEFuVnpNUk13RVFZRFZRUUlEQXBEWVd4cFptOXlibWxoTVJVd0V3WURWUVFLREF4UGJtVnNiMmRwYmlCSmJtTXhGekFWQmdOVkJBTU1Ebk53TG1WNFlXMXdiR1V1WTI5dE1JR2ZNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0R05BRENCaVFLQmdRRFp4K09ONElVb0lXeGd1a1RiMXRPaVgzYk1ZellRaXdXUFVOTXArRnE4MnhvTm9nc28yYnlrWkcweWlKbTVvOHp2L3NkNnBHb3VheU1na3gvMkZTT2RjMzZUMGpHYkNIdVJTYnRpYTBQRXpOSVJ0bVZpTXJ0M0Flb1dCaWRSWG1ac3hDTkx3Z0lWNmRuMldwdUU1QXowYkhncFpuUXhUS0ZlazBCTUtVL2Q4d0lEQVFBQm8xQXdUakFkQmdOVkhRNEVGZ1FVR0h4WXFaWXlYN2NUeEtWT0RWZ1p3U1RkQ253d0h3WURWUjBqQkJnd0ZvQVVHSHhZcVpZeVg3Y1R4S1ZPRFZnWndTVGRDbnd3REFZRFZSMFRCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUTBGQUFPQmdRQnlGT2wraE1GSUNiZDNESmZucDJSZ2QvZHF0dHNaRy90eWhJTFd2RXJiaW8vREVlOThtWHBvd2hUa0MwNEVOcHJPeVhpN1piVXFpaWNGODl1QUd5dDFvcWdUVUNEMVZzTGFocUljbXJ6Z3VtTnlUd0xHV28xN1dEQWExL3VzRGhldFdBTWhnekYvQ25mNWVrMG5LMDBtMFlaR3ljNEx6Z0QwQ1JPTUFTVFdOZz09PC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+DQogICAgPHNhbWw6U3ViamVjdD4NCiAgICAgIDxzYW1sOk5hbWVJRCBTUE5hbWVRdWFsaWZpZXI9Imh0dHA6Ly9zcC5leGFtcGxlLmNvbS9kZW1vMS9tZXRhZGF0YS5waHAiIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6dHJhbnNpZW50Ij5fY2UzZDI5NDhiNGNmMjAxNDZkZWUwYTBiM2RkNmY2OWI2Y2Y4NmY2MmQ3PC9zYW1sOk5hbWVJRD4NCiAgICAgIDxzYW1sOlN1YmplY3RDb25maXJtYXRpb24gTWV0aG9kPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6Y206YmVhcmVyIj4NCiAgICAgICAgPHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbkRhdGEgTm90T25PckFmdGVyPSIyMDI0LTAxLTE4VDA2OjIxOjQ4WiIgUmVjaXBpZW50PSJodHRwOi8vc3AuZXhhbXBsZS5jb20vZGVtbzEvaW5kZXgucGhwP2FjcyIgSW5SZXNwb25zZVRvPSJPTkVMT0dJTl80ZmVlM2IwNDYzOTVjNGU3NTEwMTFlOTdmODkwMGI1MjczZDU2Njg1Ii8+DQogICAgICA8L3NhbWw6U3ViamVjdENvbmZpcm1hdGlvbj4NCiAgICA8L3NhbWw6U3ViamVjdD4NCiAgICA8c2FtbDpDb25kaXRpb25zIE5vdEJlZm9yZT0iMjAxNC0wNy0xN1QwMTowMToxOFoiIE5vdE9uT3JBZnRlcj0iMjAyNC0wMS0xOFQwNjoyMTo0OFoiPg0KICAgICAgPHNhbWw6QXVkaWVuY2VSZXN0cmljdGlvbj4NCiAgICAgICAgPHNhbWw6QXVkaWVuY2U+aHR0cDovL3NwLmV4YW1wbGUuY29tL2RlbW8xL21ldGFkYXRhLnBocDwvc2FtbDpBdWRpZW5jZT4NCiAgICAgIDwvc2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPg0KICAgIDwvc2FtbDpDb25kaXRpb25zPg0KICAgIDxzYW1sOkF1dGhuU3RhdGVtZW50IEF1dGhuSW5zdGFudD0iMjAxNC0wNy0xN1QwMTowMTo0OFoiIFNlc3Npb25Ob3RPbk9yQWZ0ZXI9IjIwMjQtMDctMTdUMDk6MDE6NDhaIiBTZXNzaW9uSW5kZXg9Il9iZTk5NjdhYmQ5MDRkZGNhZTNjMGViNDE4OWFkYmUzZjcxZTMyN2NmOTMiPg0KICAgICAgPHNhbWw6QXV0aG5Db250ZXh0Pg0KICAgICAgICA8c2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6Y2xhc3NlczpQYXNzd29yZDwvc2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj4NCiAgICAgIDwvc2FtbDpBdXRobkNvbnRleHQ+DQogICAgPC9zYW1sOkF1dGhuU3RhdGVtZW50Pg0KICAgIDxzYW1sOkF0dHJpYnV0ZVN0YXRlbWVudD4NCiAgICAgIDxzYW1sOkF0dHJpYnV0ZSBOYW1lPSJ1aWQiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6YmFzaWMiPg0KICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4c2k6dHlwZT0ieHM6c3RyaW5nIj50ZXN0PC9zYW1sOkF0dHJpYnV0ZVZhbHVlPg0KICAgICAgPC9zYW1sOkF0dHJpYnV0ZT4NCiAgICAgIDxzYW1sOkF0dHJpYnV0ZSBOYW1lPSJtYWlsIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj4NCiAgICAgICAgPHNhbWw6QXR0cmlidXRlVmFsdWUgeHNpOnR5cGU9InhzOnN0cmluZyI+dGVzdEBleGFtcGxlLmNvbTwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT4NCiAgICAgIDwvc2FtbDpBdHRyaWJ1dGU+DQogICAgICA8c2FtbDpBdHRyaWJ1dGUgTmFtZT0iZWR1UGVyc29uQWZmaWxpYXRpb24iIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6YmFzaWMiPg0KICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4c2k6dHlwZT0ieHM6c3RyaW5nIj51c2Vyczwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT4NCiAgICAgICAgPHNhbWw6QXR0cmlidXRlVmFsdWUgeHNpOnR5cGU9InhzOnN0cmluZyI+ZXhhbXBsZXJvbGUxPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPg0KICAgICAgPC9zYW1sOkF0dHJpYnV0ZT4NCiAgICA8L3NhbWw6QXR0cmlidXRlU3RhdGVtZW50Pg0KICA8L3NhbWw6QXNzZXJ0aW9uPg0KPC9zYW1scDpSZXNwb25zZT4=
|
@@ -0,0 +1 @@
|
|
1
|
+
PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c2FtbHA6UmVzcG9uc2UgeG1sbnM6c2FtbHA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCIgSUQ9InBmeGQ1OTQzNDdkLTQ5NWYtYjhkMS0wZWUyLTQxY2ZkYTE0ZGQzNSIgVmVyc2lvbj0iMi4wIiBJc3N1ZUluc3RhbnQ9IjIwMTUtMDEtMDJUMjI6NDg6NDhaIiBEZXN0aW5hdGlvbj0iaHR0cDovL2xvY2FsaG9zdDo5MDAxL3YxL3VzZXJzL2F1dGhvcml6ZS9zYW1sIiBDb25zZW50PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6Y29uc2VudDp1bnNwZWNpZmllZCIgSW5SZXNwb25zZVRvPSJfZWQ5MTVhNDAtNzRmYi0wMTMyLTViMTYtNDhlMGViMTRhMWM3Ij4NCiAgPElzc3VlciB4bWxucz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+aHR0cDovL2V4YW1wbGUuY29tPC9Jc3N1ZXI+PGRzOlNpZ25hdHVyZSB4bWxuczpkcz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+DQogIDxkczpTaWduZWRJbmZvPjxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+DQogICAgPGRzOlNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNyc2Etc2hhMSIvPg0KICA8ZHM6UmVmZXJlbmNlIFVSST0iIj48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT5qQ2dlWENQREZsd2pUZ3FnUHAwbVUyVHF3OWc9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPkRmdXByMTh3UityRGFndENQRWZRbFNHSHp3NE5kZlBIWjRIc3pGZTFKUENKWGpmYnlFTTFmZytqemdHYk1NdDZYemdDWGNLSk03RS9DUFNURGt2TWUzRFVKbEh1NERodURPQXovRHN5b0J3V3VWK1JmM1dpTmNGNFhDYzl3QlF6dm4vYXREN3pXNnh3TzdOL2hrQVpKcWZ2SmRkbnBNTUhLR1hxRy9aSFpBdz08L2RzOlNpZ25hdHVyZVZhbHVlPg0KPGRzOktleUluZm8+PGRzOlg1MDlEYXRhPjxkczpYNTA5Q2VydGlmaWNhdGU+TUlJQ3FEQ0NBaEdnQXdJQkFnSUJBREFOQmdrcWhraUc5dzBCQVEwRkFEQnhNUXN3Q1FZRFZRUUdFd0oxY3pFVE1CRUdBMVVFQ0F3S1YyRnphR2x1WjNSdmJqRWlNQ0FHQTFVRUNnd1pSbXhoZENCWGIzSnNaQ0JMYm05M2JHVmtaMlVzSUVsdVl6RWNNQm9HQTFVRUF3d1RiR1ZoY200dVpteGhkSGR2Y214a0xtTnZiVEVMTUFrR0ExVUVCd3dDUkVNd0hoY05NVFV3TnpBNE1EazFPVEF6V2hjTk1qVXdOekExTURrMU9UQXpXakJ4TVFzd0NRWURWUVFHRXdKMWN6RVRNQkVHQTFVRUNBd0tWMkZ6YUdsdVozUnZiakVpTUNBR0ExVUVDZ3daUm14aGRDQlhiM0pzWkNCTGJtOTNiR1ZrWjJVc0lFbHVZekVjTUJvR0ExVUVBd3dUYkdWaGNtNHVabXhoZEhkdmNteGtMbU52YlRFTE1Ba0dBMVVFQnd3Q1JFTXdnWjh3RFFZSktvWklodmNOQVFFQkJRQURnWTBBTUlHSkFvR0JBTVBEd3NsNW82eDJRb3VOaTEvRTdJVXFSWWoyWW9jSlJGc3VFR1RldnlVKzJhRkNhQk5WL3R0NnNBYk05V1N1dEx1cWpFL2hmYm5sRWNaMDMrZ24wQ29MbDZZbXdiS0tlUnBrSXplVmhveUoxWVlNUUVBVmhMcmR5OFBvd3U4VUNaMFBiQXorbjlka2lSek01cENDTzc3K2d5Y0ZUQkZLSEFBOXFJcFVaWmtQQWdNQkFBR2pVREJPTUIwR0ExVWREZ1FXQkJRSFU1OGl1R3hGbFp1ckJVSndvbGFsSnIrRlJ6QWZCZ05WSFNNRUdEQVdnQlFIVTU4aXVHeEZsWnVyQlVKd29sYWxKcitGUnpBTUJnTlZIUk1FQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCRFFVQUE0R0JBQzZpSGZNbWQraE1TUnpma29zaTNDK3d2cUhDTEVVc2czSEZwa1ptNWp4bVREbEY1cU8rQnQwbjB4bWZvcVdCekJNbE5DOFRzR3JhZmhKM3p1OEdORjBMZW8xMXJmYzFHTUdCdnI1SG9aM1dBQXltbkJFREFBb3N4TjZXWlJtajF4YWdhMTMrNnBXZkdCKysyblB3Y1pXUC84ZGtQY1JvZ2V2VjB4MHA1Njg2PC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+DQogIDxzYW1scDpTdGF0dXM+DQogICAgPHNhbWxwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPg0KICA8L3NhbWxwOlN0YXR1cz4NCg0KICA8QXNzZXJ0aW9uIHhtbG5zPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiBJRD0iXzcwMGFjMzIwLTc0ZmYtMDEzMi01YjE0LTQ4ZTBlYjE0YTFjNyIgSXNzdWVJbnN0YW50PSIyMDE1LTAxLTAyVDIyOjQ4OjQ4WiIgVmVyc2lvbj0iMi4wIj4NCiAgICA8SXNzdWVyPmh0dHA6Ly9leGFtcGxlLmNvbTwvSXNzdWVyPg0KICAgIDxTdWJqZWN0Pg0KICAgICAgPE5hbWVJRCBGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OmVtYWlsQWRkcmVzcyI+c2FtbEB1c2VyLmNvbTwvTmFtZUlEPg0KICAgICAgPFN1YmplY3RDb25maXJtYXRpb24gTWV0aG9kPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6Y206YmVhcmVyIj4NCiAgICAgICAgPFN1YmplY3RDb25maXJtYXRpb25EYXRhIEluUmVzcG9uc2VUbz0iX2VkOTE1YTQwLTc0ZmItMDEzMi01YjE2LTQ4ZTBlYjE0YTFjNyIgTm90T25PckFmdGVyPSIyMDM4LTAxLTAyVDIyOjUxOjQ4WiIgUmVjaXBpZW50PSJodHRwOi8vbG9jYWxob3N0OjkwMDEvdjEvdXNlcnMvYXV0aG9yaXplL3NhbWwiLz4NCiAgICAgIDwvU3ViamVjdENvbmZpcm1hdGlvbj4NCiAgICA8L1N1YmplY3Q+DQogICAgPENvbmRpdGlvbnMgTm90QmVmb3JlPSIyMDE1LTAxLTAyVDIyOjQ4OjQzWiIgTm90T25PckFmdGVyPSIyMDM4LTAxLTAyVDIzOjQ4OjQ4WiI+DQogICAgICA8QXVkaWVuY2VSZXN0cmljdGlvbj4NCiAgICAgICAgPEF1ZGllbmNlPmh0dHA6Ly9sb2NhbGhvc3Q6OTAwMS88L0F1ZGllbmNlPg0KICAgICAgICA8QXVkaWVuY2U+ZmxhdF93b3JsZDwvQXVkaWVuY2U+DQogICAgICA8L0F1ZGllbmNlUmVzdHJpY3Rpb24+DQogICAgPC9Db25kaXRpb25zPg0KICAgIDxBdHRyaWJ1dGVTdGF0ZW1lbnQ+DQogICAgICA8QXR0cmlidXRlIE5hbWU9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL2VtYWlsYWRkcmVzcyI+DQogICAgICAgIDxBdHRyaWJ1dGVWYWx1ZT5zYW1sQHVzZXIuY29tPC9BdHRyaWJ1dGVWYWx1ZT4NCiAgICAgIDwvQXR0cmlidXRlPg0KICAgIDwvQXR0cmlidXRlU3RhdGVtZW50Pg0KICAgIDxBdXRoblN0YXRlbWVudCBBdXRobkluc3RhbnQ9IjIwMTUtMDEtMDJUMjI6NDg6NDhaIiBTZXNzaW9uSW5kZXg9Il83MDBhYzMyMC03NGZmLTAxMzItNWIxNC00OGUwZWIxNGExYzciPg0KICAgICAgPEF1dGhuQ29udGV4dD4NCiAgICAgICAgPEF1dGhuQ29udGV4dENsYXNzUmVmPnVybjpmZWRlcmF0aW9uOmF1dGhlbnRpY2F0aW9uOndpbmRvd3M8L0F1dGhuQ29udGV4dENsYXNzUmVmPg0KICAgICAgPC9BdXRobkNvbnRleHQ+DQogICAgPC9BdXRoblN0YXRlbWVudD4NCiAgPC9Bc3NlcnRpb24+DQo8L3NhbWxwOlJlc3BvbnNlPg==
|
@@ -0,0 +1,47 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="pfx3437f097-cd95-f187-4501-0bce24d4d6f8" Version="2.0" IssueInstant="2014-07-17T01:01:48Z" Destination="http://sp.example.com/demo1/index.php?acs" InResponseTo="ONELOGIN_4fee3b046395c4e751011e97f8900b5273d56685">
|
3
|
+
<saml:Issuer>http://idp.example.com/metadata.php</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
4
|
+
<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
5
|
+
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
6
|
+
<ds:Reference URI="#pfx3437f097-cd95-f187-4501-0bce24d4d6f8"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>7IMOicPUD8hBuAv8HeVDrUErclY=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>jPBUr/iVsSXvMeT6PhQxSTbi3j6M34OQiyAKLPyPQWypX0uJ04UbC2J4v1DqFqC3OJYyepQ6OBocSMH4r+uqv4hdoWeaj1Ieeo4HRB5UFTxhR4TV8tTPpEZjGA2vXz74BjtCi6PMWVe/28/TejkAosHfe62WktcznTvfWKePlFA=</ds:SignatureValue>
|
7
|
+
<ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICGzCCAYQCCQCNNcQXom32VDANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJVUzELMAkGA1UECBMCSU4xFTATBgNVBAcTDEluZGlhbmFwb2xpczERMA8GA1UEChMIT25lTG9naW4xDDAKBgNVBAsTA0VuZzAeFw0xNDA0MjMxODQxMDFaFw0xNTA0MjMxODQxMDFaMFIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTjEVMBMGA1UEBxMMSW5kaWFuYXBvbGlzMREwDwYDVQQKEwhPbmVMb2dpbjEMMAoGA1UECxMDRW5nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDo6m+QZvYQ/xL0ElLgupK1QDcYL4f5PckwsNgS9pUvV7fzTqCHk8ThLxTk42MQ2McJsOeUJVP728KhymjFCqxgP4VuwRk9rpAl0+mhy6MPdyjyA6G14jrDWS65ysLchK4t/vwpEDz0SQlEoG1kMzllSm7zZS3XregA7DjNaUYQqwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBALM2vGCiQ/vm+a6v40+VX2zdqHA2Q/1vF1ibQzJ54MJCOVWvs+vQXfZFhdm0OPM2IrDU7oqvKPqP6xOAeJK6H0yP7M4YL3fatSvIYmmfyXC9kt3Svz/NyrHzPhUnJ0ye/sUSXxnzQxwcm/9PwAqrQaA3QpQkH57ybF/OoryPe+2h</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature>
|
8
|
+
<samlp:Status>
|
9
|
+
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
|
10
|
+
</samlp:Status>
|
11
|
+
<saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="_d71a3a8e9fcc45c9e9d248ef7049393fc8f04e5f75" Version="2.0" IssueInstant="2014-07-17T01:01:48Z">
|
12
|
+
<saml:Issuer>http://idp.example.com/metadata.php</saml:Issuer>
|
13
|
+
<saml:Subject>
|
14
|
+
<saml:NameID SPNameQualifier="http://sp.example.com/demo1/metadata.php" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">_ce3d2948b4cf20146dee0a0b3dd6f69b6cf86f62d7</saml:NameID>
|
15
|
+
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
|
16
|
+
<saml:SubjectConfirmationData NotOnOrAfter="2024-01-18T06:21:48Z" Recipient="http://sp.example.com/demo1/index.php?acs" InResponseTo="ONELOGIN_4fee3b046395c4e751011e97f8900b5273d56685"/>
|
17
|
+
</saml:SubjectConfirmation>
|
18
|
+
</saml:Subject>
|
19
|
+
<saml:Conditions NotBefore="2014-07-17T01:01:18Z" NotOnOrAfter="2024-01-18T06:21:48Z">
|
20
|
+
<saml:AudienceRestriction>
|
21
|
+
<saml:Audience>http://sp.example.com/demo1/metadata.php</saml:Audience>
|
22
|
+
</saml:AudienceRestriction>
|
23
|
+
</saml:Conditions>
|
24
|
+
<saml:AuthnStatement AuthnInstant="2014-07-17T01:01:48Z" SessionNotOnOrAfter="2024-07-17T09:01:48Z" SessionIndex="_be9967abd904ddcae3c0eb4189adbe3f71e327cf93">
|
25
|
+
<saml:AuthnContext>
|
26
|
+
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
|
27
|
+
</saml:AuthnContext>
|
28
|
+
</saml:AuthnStatement>
|
29
|
+
<saml:AttributeStatement>
|
30
|
+
<saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
31
|
+
<saml:AttributeValue xsi:type="xs:string">test</saml:AttributeValue>
|
32
|
+
</saml:Attribute>
|
33
|
+
<saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
34
|
+
<saml:AttributeValue xsi:type="xs:string">test@example.com</saml:AttributeValue>
|
35
|
+
</saml:Attribute>
|
36
|
+
<saml:Attribute Name="eduPersonAffiliation" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
37
|
+
<saml:AttributeValue xsi:type="xs:string">users</saml:AttributeValue>
|
38
|
+
<saml:AttributeValue xsi:type="xs:string">examplerole1</saml:AttributeValue>
|
39
|
+
</saml:Attribute>
|
40
|
+
<saml:Attribute FriendlyName="eduPersonTargetedID" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
|
41
|
+
<saml:AttributeValue>
|
42
|
+
<saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" NameQualifier="http://idp.example.com/metadata.php" SPNameQualifier="http://sp.example.com/demo1/metadata.php">ZdrjpwEdw22vKoxWAbZB78/gQ7s=</saml:NameID>
|
43
|
+
</saml:AttributeValue>
|
44
|
+
</saml:Attribute>
|
45
|
+
</saml:AttributeStatement>
|
46
|
+
</saml:Assertion>
|
47
|
+
</samlp:Response>
|
@@ -0,0 +1,47 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="pfx852f7331-dd1c-95c3-9cbe-0ab1ebf9c538" Version="2.0" IssueInstant="2014-07-17T01:01:48Z" Destination="http://sp.example.com/demo1/index.php?acs" InResponseTo="ONELOGIN_4fee3b046395c4e751011e97f8900b5273d56685">
|
3
|
+
<saml:Issuer>http://idp.example.com/metadata.php</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
4
|
+
<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
5
|
+
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
6
|
+
<ds:Reference URI="#pfx852f7331-dd1c-95c3-9cbe-0ab1ebf9c538"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>LQa/IrEdbLE1BHEP3B7KfvOABpg=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>fWg7OauBy7cExPo+GbNVb1e1OopaYc0ke+BYF1N4bpoej86o7U75xOttDN7oz58LhpDZYWcgEvsqX/Jth7Adc3v0bsUEw1h3rFVhGCOnJLS21o1r9cEdkUSbGcJ7jk6EnlxE9s3/puAxkanqzC50hWsIm19Xzu9Li1MN3eDgB9M=</ds:SignatureValue>
|
7
|
+
<ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICGzCCAYQCCQCNNcQXom32VDANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJVUzELMAkGA1UECBMCSU4xFTATBgNVBAcTDEluZGlhbmFwb2xpczERMA8GA1UEChMIT25lTG9naW4xDDAKBgNVBAsTA0VuZzAeFw0xNDA0MjMxODQxMDFaFw0xNTA0MjMxODQxMDFaMFIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTjEVMBMGA1UEBxMMSW5kaWFuYXBvbGlzMREwDwYDVQQKEwhPbmVMb2dpbjEMMAoGA1UECxMDRW5nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDo6m+QZvYQ/xL0ElLgupK1QDcYL4f5PckwsNgS9pUvV7fzTqCHk8ThLxTk42MQ2McJsOeUJVP728KhymjFCqxgP4VuwRk9rpAl0+mhy6MPdyjyA6G14jrDWS65ysLchK4t/vwpEDz0SQlEoG1kMzllSm7zZS3XregA7DjNaUYQqwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBALM2vGCiQ/vm+a6v40+VX2zdqHA2Q/1vF1ibQzJ54MJCOVWvs+vQXfZFhdm0OPM2IrDU7oqvKPqP6xOAeJK6H0yP7M4YL3fatSvIYmmfyXC9kt3Svz/NyrHzPhUnJ0ye/sUSXxnzQxwcm/9PwAqrQaA3QpQkH57ybF/OoryPe+2h</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature>
|
8
|
+
<samlp:Status>
|
9
|
+
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
|
10
|
+
</samlp:Status>
|
11
|
+
<saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="_d71a3a8e9fcc45c9e9d248ef7049393fc8f04e5f75" Version="2.0" IssueInstant="2014-07-17T01:01:48Z">
|
12
|
+
<saml:Issuer>http://idp.example.com/metadata.php</saml:Issuer>
|
13
|
+
<saml:Subject>
|
14
|
+
<saml:NameID SPNameQualifier="http://sp.example.com/demo1/metadata.php" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">_ce3d2948b4cf20146dee0a0b3dd6f69b6cf86f62d7</saml:NameID>
|
15
|
+
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
|
16
|
+
<saml:SubjectConfirmationData NotOnOrAfter="2024-01-18T06:21:48Z" Recipient="http://sp.example.com/demo1/index.php?acs" InResponseTo="ONELOGIN_4fee3b046395c4e751011e97f8900b5273d56685"/>
|
17
|
+
</saml:SubjectConfirmation>
|
18
|
+
</saml:Subject>
|
19
|
+
<saml:Conditions NotBefore="2014-07-17T01:01:18Z" NotOnOrAfter="2024-01-18T06:21:48Z">
|
20
|
+
<saml:AudienceRestriction>
|
21
|
+
<saml:Audience>http://sp.example.com/demo1/metadata.php</saml:Audience>
|
22
|
+
</saml:AudienceRestriction>
|
23
|
+
</saml:Conditions>
|
24
|
+
<saml:AuthnStatement AuthnInstant="2014-07-17T01:01:48Z" SessionNotOnOrAfter="2024-07-17T09:01:48Z" SessionIndex="_be9967abd904ddcae3c0eb4189adbe3f71e327cf93">
|
25
|
+
<saml:AuthnContext>
|
26
|
+
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
|
27
|
+
</saml:AuthnContext>
|
28
|
+
</saml:AuthnStatement>
|
29
|
+
<saml:AttributeStatement>
|
30
|
+
<saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
31
|
+
<saml:AttributeValue xsi:type="xs:string">test</saml:AttributeValue>
|
32
|
+
</saml:Attribute>
|
33
|
+
<saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
34
|
+
<saml:AttributeValue xsi:type="xs:string">test@example.com</saml:AttributeValue>
|
35
|
+
</saml:Attribute>
|
36
|
+
<saml:Attribute Name="eduPersonAffiliation" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
|
37
|
+
<saml:AttributeValue xsi:type="xs:string">users</saml:AttributeValue>
|
38
|
+
<saml:AttributeValue xsi:type="xs:string">examplerole1</saml:AttributeValue>
|
39
|
+
</saml:Attribute>
|
40
|
+
<saml:Attribute FriendlyName="eduPersonTargetedID" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
|
41
|
+
<saml:AttributeValue>
|
42
|
+
<saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">ZdrjpwEdw22vKoxWAbZB78/gQ7s=</saml:NameID>
|
43
|
+
</saml:AttributeValue>
|
44
|
+
</saml:Attribute>
|
45
|
+
</saml:AttributeStatement>
|
46
|
+
</saml:Assertion>
|
47
|
+
</samlp:Response>
|
@@ -0,0 +1 @@
|
|
1
|
+
pVZdd9o4EH3fc/Y/+LiPOcayDTb4BLoU0oSWfBDTbpuXPbI0Bie25Egi0Pz6lQ04kJI03X2CGY/u3LkjjXT8fpVnxgMImXLWNZ0GMt/3/vzjWOI8K8JrkAVnEgwdxGRYOrvmQrCQY5nKkOEcZKhIGPXPx6HbQCGWEoTSUObOkuL1NYXgihOemcZo2DWLZBWTtuvjhFrQScCiXhJbtB00LdIMECIeJIi0TePrlrPG0EulXMCISYWZ0i7kNC3kW6g5RW7ouiFyb0xjCFKlDKtq1VypIrRtXBSNfEFxg3FbSm4TXe4iBw3ItsVPedf8JyFN7DVjZAWg6SDHBYtgDFbQdmMSO14ce22zV8kWVlxEr8wgNyk4g4zPUtYgPLfLIPfY3o09pjKM0pkmtxBbtamsWS6Xy8bSa3Axs12EkI06to6hMp29M3W3DGO7HuiIJbyCG2DGWUpwlj5WJZ+DmnNq9LMZF6ma5y+AO7aDSnALVsQiTpO9M+0qxVOSiuQb4fa4CoktOcfOBrHEu4YEBDACxpfrUdd899b2VyVOBWYy4SKX++bvsQL2oJtTALXktjhN8PcAD6p2bP/McZjO9C78L+JthHsC+YqzBfRGj82bSSa9/qebYezJ9gP58s32rsnRx0m3IrAbXDlqydfms21TN3i9YjL//Cnn7Ie8cu5zhoPoCE6cMXHF5/7t7cC9PBWTy1l0e1VMOVnkE3/+/ezucRrdiEDZI/vz9DJ6OBtM7oeOmDezCN0Or+yTxdlFf6DuOt+DLHO//JgtAnd8FH9U9zduZ8g6YnwX0VORHo2Cs/lq7PkBTfpRNPeP5I/gb3g4oXfnyRKGE7f/TR8i/8OH09ljMD3p1uXs8NejbM/b20y2SGlT7lsDTsGolr0+sGQVHUYLQkDKqtE/g4b97SjcHOfVS8fZsb+djyMyhxybdWz662ArrcYdgZ9m4XqMdlqOH6PEs5otz7cclPgW8RNsdShtuR44zU6bvGlw/o+xVhnRIr4FojbWhdZzNDQ+6iOB1ctCOw2n8qTUSqrQUJecZn1KRSl6T+lN/ddu/k3mNfx+5gFnSVpilN1Yn73XO0zyMAYsQJgvAw2xwsYFV5fsUvQTBaJUz0M76gXra+caSFqkUMortn/rTXMI+dmnDQUdQdPysyyzfgCtClQNc55SOpuUb6C13aULmpazQF92SqRknX7vS91wyXPQgjdghfMig6rneBO0YVyveWbvodvPyqnzqTkrTxDkWiCjMn9xoUd6J2iEF6ptHQgdMQorfZ07ftIKUBIT5DkthAKMvFaLJoD92CNNn5i7pDRVBSt1wDXI9INHz9Peq28iEpIyTruv9M+SC3qlnzy6s0Cr26HgQtWCHQA/8G3PV4tWe7ejp55M27dM718=
|
data/test/test_helper.rb
CHANGED
@@ -10,6 +10,7 @@ require 'rubygems'
|
|
10
10
|
require 'bundler'
|
11
11
|
require 'minitest/autorun'
|
12
12
|
require 'mocha/setup'
|
13
|
+
require 'timecop'
|
13
14
|
|
14
15
|
Bundler.require :default, :test
|
15
16
|
|
@@ -51,6 +52,10 @@ class Minitest::Test
|
|
51
52
|
@response_document_valid_signed ||= read_response("valid_response.xml.base64")
|
52
53
|
end
|
53
54
|
|
55
|
+
def response_document_valid_signed_without_x509certificate
|
56
|
+
@response_document_valid_signed_without_x509certificate ||= read_response("valid_response_without_x509certificate.xml.base64")
|
57
|
+
end
|
58
|
+
|
54
59
|
def response_document_without_recipient
|
55
60
|
@response_document_without_recipient ||= read_response("response_with_undefined_recipient.xml.base64")
|
56
61
|
end
|
@@ -66,6 +71,10 @@ class Minitest::Test
|
|
66
71
|
@response_document_without_attributes ||= read_response("response_without_attributes.xml.base64")
|
67
72
|
end
|
68
73
|
|
74
|
+
def response_document_without_reference_uri
|
75
|
+
@response_document_without_reference_uri ||= read_response("response_without_reference_uri.xml.base64")
|
76
|
+
end
|
77
|
+
|
69
78
|
def response_document_with_signed_assertion
|
70
79
|
@response_document_with_signed_assertion ||= read_response("response_with_signed_assertion.xml.base64")
|
71
80
|
end
|
@@ -74,6 +83,10 @@ class Minitest::Test
|
|
74
83
|
@response_document_with_signed_assertion_2 ||= read_response("response_with_signed_assertion_2.xml.base64")
|
75
84
|
end
|
76
85
|
|
86
|
+
def response_document_with_ds_namespace_at_the_root
|
87
|
+
@response_document_with_ds_namespace_at_the_root ||= read_response("response_with_ds_namespace_at_the_root.xml.base64")
|
88
|
+
end
|
89
|
+
|
77
90
|
def response_document_unsigned
|
78
91
|
@response_document_unsigned ||= read_response("response_unsigned_xml_base64")
|
79
92
|
end
|
data/test/xml_security_test.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
|
2
2
|
require 'xml_security'
|
3
|
-
require 'timecop'
|
4
3
|
|
5
4
|
class XmlSecurityTest < Minitest::Test
|
6
5
|
include XMLSecurity
|
@@ -69,13 +68,20 @@ class XmlSecurityTest < Minitest::Test
|
|
69
68
|
assert adfs_document.validate_signature(base64cert, false)
|
70
69
|
end
|
71
70
|
|
72
|
-
it "raise validation error when the X509Certificate is missing" do
|
71
|
+
it "raise validation error when the X509Certificate is missing and no cert provided" do
|
73
72
|
decoded_response.sub!(/<ds:X509Certificate>.*<\/ds:X509Certificate>/, "")
|
74
73
|
mod_document = XMLSecurity::SignedDocument.new(decoded_response)
|
75
74
|
exception = assert_raises(OneLogin::RubySaml::ValidationError) do
|
76
75
|
mod_document.validate_document("a fingerprint", false) # The fingerprint isn't relevant to this test
|
77
76
|
end
|
78
|
-
assert_equal("Certificate element missing in response (ds:X509Certificate)", exception.message)
|
77
|
+
assert_equal("Certificate element missing in response (ds:X509Certificate) and not cert provided at settings", exception.message)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "invalidaties when the X509Certificate is missing and the cert is provided but mismatches" do
|
81
|
+
decoded_response.sub!(/<ds:X509Certificate>.*<\/ds:X509Certificate>/, "")
|
82
|
+
mod_document = XMLSecurity::SignedDocument.new(decoded_response)
|
83
|
+
cert = OpenSSL::X509::Certificate.new(ruby_saml_cert)
|
84
|
+
assert !mod_document.validate_document("a fingerprint", true, :cert => cert) # The fingerprint isn't relevant to this test
|
79
85
|
end
|
80
86
|
end
|
81
87
|
|
@@ -215,14 +221,14 @@ class XmlSecurityTest < Minitest::Test
|
|
215
221
|
assert response.is_valid?
|
216
222
|
end
|
217
223
|
|
218
|
-
it "return
|
224
|
+
it "return nil when inclusive namespace element is missing" do
|
219
225
|
response = fixture(:no_signature_ns, false)
|
220
226
|
response.slice! %r{<InclusiveNamespaces xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="#default saml ds xs xsi"/>}
|
221
227
|
|
222
228
|
document = XMLSecurity::SignedDocument.new(response)
|
223
229
|
inclusive_namespaces = document.send(:extract_inclusive_namespaces)
|
224
230
|
|
225
|
-
assert inclusive_namespaces.
|
231
|
+
assert inclusive_namespaces.nil?
|
226
232
|
end
|
227
233
|
end
|
228
234
|
|
metadata
CHANGED
@@ -1,155 +1,192 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-saml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- OneLogin LLC
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2015-
|
12
|
+
date: 2015-10-27 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: uuid
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
|
-
- -
|
19
|
+
- - ~>
|
18
20
|
- !ruby/object:Gem::Version
|
19
21
|
version: '2.3'
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
|
-
- -
|
27
|
+
- - ~>
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '2.3'
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
31
|
name: nokogiri
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
|
-
- -
|
35
|
+
- - ! '>='
|
32
36
|
- !ruby/object:Gem::Version
|
33
37
|
version: 1.5.10
|
34
38
|
type: :runtime
|
35
39
|
prerelease: false
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
37
42
|
requirements:
|
38
|
-
- -
|
43
|
+
- - ! '>='
|
39
44
|
- !ruby/object:Gem::Version
|
40
45
|
version: 1.5.10
|
41
46
|
- !ruby/object:Gem::Dependency
|
42
47
|
name: minitest
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
44
50
|
requirements:
|
45
|
-
- -
|
51
|
+
- - ~>
|
46
52
|
- !ruby/object:Gem::Version
|
47
53
|
version: '5.5'
|
48
54
|
type: :development
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
51
58
|
requirements:
|
52
|
-
- -
|
59
|
+
- - ~>
|
53
60
|
- !ruby/object:Gem::Version
|
54
61
|
version: '5.5'
|
55
62
|
- !ruby/object:Gem::Dependency
|
56
63
|
name: mocha
|
57
64
|
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
58
66
|
requirements:
|
59
|
-
- -
|
67
|
+
- - ~>
|
60
68
|
- !ruby/object:Gem::Version
|
61
69
|
version: '0.14'
|
62
70
|
type: :development
|
63
71
|
prerelease: false
|
64
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
65
74
|
requirements:
|
66
|
-
- -
|
75
|
+
- - ~>
|
67
76
|
- !ruby/object:Gem::Version
|
68
77
|
version: '0.14'
|
69
78
|
- !ruby/object:Gem::Dependency
|
70
79
|
name: rake
|
71
80
|
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
72
82
|
requirements:
|
73
|
-
- -
|
83
|
+
- - ~>
|
74
84
|
- !ruby/object:Gem::Version
|
75
85
|
version: '10'
|
76
86
|
type: :development
|
77
87
|
prerelease: false
|
78
88
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
79
90
|
requirements:
|
80
|
-
- -
|
91
|
+
- - ~>
|
81
92
|
- !ruby/object:Gem::Version
|
82
93
|
version: '10'
|
83
94
|
- !ruby/object:Gem::Dependency
|
84
95
|
name: shoulda
|
85
96
|
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
86
98
|
requirements:
|
87
|
-
- -
|
99
|
+
- - ~>
|
88
100
|
- !ruby/object:Gem::Version
|
89
101
|
version: '2.11'
|
90
102
|
type: :development
|
91
103
|
prerelease: false
|
92
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
93
106
|
requirements:
|
94
|
-
- -
|
107
|
+
- - ~>
|
95
108
|
- !ruby/object:Gem::Version
|
96
109
|
version: '2.11'
|
97
110
|
- !ruby/object:Gem::Dependency
|
98
111
|
name: simplecov
|
99
112
|
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
100
114
|
requirements:
|
101
|
-
- -
|
115
|
+
- - ~>
|
102
116
|
- !ruby/object:Gem::Version
|
103
117
|
version: 0.9.0
|
104
118
|
type: :development
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
107
122
|
requirements:
|
108
|
-
- -
|
123
|
+
- - ~>
|
109
124
|
- !ruby/object:Gem::Version
|
110
125
|
version: 0.9.0
|
111
126
|
- !ruby/object:Gem::Dependency
|
112
127
|
name: systemu
|
113
128
|
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
114
130
|
requirements:
|
115
|
-
- -
|
131
|
+
- - ~>
|
116
132
|
- !ruby/object:Gem::Version
|
117
133
|
version: '2'
|
118
134
|
type: :development
|
119
135
|
prerelease: false
|
120
136
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
121
138
|
requirements:
|
122
|
-
- -
|
139
|
+
- - ~>
|
123
140
|
- !ruby/object:Gem::Version
|
124
141
|
version: '2'
|
125
142
|
- !ruby/object:Gem::Dependency
|
126
143
|
name: timecop
|
127
144
|
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
128
146
|
requirements:
|
129
|
-
- -
|
147
|
+
- - <=
|
130
148
|
- !ruby/object:Gem::Version
|
131
149
|
version: 0.6.0
|
132
150
|
type: :development
|
133
151
|
prerelease: false
|
134
152
|
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
135
154
|
requirements:
|
136
|
-
- -
|
155
|
+
- - <=
|
137
156
|
- !ruby/object:Gem::Version
|
138
157
|
version: 0.6.0
|
139
158
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
159
|
+
name: debugger-linecache
|
141
160
|
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
142
162
|
requirements:
|
143
|
-
- -
|
163
|
+
- - ~>
|
144
164
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
165
|
+
version: 1.2.0
|
146
166
|
type: :development
|
147
167
|
prerelease: false
|
148
168
|
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
149
170
|
requirements:
|
150
|
-
- -
|
171
|
+
- - ~>
|
151
172
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
173
|
+
version: 1.2.0
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: debugger
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ~>
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: 1.6.4
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ~>
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: 1.6.4
|
153
190
|
description: SAML toolkit for Ruby on Rails
|
154
191
|
email: support@onelogin.com
|
155
192
|
executables: []
|
@@ -158,9 +195,9 @@ extra_rdoc_files:
|
|
158
195
|
- LICENSE
|
159
196
|
- README.md
|
160
197
|
files:
|
161
|
-
-
|
162
|
-
-
|
163
|
-
-
|
198
|
+
- .document
|
199
|
+
- .gitignore
|
200
|
+
- .travis.yml
|
164
201
|
- Gemfile
|
165
202
|
- LICENSE
|
166
203
|
- README.md
|
@@ -266,15 +303,19 @@ files:
|
|
266
303
|
- test/responses/response_unsigned_xml_base64
|
267
304
|
- test/responses/response_with_ampersands.xml
|
268
305
|
- test/responses/response_with_ampersands.xml.base64
|
306
|
+
- test/responses/response_with_ds_namespace_at_the_root.xml.base64
|
269
307
|
- test/responses/response_with_multiple_attribute_values.xml
|
270
308
|
- test/responses/response_with_saml2_namespace.xml.base64
|
271
309
|
- test/responses/response_with_signed_assertion.xml.base64
|
272
310
|
- test/responses/response_with_signed_assertion_2.xml.base64
|
273
311
|
- test/responses/response_with_undefined_recipient.xml.base64
|
274
312
|
- test/responses/response_without_attributes.xml.base64
|
313
|
+
- test/responses/response_without_reference_uri.xml.base64
|
275
314
|
- test/responses/response_wrapped.xml.base64
|
276
315
|
- test/responses/signed_message_encrypted_signed_assertion.xml.base64
|
277
316
|
- test/responses/signed_message_encrypted_unsigned_assertion.xml.base64
|
317
|
+
- test/responses/signed_nameid_in_atts.xml
|
318
|
+
- test/responses/signed_unqual_nameid_in_atts.xml
|
278
319
|
- test/responses/simple_saml_php.xml
|
279
320
|
- test/responses/starfield_response.xml.base64
|
280
321
|
- test/responses/test_sign.xml
|
@@ -286,6 +327,7 @@ files:
|
|
286
327
|
- test/responses/unsigned_message_encrypted_signed_assertion.xml.base64
|
287
328
|
- test/responses/unsigned_message_encrypted_unsigned_assertion.xml.base64
|
288
329
|
- test/responses/valid_response.xml.base64
|
330
|
+
- test/responses/valid_response_without_x509certificate.xml.base64
|
289
331
|
- test/saml_message_test.rb
|
290
332
|
- test/settings_test.rb
|
291
333
|
- test/slo_logoutrequest_test.rb
|
@@ -296,27 +338,28 @@ files:
|
|
296
338
|
homepage: http://github.com/onelogin/ruby-saml
|
297
339
|
licenses:
|
298
340
|
- MIT
|
299
|
-
metadata: {}
|
300
341
|
post_install_message:
|
301
342
|
rdoc_options:
|
302
|
-
-
|
343
|
+
- --charset=UTF-8
|
303
344
|
require_paths:
|
304
345
|
- lib
|
305
346
|
required_ruby_version: !ruby/object:Gem::Requirement
|
347
|
+
none: false
|
306
348
|
requirements:
|
307
|
-
- -
|
349
|
+
- - ! '>='
|
308
350
|
- !ruby/object:Gem::Version
|
309
351
|
version: 1.8.7
|
310
352
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
353
|
+
none: false
|
311
354
|
requirements:
|
312
|
-
- -
|
355
|
+
- - ! '>='
|
313
356
|
- !ruby/object:Gem::Version
|
314
357
|
version: '0'
|
315
358
|
requirements: []
|
316
359
|
rubyforge_project: http://www.rubygems.org/gems/ruby-saml
|
317
|
-
rubygems_version:
|
360
|
+
rubygems_version: 1.8.23
|
318
361
|
signing_key:
|
319
|
-
specification_version:
|
362
|
+
specification_version: 3
|
320
363
|
summary: SAML Ruby Tookit
|
321
364
|
test_files:
|
322
365
|
- test/certificates/certificate1
|
@@ -385,15 +428,19 @@ test_files:
|
|
385
428
|
- test/responses/response_unsigned_xml_base64
|
386
429
|
- test/responses/response_with_ampersands.xml
|
387
430
|
- test/responses/response_with_ampersands.xml.base64
|
431
|
+
- test/responses/response_with_ds_namespace_at_the_root.xml.base64
|
388
432
|
- test/responses/response_with_multiple_attribute_values.xml
|
389
433
|
- test/responses/response_with_saml2_namespace.xml.base64
|
390
434
|
- test/responses/response_with_signed_assertion.xml.base64
|
391
435
|
- test/responses/response_with_signed_assertion_2.xml.base64
|
392
436
|
- test/responses/response_with_undefined_recipient.xml.base64
|
393
437
|
- test/responses/response_without_attributes.xml.base64
|
438
|
+
- test/responses/response_without_reference_uri.xml.base64
|
394
439
|
- test/responses/response_wrapped.xml.base64
|
395
440
|
- test/responses/signed_message_encrypted_signed_assertion.xml.base64
|
396
441
|
- test/responses/signed_message_encrypted_unsigned_assertion.xml.base64
|
442
|
+
- test/responses/signed_nameid_in_atts.xml
|
443
|
+
- test/responses/signed_unqual_nameid_in_atts.xml
|
397
444
|
- test/responses/simple_saml_php.xml
|
398
445
|
- test/responses/starfield_response.xml.base64
|
399
446
|
- test/responses/test_sign.xml
|
@@ -405,6 +452,7 @@ test_files:
|
|
405
452
|
- test/responses/unsigned_message_encrypted_signed_assertion.xml.base64
|
406
453
|
- test/responses/unsigned_message_encrypted_unsigned_assertion.xml.base64
|
407
454
|
- test/responses/valid_response.xml.base64
|
455
|
+
- test/responses/valid_response_without_x509certificate.xml.base64
|
408
456
|
- test/saml_message_test.rb
|
409
457
|
- test/settings_test.rb
|
410
458
|
- test/slo_logoutrequest_test.rb
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 381e8f35422cfa0bbb991272a777f7fdfcdd2081
|
4
|
-
data.tar.gz: 0371c2cbd05ee2b482fca1feda05a82162550295
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: a3553e3802bba3fe72375cf5865dfce58a5bf46efa335a43e49f020ee12691bd099ecc3496be389a2556808ad4428bd79d4c4a51171c582df8ac74d66187e2a0
|
7
|
-
data.tar.gz: 473180d499b2ffd2648438ce2c4fd103a8b314ccfa18145cb72215edeecc0864f53dbf016ccd66f6025cdb45aca241df14ca3e9f7ec36731ba4a4004ef0b3a6f
|