ruby-saml 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ruby-saml might be problematic. Click here for more details.
- 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
|