ruby-saml 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ruby-saml might be problematic. Click here for more details.
- data/.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 [![Build Status](https://secure.travis-ci.org/onelogin/ruby-saml.png)](http://travis-ci.org/onelogin/ruby-saml)
|
1
|
+
# Ruby SAML [![Build Status](https://secure.travis-ci.org/onelogin/ruby-saml.png)](http://travis-ci.org/onelogin/ruby-saml) [![Coverage Status](https://coveralls.io/repos/onelogin/ruby-saml/badge.svg?branch=master%0A)](https://coveralls.io/r/onelogin/ruby-saml?branch=master%0A) [![Gem Version](https://badge.fury.io/rb/ruby-saml.svg)](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
|