ruby-saml 1.8.0 → 1.9.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.
- checksums.yaml +4 -4
- data/.travis.yml +10 -4
- data/README.md +3 -1
- data/changelog.md +7 -0
- data/lib/onelogin/ruby-saml/attribute_service.rb +1 -1
- data/lib/onelogin/ruby-saml/logging.rb +4 -1
- data/lib/onelogin/ruby-saml/logoutresponse.rb +7 -7
- data/lib/onelogin/ruby-saml/response.rb +9 -9
- data/lib/onelogin/ruby-saml/saml_message.rb +3 -3
- data/lib/onelogin/ruby-saml/settings.rb +9 -2
- data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +6 -6
- data/lib/onelogin/ruby-saml/utils.rb +13 -9
- data/lib/onelogin/ruby-saml/version.rb +1 -1
- data/lib/xml_security.rb +5 -6
- data/ruby-saml.gemspec +2 -2
- data/test/response_test.rb +34 -1
- data/test/responses/valid_response_with_formatted_x509certificate.xml.base64 +1 -0
- data/test/settings_test.rb +30 -2
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d36c7827c8bb0a1ab808a352ecb85bb925aca401
|
4
|
+
data.tar.gz: e823dc21a31d81901cad0bdcdc2c5f737ed37d42
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d2a444bfe39a2236b37ff979015dd1b7e82f06d06f23abf38251bebdc33b64ca91b76c128811a7636335b00bfa1609ef0a7a450ff99be8613ea6f0d4f2aea22d
|
7
|
+
data.tar.gz: 974a863b07f77aaef63393a23d825a1af3bfd3acc4e5d8ad00902d5efd556cf7d2062dac80e44f06c5a5cbe42154ffe2632351d897f18bcc7210fa0582b24d7e
|
data/.travis.yml
CHANGED
@@ -8,9 +8,11 @@ rvm:
|
|
8
8
|
- 2.2.0
|
9
9
|
- 2.3.0
|
10
10
|
- 2.4.0
|
11
|
+
- 2.5.0
|
11
12
|
- ree
|
12
|
-
- jruby-1.7.
|
13
|
-
- jruby-9.
|
13
|
+
- jruby-1.7.27
|
14
|
+
- jruby-9.1.17.0
|
15
|
+
- jruby-9.2.0.0
|
14
16
|
gemfile:
|
15
17
|
- Gemfile
|
16
18
|
- gemfiles/nokogiri-1.5.gemfile
|
@@ -20,7 +22,11 @@ matrix:
|
|
20
22
|
gemfile: Gemfile
|
21
23
|
- rvm: ree
|
22
24
|
gemfile: Gemfile
|
23
|
-
- rvm: jruby-
|
25
|
+
- rvm: jruby-1.7.27
|
24
26
|
gemfile: gemfiles/nokogiri-1.5.gemfile
|
25
|
-
- rvm: jruby-1.
|
27
|
+
- rvm: jruby-9.1.17.0
|
26
28
|
gemfile: gemfiles/nokogiri-1.5.gemfile
|
29
|
+
- rvm: jruby-9.2.0.0
|
30
|
+
gemfile: gemfiles/nokogiri-1.5.gemfile
|
31
|
+
env:
|
32
|
+
- JRUBY_OPTS="--debug"
|
data/README.md
CHANGED
@@ -121,7 +121,7 @@ Using `Gemfile`
|
|
121
121
|
|
122
122
|
```ruby
|
123
123
|
# latest stable
|
124
|
-
gem 'ruby-saml', '~> 1.
|
124
|
+
gem 'ruby-saml', '~> 1.8.0'
|
125
125
|
|
126
126
|
# or track master for bleeding-edge
|
127
127
|
gem 'ruby-saml', :github => 'onelogin/ruby-saml'
|
@@ -313,6 +313,8 @@ On the ruby-saml toolkit there are different ways to validate the signature of t
|
|
313
313
|
When validating the signature of redirect binding, the fingerprint is useless and the certficate of the IdP is required in order to execute the validation.
|
314
314
|
You can pass the option :relax_signature_validation to SloLogoutrequest and Logoutresponse if want to avoid signature validation if no certificate of the IdP is provided.
|
315
315
|
|
316
|
+
In production also we highly recommend to register on the settings the IdP certificate instead of using the fingerprint method. The fingerprint, is a hash, so at the end is open to a collision attack that can end on a signature validation bypass. Other SAML toolkits deprecated that mechanism, we maintain it for compatibility and also to be used on test environment.
|
317
|
+
|
316
318
|
In some scenarios the IdP uses different certificates for signing/encryption, or is under key rollover phase and more than one certificate is published on IdP metadata.
|
317
319
|
|
318
320
|
In order to handle that the toolkit offers the 'idp_cert_multi' parameter.
|
data/changelog.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# RubySaml Changelog
|
2
2
|
|
3
|
+
### 1.9.0 (Sept 03, 2018)
|
4
|
+
* [#458](https://github.com/onelogin/ruby-saml/pull/458) Remove ruby 2.4+ warnings
|
5
|
+
* Improve JRuby support
|
6
|
+
* [#465](https://github.com/onelogin/ruby-saml/pull/465) Extend Settings initialization with the new keep_security_attributes parameter
|
7
|
+
* Fix wrong message when SessionNotOnOrAfter expired
|
8
|
+
* [#471](https://github.com/onelogin/ruby-saml/pull/471) Allow for `allowed_clock_drift` to be set as a string
|
9
|
+
|
3
10
|
### 1.8.0 (April 23, 2018)
|
4
11
|
* [#437](https://github.com/onelogin/ruby-saml/issues/437) Creating AuthRequests/LogoutRequests/LogoutResponses with nil RelayState should not send empty RelayState URL param
|
5
12
|
* [#454](https://github.com/onelogin/ruby-saml/pull/454) Added Response available options
|
@@ -7,7 +7,10 @@ module OneLogin
|
|
7
7
|
DEFAULT_LOGGER = ::Logger.new(STDOUT)
|
8
8
|
|
9
9
|
def self.logger
|
10
|
-
@logger
|
10
|
+
@logger ||= begin
|
11
|
+
(defined?(::Rails) && Rails.respond_to?(:logger) && Rails.logger) ||
|
12
|
+
DEFAULT_LOGGER
|
13
|
+
end
|
11
14
|
end
|
12
15
|
|
13
16
|
def self.logger=(logger)
|
@@ -24,7 +24,7 @@ module OneLogin
|
|
24
24
|
# Constructs the Logout Response. A Logout Response Object that is an extension of the SamlMessage class.
|
25
25
|
# @param response [String] A UUEncoded logout response from the IdP.
|
26
26
|
# @param settings [OneLogin::RubySaml::Settings|nil] Toolkit settings
|
27
|
-
# @param options [Hash] Extra parameters.
|
27
|
+
# @param options [Hash] Extra parameters.
|
28
28
|
# :matches_request_id It will validate that the logout response matches the ID of the request.
|
29
29
|
# :get_params GET Parameters, including the SAMLResponse
|
30
30
|
# :relax_signature_validation to accept signatures if no idp certificate registered on settings
|
@@ -50,7 +50,7 @@ module OneLogin
|
|
50
50
|
# Checks if the Status has the "Success" code
|
51
51
|
# @return [Boolean] True if the StatusCode is Sucess
|
52
52
|
# @raise [ValidationError] if soft == false and validation fails
|
53
|
-
#
|
53
|
+
#
|
54
54
|
def success?
|
55
55
|
unless status_code == "urn:oasis:names:tc:SAML:2.0:status:Success"
|
56
56
|
return append_error("Bad status code. Expected <urn:oasis:names:tc:SAML:2.0:status:Success>, but was: <#@status_code>")
|
@@ -146,7 +146,7 @@ module OneLogin
|
|
146
146
|
|
147
147
|
# Validates the Logout Response against the specified schema.
|
148
148
|
# @return [Boolean] True if the XML is valid, otherwise False if soft=True
|
149
|
-
# @raise [ValidationError] if soft == false and validation fails
|
149
|
+
# @raise [ValidationError] if soft == false and validation fails
|
150
150
|
#
|
151
151
|
def validate_structure
|
152
152
|
unless valid_saml?(document, soft)
|
@@ -205,7 +205,7 @@ module OneLogin
|
|
205
205
|
# Validates the Signature if it exists and the GET parameters are provided
|
206
206
|
# @return [Boolean] True if not contains a Signature or if the Signature is valid, otherwise False if soft=True
|
207
207
|
# @raise [ValidationError] if soft == false and validation fails
|
208
|
-
#
|
208
|
+
#
|
209
209
|
def validate_signature
|
210
210
|
return true unless !options.nil?
|
211
211
|
return true unless options.has_key? :get_params
|
@@ -240,9 +240,9 @@ module OneLogin
|
|
240
240
|
)
|
241
241
|
else
|
242
242
|
valid = false
|
243
|
-
idp_certs[:signing].each do |
|
243
|
+
idp_certs[:signing].each do |signing_idp_cert|
|
244
244
|
valid = OneLogin::RubySaml::Utils.verify_signature(
|
245
|
-
:cert =>
|
245
|
+
:cert => signing_idp_cert,
|
246
246
|
:sig_alg => options[:get_params]['SigAlg'],
|
247
247
|
:signature => options[:get_params]['Signature'],
|
248
248
|
:query_string => query_string
|
@@ -257,7 +257,7 @@ module OneLogin
|
|
257
257
|
error_msg = "Invalid Signature on Logout Response"
|
258
258
|
return append_error(error_msg)
|
259
259
|
end
|
260
|
-
true
|
260
|
+
true
|
261
261
|
end
|
262
262
|
|
263
263
|
end
|
@@ -171,9 +171,10 @@ module OneLogin
|
|
171
171
|
# identify the subject in an SP rather than email or other less opaque attributes
|
172
172
|
# NameQualifier, if present is prefixed with a "/" to the value
|
173
173
|
else
|
174
|
-
|
175
|
-
|
176
|
-
|
174
|
+
REXML::XPath.match(e,'a:NameID', { "a" => ASSERTION }).collect do |n|
|
175
|
+
base_path = n.attributes['NameQualifier'] ? "#{n.attributes['NameQualifier']}/" : ''
|
176
|
+
"#{base_path}#{Utils.element_text(n)}"
|
177
|
+
end
|
177
178
|
end
|
178
179
|
}
|
179
180
|
|
@@ -221,8 +222,8 @@ module OneLogin
|
|
221
222
|
"/p:Response/p:Status/p:StatusCode/p:StatusCode",
|
222
223
|
{ "p" => PROTOCOL }
|
223
224
|
)
|
224
|
-
statuses = nodes.collect do |
|
225
|
-
|
225
|
+
statuses = nodes.collect do |inner_node|
|
226
|
+
inner_node.attributes["Value"]
|
226
227
|
end
|
227
228
|
extra_code = statuses.join(" | ")
|
228
229
|
if extra_code
|
@@ -288,7 +289,6 @@ module OneLogin
|
|
288
289
|
raise ValidationError.new(error_msg)
|
289
290
|
end
|
290
291
|
|
291
|
-
doc = decrypted_document.nil? ? document : decrypted_document
|
292
292
|
issuer_assertion_nodes = xpath_from_signed_assertion("/a:Issuer")
|
293
293
|
unless issuer_assertion_nodes.size == 1
|
294
294
|
error_msg = "Issuer of the Assertion not found or multiple."
|
@@ -338,7 +338,7 @@ module OneLogin
|
|
338
338
|
# returns the allowed clock drift on timing validation
|
339
339
|
# @return [Integer]
|
340
340
|
def allowed_clock_drift
|
341
|
-
return options[:allowed_clock_drift]
|
341
|
+
return options[:allowed_clock_drift].to_f
|
342
342
|
end
|
343
343
|
|
344
344
|
private
|
@@ -709,7 +709,7 @@ module OneLogin
|
|
709
709
|
# this time validation is relaxed by the allowed_clock_drift value)
|
710
710
|
# If fails, the error is added to the errors array
|
711
711
|
# @param soft [Boolean] soft Enable or Disable the soft mode (In order to raise exceptions when the response is invalid or not)
|
712
|
-
# @return [Boolean] True if the SessionNotOnOrAfter of the
|
712
|
+
# @return [Boolean] True if the SessionNotOnOrAfter of the AuthnStatement is valid, otherwise (when expired) False if soft=True
|
713
713
|
# @raise [ValidationError] if soft == false and validation fails
|
714
714
|
#
|
715
715
|
def validate_session_expiration(soft = true)
|
@@ -717,7 +717,7 @@ module OneLogin
|
|
717
717
|
|
718
718
|
now = Time.now.utc
|
719
719
|
unless (session_expires_at + allowed_clock_drift) > now
|
720
|
-
error_msg = "The attributes have expired, based on the SessionNotOnOrAfter of the
|
720
|
+
error_msg = "The attributes have expired, based on the SessionNotOnOrAfter of the AuthnStatement of this Response"
|
721
721
|
return append_error(error_msg)
|
722
722
|
end
|
723
723
|
|
@@ -62,7 +62,7 @@ module OneLogin
|
|
62
62
|
# @param document [REXML::Document] The message that will be validated
|
63
63
|
# @param soft [Boolean] soft Enable or Disable the soft mode (In order to raise exceptions when the message is invalid or not)
|
64
64
|
# @return [Boolean] True if the XML is valid, otherwise False, if soft=True
|
65
|
-
# @raise [ValidationError] if soft == false and validation fails
|
65
|
+
# @raise [ValidationError] if soft == false and validation fails
|
66
66
|
#
|
67
67
|
def valid_saml?(document, soft = true)
|
68
68
|
begin
|
@@ -74,9 +74,9 @@ module OneLogin
|
|
74
74
|
raise ValidationError.new("XML load failed: #{error.message}")
|
75
75
|
end
|
76
76
|
|
77
|
-
SamlMessage.schema.validate(xml).map do |
|
77
|
+
SamlMessage.schema.validate(xml).map do |schema_error|
|
78
78
|
return false if soft
|
79
|
-
raise ValidationError.new("#{
|
79
|
+
raise ValidationError.new("#{schema_error.message}\n\n#{xml.to_s}")
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
@@ -9,8 +9,15 @@ module OneLogin
|
|
9
9
|
# SAML2 Toolkit Settings
|
10
10
|
#
|
11
11
|
class Settings
|
12
|
-
def initialize(overrides = {})
|
13
|
-
|
12
|
+
def initialize(overrides = {}, keep_security_attributes = false)
|
13
|
+
if keep_security_attributes
|
14
|
+
security_attributes = overrides.delete(:security) || {}
|
15
|
+
config = DEFAULTS.merge(overrides)
|
16
|
+
config[:security] = DEFAULTS[:security].merge(security_attributes)
|
17
|
+
else
|
18
|
+
config = DEFAULTS.merge(overrides)
|
19
|
+
end
|
20
|
+
|
14
21
|
config.each do |k,v|
|
15
22
|
acc = "#{k.to_s}=".to_sym
|
16
23
|
if respond_to? acc
|
@@ -24,9 +24,9 @@ module OneLogin
|
|
24
24
|
|
25
25
|
# Constructs the Logout Request. A Logout Request Object that is an extension of the SamlMessage class.
|
26
26
|
# @param request [String] A UUEncoded Logout Request from the IdP.
|
27
|
-
# @param options [Hash] :settings to provide the OneLogin::RubySaml::Settings object
|
27
|
+
# @param options [Hash] :settings to provide the OneLogin::RubySaml::Settings object
|
28
28
|
# Or :allowed_clock_drift for the logout request validation process to allow a clock drift when checking dates with
|
29
|
-
# Or :relax_signature_validation to accept signatures if no idp certificate registered on settings
|
29
|
+
# Or :relax_signature_validation to accept signatures if no idp certificate registered on settings
|
30
30
|
#
|
31
31
|
# @raise [ArgumentError] If Request is nil
|
32
32
|
#
|
@@ -192,7 +192,7 @@ module OneLogin
|
|
192
192
|
|
193
193
|
# Validates the Logout Request against the specified schema.
|
194
194
|
# @return [Boolean] True if the XML is valid, otherwise False if soft=True
|
195
|
-
# @raise [ValidationError] if soft == false and validation fails
|
195
|
+
# @raise [ValidationError] if soft == false and validation fails
|
196
196
|
#
|
197
197
|
def validate_structure
|
198
198
|
unless valid_saml?(document, soft)
|
@@ -202,7 +202,7 @@ module OneLogin
|
|
202
202
|
true
|
203
203
|
end
|
204
204
|
|
205
|
-
# Validates that the Logout Request provided in the initialization is not empty,
|
205
|
+
# Validates that the Logout Request provided in the initialization is not empty,
|
206
206
|
# @return [Boolean] True if the required info is found, otherwise False if soft=True
|
207
207
|
# @raise [ValidationError] if soft == false and validation fails
|
208
208
|
#
|
@@ -289,9 +289,9 @@ module OneLogin
|
|
289
289
|
)
|
290
290
|
else
|
291
291
|
valid = false
|
292
|
-
idp_certs[:signing].each do |
|
292
|
+
idp_certs[:signing].each do |signing_idp_cert|
|
293
293
|
valid = OneLogin::RubySaml::Utils.verify_signature(
|
294
|
-
:cert =>
|
294
|
+
:cert => signing_idp_cert,
|
295
295
|
:sig_alg => options[:get_params]['SigAlg'],
|
296
296
|
:signature => options[:get_params]['Signature'],
|
297
297
|
:query_string => query_string
|
@@ -32,7 +32,9 @@ module OneLogin
|
|
32
32
|
formatted_cert.join("\n")
|
33
33
|
else
|
34
34
|
cert = cert.gsub(/\-{5}\s?(BEGIN|END) CERTIFICATE\s?\-{5}/, "")
|
35
|
-
cert = cert.gsub(
|
35
|
+
cert = cert.gsub(/\r/, "")
|
36
|
+
cert = cert.gsub(/\n/, "")
|
37
|
+
cert = cert.gsub(/\s/, "")
|
36
38
|
cert = cert.scan(/.{1,64}/)
|
37
39
|
cert = cert.join("\n")
|
38
40
|
"-----BEGIN CERTIFICATE-----\n#{cert}\n-----END CERTIFICATE-----"
|
@@ -51,7 +53,9 @@ module OneLogin
|
|
51
53
|
# is this an rsa key?
|
52
54
|
rsa_key = key.match("RSA PRIVATE KEY")
|
53
55
|
key = key.gsub(/\-{5}\s?(BEGIN|END)( RSA)? PRIVATE KEY\s?\-{5}/, "")
|
54
|
-
key = key.gsub(
|
56
|
+
key = key.gsub(/\n/, "")
|
57
|
+
key = key.gsub(/\r/, "")
|
58
|
+
key = key.gsub(/\s/, "")
|
55
59
|
key = key.scan(/.{1,64}/)
|
56
60
|
key = key.join("\n")
|
57
61
|
key_label = rsa_key ? "RSA PRIVATE KEY" : "PRIVATE KEY"
|
@@ -98,7 +102,7 @@ module OneLogin
|
|
98
102
|
# @param rawparams [Hash] Raw GET Parameters
|
99
103
|
# @param params [Hash] GET Parameters
|
100
104
|
# @return [Hash] New raw parameters
|
101
|
-
#
|
105
|
+
#
|
102
106
|
def self.prepare_raw_get_params(rawparams, params)
|
103
107
|
rawparams ||= {}
|
104
108
|
|
@@ -107,7 +111,7 @@ module OneLogin
|
|
107
111
|
end
|
108
112
|
if rawparams['SAMLResponse'].nil? && !params['SAMLResponse'].nil?
|
109
113
|
rawparams['SAMLResponse'] = CGI.escape(params['SAMLResponse'])
|
110
|
-
end
|
114
|
+
end
|
111
115
|
if rawparams['RelayState'].nil? && !params['RelayState'].nil?
|
112
116
|
rawparams['RelayState'] = CGI.escape(params['RelayState'])
|
113
117
|
end
|
@@ -136,16 +140,16 @@ module OneLogin
|
|
136
140
|
# @param status_code [String] StatusCode value
|
137
141
|
# @param status_message [Strig] StatusMessage value
|
138
142
|
# @return [String] The status error message
|
139
|
-
def self.status_error_msg(error_msg,
|
140
|
-
unless
|
141
|
-
if
|
142
|
-
status_codes =
|
143
|
+
def self.status_error_msg(error_msg, raw_status_code = nil, status_message = nil)
|
144
|
+
unless raw_status_code.nil?
|
145
|
+
if raw_status_code.include? "|"
|
146
|
+
status_codes = raw_status_code.split(' | ')
|
143
147
|
values = status_codes.collect do |status_code|
|
144
148
|
status_code.split(':').last
|
145
149
|
end
|
146
150
|
printable_code = values.join(" => ")
|
147
151
|
else
|
148
|
-
printable_code =
|
152
|
+
printable_code = raw_status_code.split(':').last
|
149
153
|
end
|
150
154
|
error_msg << ', was ' + printable_code
|
151
155
|
end
|
data/lib/xml_security.rb
CHANGED
@@ -91,7 +91,7 @@ module XMLSecurity
|
|
91
91
|
ENVELOPED_SIG = "http://www.w3.org/2000/09/xmldsig#enveloped-signature"
|
92
92
|
INC_PREFIX_LIST = "#default samlp saml ds xs xsi md"
|
93
93
|
|
94
|
-
|
94
|
+
attr_writer :uuid
|
95
95
|
|
96
96
|
def uuid
|
97
97
|
@uuid ||= begin
|
@@ -187,7 +187,7 @@ module XMLSecurity
|
|
187
187
|
class SignedDocument < BaseDocument
|
188
188
|
include OneLogin::RubySaml::ErrorHandling
|
189
189
|
|
190
|
-
|
190
|
+
attr_writer :signed_element_id
|
191
191
|
|
192
192
|
def initialize(response, errors = [])
|
193
193
|
super(response)
|
@@ -211,7 +211,7 @@ module XMLSecurity
|
|
211
211
|
cert_text = Base64.decode64(base64_cert)
|
212
212
|
begin
|
213
213
|
cert = OpenSSL::X509::Certificate.new(cert_text)
|
214
|
-
rescue OpenSSL::X509::CertificateError =>
|
214
|
+
rescue OpenSSL::X509::CertificateError => _e
|
215
215
|
return append_error("Certificate Error", soft)
|
216
216
|
end
|
217
217
|
|
@@ -254,7 +254,7 @@ module XMLSecurity
|
|
254
254
|
cert_text = Base64.decode64(base64_cert)
|
255
255
|
begin
|
256
256
|
cert = OpenSSL::X509::Certificate.new(cert_text)
|
257
|
-
rescue OpenSSL::X509::CertificateError =>
|
257
|
+
rescue OpenSSL::X509::CertificateError => _e
|
258
258
|
return append_error("Certificate Error", soft)
|
259
259
|
end
|
260
260
|
|
@@ -318,10 +318,9 @@ module XMLSecurity
|
|
318
318
|
|
319
319
|
# check digests
|
320
320
|
ref = REXML::XPath.first(sig_element, "//ds:Reference", {"ds"=>DSIG})
|
321
|
-
uri = ref.attributes.get_attribute("URI").value
|
322
321
|
|
323
322
|
hashed_element = document.at_xpath("//*[@ID=$id]", nil, { 'id' => extract_signed_element_id })
|
324
|
-
|
323
|
+
|
325
324
|
canon_algorithm = canon_algorithm REXML::XPath.first(
|
326
325
|
ref,
|
327
326
|
'//ds:CanonicalizationMethod',
|
data/ruby-saml.gemspec
CHANGED
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
|
|
30
30
|
# have liked to constrain Ruby 1.8.7 to install only the 1.5.x versions.
|
31
31
|
if defined?(JRUBY_VERSION)
|
32
32
|
s.add_runtime_dependency('nokogiri', '>= 1.6.0')
|
33
|
-
s.add_runtime_dependency('jruby-openssl', '>= 0.9.8')
|
33
|
+
s.add_runtime_dependency('jruby-openssl', '>= 0.9.8') if JRUBY_VERSION < '9.2.0.0'
|
34
34
|
elsif RUBY_VERSION < '1.9'
|
35
35
|
s.add_runtime_dependency('uuid')
|
36
36
|
s.add_runtime_dependency('nokogiri', '<= 1.5.11')
|
@@ -44,7 +44,7 @@ Gem::Specification.new do |s|
|
|
44
44
|
s.add_development_dependency('mocha', '~> 0.14')
|
45
45
|
s.add_development_dependency('rake', '~> 10')
|
46
46
|
s.add_development_dependency('shoulda', '~> 2.11')
|
47
|
-
s.add_development_dependency('simplecov'
|
47
|
+
s.add_development_dependency('simplecov')
|
48
48
|
s.add_development_dependency('systemu', '~> 2')
|
49
49
|
s.add_development_dependency('timecop', '<= 0.6.0')
|
50
50
|
|
data/test/response_test.rb
CHANGED
@@ -627,6 +627,21 @@ class RubySamlTest < Minitest::Test
|
|
627
627
|
end
|
628
628
|
end
|
629
629
|
|
630
|
+
describe "validate_formatted_x509_certificate" do
|
631
|
+
let(:response_with_formatted_x509certificate) {
|
632
|
+
OneLogin::RubySaml::Response.new(read_response("valid_response_with_formatted_x509certificate.xml.base64"), {
|
633
|
+
:skip_conditions => true,
|
634
|
+
:skip_subject_confirmation => true })
|
635
|
+
}
|
636
|
+
|
637
|
+
it "be able to parse the response wihout errors" do
|
638
|
+
response_with_formatted_x509certificate.settings = settings
|
639
|
+
response_with_formatted_x509certificate.settings.idp_cert = ruby_saml_cert_text
|
640
|
+
assert response_with_formatted_x509certificate.is_valid?
|
641
|
+
assert_empty response_with_formatted_x509certificate.errors
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
630
645
|
describe "#validate_in_response_to" do
|
631
646
|
it "return true when the inResponseTo value matches the Request ID" do
|
632
647
|
response = OneLogin::RubySaml::Response.new(response_document_valid_signed, :settings => settings, :matches_request_id => "_fc4a34b0-7efb-012e-caae-782bcb13bb38")
|
@@ -802,7 +817,7 @@ class RubySamlTest < Minitest::Test
|
|
802
817
|
it "return false when the session has expired" do
|
803
818
|
response.settings = settings
|
804
819
|
assert !response.send(:validate_session_expiration)
|
805
|
-
assert_includes response.errors, "The attributes have expired, based on the SessionNotOnOrAfter of the
|
820
|
+
assert_includes response.errors, "The attributes have expired, based on the SessionNotOnOrAfter of the AuthnStatement of this Response"
|
806
821
|
end
|
807
822
|
|
808
823
|
it "returns true when the session has expired, but is still within the allowed_clock_drift" do
|
@@ -1057,6 +1072,24 @@ class RubySamlTest < Minitest::Test
|
|
1057
1072
|
)
|
1058
1073
|
assert special_response_with_saml2_namespace.send(:validate_conditions)
|
1059
1074
|
end
|
1075
|
+
|
1076
|
+
Timecop.freeze(Time.parse("2011-06-14T18:21:01Z")) do
|
1077
|
+
settings.soft = true
|
1078
|
+
special_response_with_saml2_namespace = OneLogin::RubySaml::Response.new(
|
1079
|
+
response_document_with_saml2_namespace,
|
1080
|
+
:allowed_clock_drift => '0.515',
|
1081
|
+
:settings => settings
|
1082
|
+
)
|
1083
|
+
assert !special_response_with_saml2_namespace.send(:validate_conditions)
|
1084
|
+
end
|
1085
|
+
|
1086
|
+
Timecop.freeze(Time.parse("2011-06-14T18:21:01Z")) do
|
1087
|
+
special_response_with_saml2_namespace = OneLogin::RubySaml::Response.new(
|
1088
|
+
response_document_with_saml2_namespace,
|
1089
|
+
:allowed_clock_drift => '0.516'
|
1090
|
+
)
|
1091
|
+
assert special_response_with_saml2_namespace.send(:validate_conditions)
|
1092
|
+
end
|
1060
1093
|
end
|
1061
1094
|
end
|
1062
1095
|
|
@@ -0,0 +1 @@
|
|
1
|
+
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
|
data/test/settings_test.rb
CHANGED
@@ -77,6 +77,34 @@ class SettingsTest < Minitest::Test
|
|
77
77
|
assert_equal new_settings.security[:signature_method], XMLSecurity::Document::RSA_SHA1
|
78
78
|
end
|
79
79
|
|
80
|
+
it "overrides only provided security attributes passing a second parameter" do
|
81
|
+
config = {
|
82
|
+
:security => {
|
83
|
+
:metadata_signed => true
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
@default_attributes = OneLogin::RubySaml::Settings::DEFAULTS
|
88
|
+
|
89
|
+
@settings = OneLogin::RubySaml::Settings.new(config, true)
|
90
|
+
assert_equal @settings.security[:metadata_signed], true
|
91
|
+
assert_equal @settings.security[:digest_method], @default_attributes[:security][:digest_method]
|
92
|
+
end
|
93
|
+
|
94
|
+
it "doesn't override only provided security attributes without passing a second parameter" do
|
95
|
+
config = {
|
96
|
+
:security => {
|
97
|
+
:metadata_signed => true
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
@default_attributes = OneLogin::RubySaml::Settings::DEFAULTS
|
102
|
+
|
103
|
+
@settings = OneLogin::RubySaml::Settings.new(config)
|
104
|
+
assert_equal @settings.security[:metadata_signed], true
|
105
|
+
assert_nil @settings.security[:digest_method]
|
106
|
+
end
|
107
|
+
|
80
108
|
describe "#single_logout_service_url" do
|
81
109
|
it "when single_logout_service_url is nil but assertion_consumer_logout_service_url returns its value" do
|
82
110
|
@settings.single_logout_service_url = nil
|
@@ -93,7 +121,7 @@ class SettingsTest < Minitest::Test
|
|
93
121
|
|
94
122
|
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", @settings.single_logout_service_binding
|
95
123
|
end
|
96
|
-
end
|
124
|
+
end
|
97
125
|
|
98
126
|
describe "#get_idp_cert" do
|
99
127
|
it "returns nil when the cert is an empty string" do
|
@@ -169,7 +197,7 @@ class SettingsTest < Minitest::Test
|
|
169
197
|
|
170
198
|
assert @settings.get_idp_cert_multi.kind_of? Hash
|
171
199
|
assert @settings.get_idp_cert_multi[:signing].kind_of? Array
|
172
|
-
assert @settings.get_idp_cert_multi[:encryption].kind_of? Array
|
200
|
+
assert @settings.get_idp_cert_multi[:encryption].kind_of? Array
|
173
201
|
assert @settings.get_idp_cert_multi[:signing][0].kind_of? OpenSSL::X509::Certificate
|
174
202
|
assert @settings.get_idp_cert_multi[:encryption][0].kind_of? OpenSSL::X509::Certificate
|
175
203
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-saml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- OneLogin LLC
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -84,16 +84,16 @@ dependencies:
|
|
84
84
|
name: simplecov
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0
|
89
|
+
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0
|
96
|
+
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: systemu
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -313,6 +313,7 @@ files:
|
|
313
313
|
- test/responses/unsigned_message_encrypted_signed_assertion.xml.base64
|
314
314
|
- test/responses/unsigned_message_encrypted_unsigned_assertion.xml.base64
|
315
315
|
- test/responses/valid_response.xml.base64
|
316
|
+
- test/responses/valid_response_with_formatted_x509certificate.xml.base64
|
316
317
|
- test/responses/valid_response_without_x509certificate.xml.base64
|
317
318
|
- test/saml_message_test.rb
|
318
319
|
- test/settings_test.rb
|
@@ -473,6 +474,7 @@ test_files:
|
|
473
474
|
- test/responses/unsigned_message_encrypted_signed_assertion.xml.base64
|
474
475
|
- test/responses/unsigned_message_encrypted_unsigned_assertion.xml.base64
|
475
476
|
- test/responses/valid_response.xml.base64
|
477
|
+
- test/responses/valid_response_with_formatted_x509certificate.xml.base64
|
476
478
|
- test/responses/valid_response_without_x509certificate.xml.base64
|
477
479
|
- test/saml_message_test.rb
|
478
480
|
- test/settings_test.rb
|