ruby-saml 1.10.2 → 1.12.2

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.

Files changed (159) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +21 -20
  3. data/README.md +95 -26
  4. data/changelog.md +30 -0
  5. data/lib/onelogin/ruby-saml/attributes.rb +24 -1
  6. data/lib/onelogin/ruby-saml/authrequest.rb +11 -6
  7. data/lib/onelogin/ruby-saml/idp_metadata_parser.rb +62 -24
  8. data/lib/onelogin/ruby-saml/logging.rb +3 -3
  9. data/lib/onelogin/ruby-saml/logoutrequest.rb +11 -5
  10. data/lib/onelogin/ruby-saml/logoutresponse.rb +21 -2
  11. data/lib/onelogin/ruby-saml/metadata.rb +11 -3
  12. data/lib/onelogin/ruby-saml/response.rb +64 -23
  13. data/lib/onelogin/ruby-saml/saml_message.rb +6 -0
  14. data/lib/onelogin/ruby-saml/setting_error.rb +6 -0
  15. data/lib/onelogin/ruby-saml/settings.rb +71 -7
  16. data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +20 -1
  17. data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +31 -17
  18. data/lib/onelogin/ruby-saml/utils.rb +69 -0
  19. data/lib/onelogin/ruby-saml/version.rb +1 -1
  20. data/lib/xml_security.rb +34 -6
  21. data/ruby-saml.gemspec +9 -5
  22. metadata +36 -282
  23. data/test/certificates/certificate.der +0 -0
  24. data/test/certificates/certificate1 +0 -12
  25. data/test/certificates/certificate_without_head_foot +0 -1
  26. data/test/certificates/formatted_certificate +0 -14
  27. data/test/certificates/formatted_chained_certificate +0 -42
  28. data/test/certificates/formatted_private_key +0 -12
  29. data/test/certificates/formatted_rsa_private_key +0 -12
  30. data/test/certificates/invalid_certificate1 +0 -1
  31. data/test/certificates/invalid_certificate2 +0 -1
  32. data/test/certificates/invalid_certificate3 +0 -12
  33. data/test/certificates/invalid_chained_certificate1 +0 -1
  34. data/test/certificates/invalid_private_key1 +0 -1
  35. data/test/certificates/invalid_private_key2 +0 -1
  36. data/test/certificates/invalid_private_key3 +0 -10
  37. data/test/certificates/invalid_rsa_private_key1 +0 -1
  38. data/test/certificates/invalid_rsa_private_key2 +0 -1
  39. data/test/certificates/invalid_rsa_private_key3 +0 -10
  40. data/test/certificates/ruby-saml-2.crt +0 -15
  41. data/test/certificates/ruby-saml.crt +0 -14
  42. data/test/certificates/ruby-saml.key +0 -15
  43. data/test/idp_metadata_parser_test.rb +0 -594
  44. data/test/logging_test.rb +0 -62
  45. data/test/logout_requests/invalid_slo_request.xml +0 -6
  46. data/test/logout_requests/slo_request.xml +0 -4
  47. data/test/logout_requests/slo_request.xml.base64 +0 -1
  48. data/test/logout_requests/slo_request_deflated.xml.base64 +0 -1
  49. data/test/logout_requests/slo_request_with_name_id_format.xml +0 -4
  50. data/test/logout_requests/slo_request_with_session_index.xml +0 -5
  51. data/test/logout_responses/logoutresponse_fixtures.rb +0 -86
  52. data/test/logoutrequest_test.rb +0 -260
  53. data/test/logoutresponse_test.rb +0 -409
  54. data/test/metadata/idp_descriptor.xml +0 -26
  55. data/test/metadata/idp_descriptor_2.xml +0 -56
  56. data/test/metadata/idp_descriptor_3.xml +0 -14
  57. data/test/metadata/idp_descriptor_4.xml +0 -72
  58. data/test/metadata/idp_metadata_different_sign_and_encrypt_cert.xml +0 -72
  59. data/test/metadata/idp_metadata_multi_certs.xml +0 -75
  60. data/test/metadata/idp_metadata_multi_signing_certs.xml +0 -52
  61. data/test/metadata/idp_metadata_same_sign_and_encrypt_cert.xml +0 -71
  62. data/test/metadata/idp_multiple_descriptors.xml +0 -59
  63. data/test/metadata/idp_multiple_descriptors_2.xml +0 -59
  64. data/test/metadata/no_idp_descriptor.xml +0 -21
  65. data/test/metadata_test.rb +0 -331
  66. data/test/request_test.rb +0 -340
  67. data/test/response_test.rb +0 -1620
  68. data/test/responses/adfs_response_sha1.xml +0 -46
  69. data/test/responses/adfs_response_sha256.xml +0 -46
  70. data/test/responses/adfs_response_sha384.xml +0 -46
  71. data/test/responses/adfs_response_sha512.xml +0 -46
  72. data/test/responses/adfs_response_xmlns.xml +0 -45
  73. data/test/responses/attackxee.xml +0 -13
  74. data/test/responses/invalids/duplicated_attributes.xml.base64 +0 -1
  75. data/test/responses/invalids/empty_destination.xml.base64 +0 -1
  76. data/test/responses/invalids/empty_nameid.xml.base64 +0 -1
  77. data/test/responses/invalids/encrypted_new_attack.xml.base64 +0 -1
  78. data/test/responses/invalids/invalid_audience.xml.base64 +0 -1
  79. data/test/responses/invalids/invalid_issuer_assertion.xml.base64 +0 -1
  80. data/test/responses/invalids/invalid_issuer_message.xml.base64 +0 -1
  81. data/test/responses/invalids/invalid_signature_position.xml.base64 +0 -1
  82. data/test/responses/invalids/invalid_subjectconfirmation_inresponse.xml.base64 +0 -1
  83. data/test/responses/invalids/invalid_subjectconfirmation_nb.xml.base64 +0 -1
  84. data/test/responses/invalids/invalid_subjectconfirmation_noa.xml.base64 +0 -1
  85. data/test/responses/invalids/invalid_subjectconfirmation_recipient.xml.base64 +0 -1
  86. data/test/responses/invalids/multiple_assertions.xml.base64 +0 -2
  87. data/test/responses/invalids/multiple_signed.xml.base64 +0 -1
  88. data/test/responses/invalids/no_authnstatement.xml.base64 +0 -1
  89. data/test/responses/invalids/no_conditions.xml.base64 +0 -1
  90. data/test/responses/invalids/no_id.xml.base64 +0 -1
  91. data/test/responses/invalids/no_issuer_assertion.xml.base64 +0 -1
  92. data/test/responses/invalids/no_issuer_response.xml.base64 +0 -1
  93. data/test/responses/invalids/no_nameid.xml.base64 +0 -1
  94. data/test/responses/invalids/no_saml2.xml.base64 +0 -1
  95. data/test/responses/invalids/no_signature.xml.base64 +0 -1
  96. data/test/responses/invalids/no_status.xml.base64 +0 -1
  97. data/test/responses/invalids/no_status_code.xml.base64 +0 -1
  98. data/test/responses/invalids/no_subjectconfirmation_data.xml.base64 +0 -1
  99. data/test/responses/invalids/no_subjectconfirmation_method.xml.base64 +0 -1
  100. data/test/responses/invalids/response_invalid_signed_element.xml.base64 +0 -1
  101. data/test/responses/invalids/response_with_concealed_signed_assertion.xml +0 -51
  102. data/test/responses/invalids/response_with_doubled_signed_assertion.xml +0 -49
  103. data/test/responses/invalids/signature_wrapping_attack.xml.base64 +0 -1
  104. data/test/responses/invalids/status_code_responder.xml.base64 +0 -1
  105. data/test/responses/invalids/status_code_responer_and_msg.xml.base64 +0 -1
  106. data/test/responses/invalids/wrong_spnamequalifier.xml.base64 +0 -1
  107. data/test/responses/no_signature_ns.xml +0 -48
  108. data/test/responses/open_saml_response.xml +0 -56
  109. data/test/responses/response_assertion_wrapped.xml.base64 +0 -93
  110. data/test/responses/response_audience_self_closed_tag.xml.base64 +0 -1
  111. data/test/responses/response_double_status_code.xml.base64 +0 -1
  112. data/test/responses/response_encrypted_attrs.xml.base64 +0 -1
  113. data/test/responses/response_encrypted_nameid.xml.base64 +0 -1
  114. data/test/responses/response_eval.xml +0 -7
  115. data/test/responses/response_no_cert_and_encrypted_attrs.xml +0 -29
  116. data/test/responses/response_node_text_attack.xml.base64 +0 -1
  117. data/test/responses/response_node_text_attack2.xml.base64 +0 -1
  118. data/test/responses/response_node_text_attack3.xml.base64 +0 -1
  119. data/test/responses/response_unsigned_xml_base64 +0 -1
  120. data/test/responses/response_with_ampersands.xml +0 -139
  121. data/test/responses/response_with_ampersands.xml.base64 +0 -93
  122. data/test/responses/response_with_ds_namespace_at_the_root.xml.base64 +0 -1
  123. data/test/responses/response_with_multiple_attribute_statements.xml +0 -72
  124. data/test/responses/response_with_multiple_attribute_values.xml +0 -67
  125. data/test/responses/response_with_retrieval_method.xml +0 -26
  126. data/test/responses/response_with_saml2_namespace.xml.base64 +0 -102
  127. data/test/responses/response_with_signed_assertion.xml.base64 +0 -66
  128. data/test/responses/response_with_signed_assertion_2.xml.base64 +0 -1
  129. data/test/responses/response_with_signed_assertion_3.xml +0 -30
  130. data/test/responses/response_with_signed_message_and_assertion.xml +0 -34
  131. data/test/responses/response_with_undefined_recipient.xml.base64 +0 -1
  132. data/test/responses/response_without_attributes.xml.base64 +0 -79
  133. data/test/responses/response_without_reference_uri.xml.base64 +0 -1
  134. data/test/responses/response_wrapped.xml.base64 +0 -150
  135. data/test/responses/signed_message_encrypted_signed_assertion.xml.base64 +0 -1
  136. data/test/responses/signed_message_encrypted_unsigned_assertion.xml.base64 +0 -1
  137. data/test/responses/signed_nameid_in_atts.xml +0 -47
  138. data/test/responses/signed_unqual_nameid_in_atts.xml +0 -47
  139. data/test/responses/simple_saml_php.xml +0 -71
  140. data/test/responses/starfield_response.xml.base64 +0 -1
  141. data/test/responses/test_sign.xml +0 -43
  142. data/test/responses/unsigned_encrypted_adfs.xml +0 -23
  143. data/test/responses/unsigned_message_aes128_encrypted_signed_assertion.xml.base64 +0 -1
  144. data/test/responses/unsigned_message_aes192_encrypted_signed_assertion.xml.base64 +0 -1
  145. data/test/responses/unsigned_message_aes256_encrypted_signed_assertion.xml.base64 +0 -1
  146. data/test/responses/unsigned_message_des192_encrypted_signed_assertion.xml.base64 +0 -1
  147. data/test/responses/unsigned_message_encrypted_assertion_without_saml_namespace.xml.base64 +0 -1
  148. data/test/responses/unsigned_message_encrypted_signed_assertion.xml.base64 +0 -1
  149. data/test/responses/unsigned_message_encrypted_unsigned_assertion.xml.base64 +0 -1
  150. data/test/responses/valid_response.xml.base64 +0 -1
  151. data/test/responses/valid_response_with_formatted_x509certificate.xml.base64 +0 -1
  152. data/test/responses/valid_response_without_x509certificate.xml.base64 +0 -1
  153. data/test/saml_message_test.rb +0 -56
  154. data/test/settings_test.rb +0 -330
  155. data/test/slo_logoutrequest_test.rb +0 -448
  156. data/test/slo_logoutresponse_test.rb +0 -233
  157. data/test/test_helper.rb +0 -331
  158. data/test/utils_test.rb +0 -259
  159. data/test/xml_security_test.rb +0 -421
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: d41dad289f19495a49ad8be046bfc6c37fdcddb5
4
- data.tar.gz: 461bc5c8000ea0124e59cc5782b997c445591e75
2
+ SHA256:
3
+ metadata.gz: 25c4115dff650511c702291e7e6e3277a2c50c43b603c4cf68ae1473b3c061b5
4
+ data.tar.gz: 375b631e4059b50e112f4fc5b890e48c000ddae894fdef7cc665b9a58bad5b7a
5
5
  SHA512:
6
- metadata.gz: 677d7efd58ec482570901bec9ec0c1ef1e234715f2df3ba8983e9202c6af7d50a7dc9b58e4adf2bcb6ac88ba90190866bd16624308f6ce14205f3047587dc38e
7
- data.tar.gz: 084285a2d56ae772430587a3e748e017c1a50cb6090ed1d4990545c0c5e46a8ecf8c20d5de04b284897e81a35f7da33a2e437686fc181a5ea7085af1121244fd
6
+ metadata.gz: 1207da19dae7cb853704a0dbbd1d55791156d6703a5d3162adaa4d47ea1e645e4806687392db53c8c3e9c0a51b2fbb45772b8202975565f9157d32b707fd56a1
7
+ data.tar.gz: 9a4a9ba94e5ffd0eb24ef08e4a45435dec63333b2cbf1a0f0ecc164ce0569bb8720941c88874d64aef8524bebb5209bd70299e0e5bbdc953b7546aa055da58be
data/.travis.yml CHANGED
@@ -1,19 +1,18 @@
1
- sudo: false
2
1
  language: ruby
3
2
  rvm:
4
- - 1.8.7
5
3
  - 1.9.3
6
4
  - 2.0.0
7
- - 2.1.5
8
- - 2.2.0
9
- - 2.3.0
10
- - 2.4.0
11
- - 2.5.0
12
- - 2.6.0
13
- - ree
5
+ - 2.1.10
6
+ - 2.2.10
7
+ - 2.3.8
8
+ - 2.4.6
9
+ - 2.5.8
10
+ - 2.6.6
11
+ - 2.7.2
12
+ - 3.0.0
14
13
  - jruby-1.7.27
15
14
  - jruby-9.1.17.0
16
- - jruby-9.2.0.0
15
+ - jruby-9.2.13.0
17
16
  gemfile:
18
17
  - Gemfile
19
18
  - gemfiles/nokogiri-1.5.gemfile
@@ -21,27 +20,29 @@ before_install:
21
20
  - gem update bundler
22
21
  matrix:
23
22
  exclude:
24
- - rvm: 1.8.7
25
- gemfile: Gemfile
26
- - rvm: ree
27
- gemfile: Gemfile
28
23
  - rvm: jruby-1.7.27
29
24
  gemfile: gemfiles/nokogiri-1.5.gemfile
30
25
  - rvm: jruby-9.1.17.0
31
26
  gemfile: gemfiles/nokogiri-1.5.gemfile
32
- - rvm: jruby-9.2.0.0
27
+ - rvm: jruby-9.2.13.0
33
28
  gemfile: gemfiles/nokogiri-1.5.gemfile
34
29
  - rvm: 2.1.5
35
30
  gemfile: gemfiles/nokogiri-1.5.gemfile
36
- - rvm: 2.2.0
31
+ - rvm: 2.1.10
37
32
  gemfile: gemfiles/nokogiri-1.5.gemfile
38
- - rvm: 2.3.0
33
+ - rvm: 2.2.10
39
34
  gemfile: gemfiles/nokogiri-1.5.gemfile
40
- - rvm: 2.4.0
35
+ - rvm: 2.3.8
41
36
  gemfile: gemfiles/nokogiri-1.5.gemfile
42
- - rvm: 2.5.0
37
+ - rvm: 2.4.6
43
38
  gemfile: gemfiles/nokogiri-1.5.gemfile
44
- - rvm: 2.6.0
39
+ - rvm: 2.5.8
40
+ gemfile: gemfiles/nokogiri-1.5.gemfile
41
+ - rvm: 2.6.6
42
+ gemfile: gemfiles/nokogiri-1.5.gemfile
43
+ - rvm: 2.7.2
44
+ gemfile: gemfiles/nokogiri-1.5.gemfile
45
+ - rvm: 3.0.0
45
46
  gemfile: gemfiles/nokogiri-1.5.gemfile
46
47
  env:
47
48
  - JRUBY_OPTS="--debug"
data/README.md CHANGED
@@ -1,6 +1,22 @@
1
- # Ruby SAML [![Build Status](https://secure.travis-ci.org/onelogin/ruby-saml.svg)](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)
1
+ # Ruby SAML [![Build Status](https://secure.travis-ci.org/onelogin/ruby-saml.svg)](http://travis-ci.org/onelogin/ruby-saml) [![Coverage Status](https://coveralls.io/repos/onelogin/ruby-saml/badge.svg?branch=master)](https://coveralls.io/r/onelogin/ruby-saml?branch=master)
2
2
 
3
- # Updating from 1.9.0 to 1.10.0
3
+ ## Updating from 1.11.x to 1.12.0
4
+ Version `1.12.0` adds support for gcm algorithm and
5
+ change/adds specific error messages for signature validations
6
+
7
+ `idp_sso_target_url` and `idp_slo_target_url` attributes of the Settings class deprecated in favor of `idp_sso_service_url` and `idp_slo_service_url`.
8
+ In IDPMetadataParser, `parse`, `parse_to_hash` and `parse_to_array` methods now retrieve SSO URL and SLO URL endpoints with
9
+ `idp_sso_service_url` and `idp_slo_service_url` (previously `idp_sso_target_url` and `idp_slo_target_url` respectively).
10
+
11
+ ## Updating from 1.10.x to 1.11.0
12
+ Version `1.11.0` deprecates the use of `settings.issuer` in favour of `settings.sp_entity_id`.
13
+ There are two new security settings: `settings.security[:check_idp_cert_expiration]` and `settings.security[:check_sp_cert_expiration]` (both false by default) that check if the IdP or SP X.509 certificate has expired, respectively.
14
+
15
+ Version `1.10.2` includes the `valid_until` attribute in parsed IdP metadata.
16
+
17
+ Version `1.10.1` improves Ruby 1.8.7 support.
18
+
19
+ ## Updating from 1.9.0 to 1.10.0
4
20
  Version `1.10.0` improves IdpMetadataParser to allow parse multiple IDPSSODescriptor, Add Subject support on AuthNRequest to allow SPs provide info to the IdP about the user to be authenticated and updates the format_cert method to accept certs with /\x0d/
5
21
 
6
22
  ## Updating from 1.8.0 to 1.9.0
@@ -107,9 +123,12 @@ We created a demo project for Rails4 that uses the latest version of this librar
107
123
  * 2.4.x
108
124
  * 2.5.x
109
125
  * 2.6.x
110
- * JRuby 1.7.19
111
- * JRuby 9.0.0.0
112
- * JRuby 9.2.0.0
126
+ * 2.7.x
127
+ * 3.0.x
128
+ * JRuby 1.7.x
129
+ * JRuby 9.0.x
130
+ * JRuby 9.1.x
131
+ * JRuby 9.2.x
113
132
 
114
133
  ## Adding Features, Pull Requests
115
134
  * Fork the repository
@@ -123,6 +142,17 @@ We created a demo project for Rails4 that uses the latest version of this librar
123
142
 
124
143
  If you believe you have discovered a security vulnerability in this gem, please report it at https://www.onelogin.com/security with a description. We follow responsible disclosure guidelines, and will work with you to quickly find a resolution.
125
144
 
145
+ ### Security warning
146
+
147
+ Some tools may incorrectly report ruby-saml is a potential security vulnerability.
148
+ ruby-saml depends on Nokogiri, and it's possible to use Nokogiri in a dangerous way
149
+ (by enabling its DTDLOAD option and disabling its NONET option).
150
+ This dangerous Nokogiri configuration, which is sometimes used by other components,
151
+ can create an XML External Entity (XXE) vulnerability if the XML data is not trusted.
152
+ However, ruby-saml never enables this dangerous Nokogiri configuration;
153
+ ruby-saml never enables DTDLOAD, and it never disables NONET.
154
+
155
+
126
156
  ## Getting Started
127
157
  In order to use the toolkit you will need to install the gem (either manually or using Bundler), and require the library in your Ruby application:
128
158
 
@@ -130,7 +160,7 @@ Using `Gemfile`
130
160
 
131
161
  ```ruby
132
162
  # latest stable
133
- gem 'ruby-saml', '~> 1.9.0'
163
+ gem 'ruby-saml', '~> 1.11.0'
134
164
 
135
165
  # or track master for bleeding-edge
136
166
  gem 'ruby-saml', :github => 'onelogin/ruby-saml'
@@ -217,6 +247,7 @@ def consume
217
247
  session[:attributes] = response.attributes
218
248
  else
219
249
  authorize_failure # This method shows an error message
250
+ # List of errors is available in response.errors array
220
251
  end
221
252
  end
222
253
  ```
@@ -238,10 +269,10 @@ def saml_settings
238
269
  settings = OneLogin::RubySaml::Settings.new
239
270
 
240
271
  settings.assertion_consumer_service_url = "http://#{request.host}/saml/consume"
241
- settings.issuer = "http://#{request.host}/saml/metadata"
272
+ settings.sp_entity_id = "http://#{request.host}/saml/metadata"
242
273
  settings.idp_entity_id = "https://app.onelogin.com/saml/metadata/#{OneLoginAppId}"
243
- settings.idp_sso_target_url = "https://app.onelogin.com/trust/saml2/http-post/sso/#{OneLoginAppId}"
244
- settings.idp_slo_target_url = "https://app.onelogin.com/trust/saml2/http-redirect/slo/#{OneLoginAppId}"
274
+ settings.idp_sso_service_url = "https://app.onelogin.com/trust/saml2/http-post/sso/#{OneLoginAppId}"
275
+ settings.idp_slo_service_url = "https://app.onelogin.com/trust/saml2/http-redirect/slo/#{OneLoginAppId}"
245
276
  settings.idp_cert_fingerprint = OneLoginAppCertFingerPrint
246
277
  settings.idp_cert_fingerprint_algorithm = "http://www.w3.org/2000/09/xmldsig#sha1"
247
278
  settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
@@ -262,6 +293,8 @@ def saml_settings
262
293
  end
263
294
  ```
264
295
 
296
+ The use of settings.issuer is deprecated in favour of settings.sp_entity_id since version 1.11.0
297
+
265
298
  Some assertion validations can be skipped by passing parameters to `OneLogin::RubySaml::Response.new()`. For example, you can skip the `AuthnStatement`, `Conditions`, `Recipient`, or the `SubjectConfirmation` validations by initializing the response with different options:
266
299
 
267
300
  ```ruby
@@ -269,6 +302,7 @@ response = OneLogin::RubySaml::Response.new(params[:SAMLResponse], {skip_authnst
269
302
  response = OneLogin::RubySaml::Response.new(params[:SAMLResponse], {skip_conditions: true}) # skips conditions
270
303
  response = OneLogin::RubySaml::Response.new(params[:SAMLResponse], {skip_subject_confirmation: true}) # skips subject confirmation
271
304
  response = OneLogin::RubySaml::Response.new(params[:SAMLResponse], {skip_recipient_check: true}) # doens't skip subject confirmation, but skips the recipient check which is a sub check of the subject_confirmation check
305
+ response = OneLogin::RubySaml::Response.new(params[:SAMLResponse], {skip_audience: true}) # skips audience check
272
306
  ```
273
307
 
274
308
  All that's left is to wrap everything in a controller and reference it in the initialization and consumption URLs in OneLogin. A full controller example could look like this:
@@ -292,6 +326,7 @@ class SamlController < ApplicationController
292
326
  session[:attributes] = response.attributes
293
327
  else
294
328
  authorize_failure # This method shows an error message
329
+ # List of errors is available in response.errors array
295
330
  end
296
331
  end
297
332
 
@@ -301,8 +336,8 @@ class SamlController < ApplicationController
301
336
  settings = OneLogin::RubySaml::Settings.new
302
337
 
303
338
  settings.assertion_consumer_service_url = "http://#{request.host}/saml/consume"
304
- settings.issuer = "http://#{request.host}/saml/metadata"
305
- settings.idp_sso_target_url = "https://app.onelogin.com/saml/signon/#{OneLoginAppId}"
339
+ settings.sp_entity_id = "http://#{request.host}/saml/metadata"
340
+ settings.idp_sso_service_url = "https://app.onelogin.com/saml/signon/#{OneLoginAppId}"
306
341
  settings.idp_cert_fingerprint = OneLoginAppCertFingerPrint
307
342
  settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
308
343
 
@@ -364,7 +399,7 @@ def saml_settings
364
399
  settings = idp_metadata_parser.parse_remote("https://example.com/auth/saml2/idp/metadata")
365
400
 
366
401
  settings.assertion_consumer_service_url = "http://#{request.host}/saml/consume"
367
- settings.issuer = "http://#{request.host}/saml/metadata"
402
+ settings.sp_entity_id = "http://#{request.host}/saml/metadata"
368
403
  settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
369
404
  # Optional for most SAML IdPs
370
405
  settings.authn_context = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
@@ -375,11 +410,11 @@ end
375
410
  The following attributes are set:
376
411
  * idp_entity_id
377
412
  * name_identifier_format
378
- * idp_sso_target_url
379
- * idp_slo_target_url
413
+ * idp_sso_service_url
414
+ * idp_slo_service_url
380
415
  * idp_attribute_names
381
- * idp_cert
382
- * idp_cert_fingerprint
416
+ * idp_cert
417
+ * idp_cert_fingerprint
383
418
  * idp_cert_multi
384
419
 
385
420
  ### Retrieve one Entity Descriptor when many exist in Metadata
@@ -442,6 +477,9 @@ Imagine this `saml:AttributeStatement`
442
477
  <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
443
478
  <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="1"/>
444
479
  </saml:Attribute>
480
+ <saml:Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname">
481
+ <saml:AttributeValue>usersName</saml:AttributeValue>
482
+ </saml:Attribute>
445
483
  </saml:AttributeStatement>
446
484
  ```
447
485
 
@@ -452,7 +490,8 @@ pp(response.attributes) # is an OneLogin::RubySaml::Attributes object
452
490
  "another_value"=>["value1", "value2"],
453
491
  "role"=>["role1", "role2", "role3"],
454
492
  "attribute_with_nil_value"=>[nil],
455
- "attribute_with_nils_and_empty_strings"=>["", "valuePresent", nil, nil]}>
493
+ "attribute_with_nils_and_empty_strings"=>["", "valuePresent", nil, nil]
494
+ "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"=>["usersName"]}>
456
495
 
457
496
  # Active single_value_compatibility
458
497
  OneLogin::RubySaml::Attributes.single_value_compatibility = true
@@ -469,6 +508,9 @@ pp(response.attributes.single(:role))
469
508
  pp(response.attributes.multi(:role))
470
509
  # => ["role1", "role2", "role3"]
471
510
 
511
+ pp(response.attributes.fetch(:role))
512
+ # => "role1"
513
+
472
514
  pp(response.attributes[:attribute_with_nil_value])
473
515
  # => nil
474
516
 
@@ -484,6 +526,9 @@ pp(response.attributes.single(:not_exists))
484
526
  pp(response.attributes.multi(:not_exists))
485
527
  # => nil
486
528
 
529
+ pp(response.attributes.fetch(/givenname/))
530
+ # => "usersName"
531
+
487
532
  # Deactive single_value_compatibility
488
533
  OneLogin::RubySaml::Attributes.single_value_compatibility = false
489
534
 
@@ -499,6 +544,9 @@ pp(response.attributes.single(:role))
499
544
  pp(response.attributes.multi(:role))
500
545
  # => ["role1", "role2", "role3"]
501
546
 
547
+ pp(response.attributes.fetch(:role))
548
+ # => ["role1", "role2", "role3"]
549
+
502
550
  pp(response.attributes[:attribute_with_nil_value])
503
551
  # => [nil]
504
552
 
@@ -513,12 +561,15 @@ pp(response.attributes.single(:not_exists))
513
561
 
514
562
  pp(response.attributes.multi(:not_exists))
515
563
  # => nil
564
+
565
+ pp(response.attributes.fetch(/givenname/))
566
+ # => ["usersName"]
516
567
  ```
517
568
 
518
569
  The `saml:AuthnContextClassRef` of the AuthNRequest can be provided by `settings.authn_context`; possible values are described at [SAMLAuthnCxt]. The comparison method can be set using `settings.authn_context_comparison` parameter. Possible values include: 'exact', 'better', 'maximum' and 'minimum' (default value is 'exact').
519
570
  To add a `saml:AuthnContextDeclRef`, define `settings.authn_context_decl_ref`.
520
571
 
521
- In a SP-initiaited flow, the SP can indicate to the IdP the subject that should be authenticated. This is done by defining the `settings.name_identifier_value_requested` before
572
+ In a SP-initiated flow, the SP can indicate to the IdP the subject that should be authenticated. This is done by defining the `settings.name_identifier_value_requested` before
522
573
  building the authrequest object.
523
574
 
524
575
 
@@ -548,6 +599,8 @@ The settings related to sign are stored in the `security` attribute of the setti
548
599
  # Embeded signature or HTTP GET parameter signature
549
600
  # Note that metadata signature is always embedded regardless of this value.
550
601
  settings.security[:embed_sign] = false
602
+ settings.security[:check_idp_cert_expiration] = false # Enable or not IdP x509 cert expiration check
603
+ settings.security[:check_sp_cert_expiration] = false # Enable or not SP x509 cert expiration check
551
604
  ```
552
605
 
553
606
  Notice that the RelayState parameter is used when creating the Signature on the HTTP-Redirect Binding.
@@ -555,7 +608,7 @@ Remember to provide it to the Signature builder if you are sending a `GET RelayS
555
608
  signature validation process will fail at the Identity Provider.
556
609
 
557
610
  The Service Provider will sign the request/responses with its private key.
558
- The Identity Provider will validate the sign of the received request/responses with the public x500 cert of the
611
+ The Identity Provider will validate the sign of the received request/responses with the public x509 cert of the
559
612
  Service Provider.
560
613
 
561
614
  Notice that this toolkit uses 'settings.certificate' and 'settings.private_key' for the sign and decrypt processes.
@@ -596,21 +649,27 @@ def sp_logout_request
596
649
  # LogoutRequest accepts plain browser requests w/o paramters
597
650
  settings = saml_settings
598
651
 
599
- if settings.idp_slo_target_url.nil?
652
+ if settings.idp_slo_service_url.nil?
600
653
  logger.info "SLO IdP Endpoint not found in settings, executing then a normal logout'"
601
654
  delete_session
602
655
  else
603
656
 
604
- # Since we created a new SAML request, save the transaction_id
605
- # to compare it with the response we get back
606
657
  logout_request = OneLogin::RubySaml::Logoutrequest.new()
607
- session[:transaction_id] = logout_request.uuid
608
- logger.info "New SP SLO for userid '#{session[:userid]}' transactionid '#{session[:transaction_id]}'"
658
+ logger.info "New SP SLO for userid '#{session[:userid]}' transactionid '#{logout_request.uuid}'"
609
659
 
610
660
  if settings.name_identifier_value.nil?
611
661
  settings.name_identifier_value = session[:userid]
612
662
  end
613
663
 
664
+ # Ensure user is logged out before redirect to IdP, in case anything goes wrong during single logout process (as recommended by saml2int [SDP-SP34])
665
+ logged_user = session[:userid]
666
+ logger.info "Delete session for '#{session[:userid]}'"
667
+ delete_session
668
+
669
+ # Save the transaction_id to compare it with the response we get back
670
+ session[:transaction_id] = logout_request.uuid
671
+ session[:logged_out_user] = logged_user
672
+
614
673
  relayState = url_for controller: 'saml', action: 'index'
615
674
  redirect_to(logout_request.create(settings, :RelayState => relayState))
616
675
  end
@@ -638,7 +697,7 @@ def process_logout_response
638
697
  logger.error "The SAML Logout Response is invalid"
639
698
  else
640
699
  # Actually log out this session
641
- logger.info "Delete session for '#{session[:userid]}'"
700
+ logger.info "SLO completed for '#{session[:logged_out_user]}'"
642
701
  delete_session
643
702
  end
644
703
  end
@@ -647,6 +706,8 @@ end
647
706
  def delete_session
648
707
  session[:userid] = nil
649
708
  session[:attributes] = nil
709
+ session[:transaction_id] = nil
710
+ session[:logged_out_user] = nil
650
711
  end
651
712
  ```
652
713
 
@@ -659,7 +720,7 @@ def idp_logout_request
659
720
  logout_request = OneLogin::RubySaml::SloLogoutrequest.new(params[:SAMLRequest])
660
721
  if !logout_request.is_valid?
661
722
  logger.error "IdP initiated LogoutRequest was not valid!"
662
- render :inline => logger.error
723
+ return render :inline => logger.error
663
724
  end
664
725
  logger.info "IdP initiated Logout for #{logout_request.name_id}"
665
726
 
@@ -714,6 +775,14 @@ class SamlController < ApplicationController
714
775
  end
715
776
  ```
716
777
 
778
+ You can add ValidUntil and CacheDuration to the XML Metadata using instead
779
+ ```ruby
780
+ # Valid until => 2 days from now
781
+ # Cache duration = 604800s = 1 week
782
+ valid_until = Time.now + 172800
783
+ cache_duration = 604800
784
+ meta.generate(settings, false, valid_until, cache_duration)
785
+ ```
717
786
 
718
787
  ## Clock Drift
719
788
 
data/changelog.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # RubySaml Changelog
2
2
 
3
+ ### 1.12.2 (Apr 08, 2022)
4
+ * [575](https://github.com/onelogin/ruby-saml/pull/575) Fix SloLogoutresponse bug on LogoutRequest
5
+
6
+ ### 1.12.1 (Apr 05, 2022)
7
+ * Fix XPath typo incompatible with Rexml 3.2.5
8
+ * Refactor GCM support
9
+
10
+ ### 1.12.0 (Feb 18, 2021)
11
+ * Support AES-128-GCM, AES-192-GCM, and AES-256-GCM encryptions
12
+ * Parse & return SLO ResponseLocation in IDPMetadataParser & Settings
13
+ * Adding idp_sso_service_url and idp_slo_service_url settings
14
+ * [#536](https://github.com/onelogin/ruby-saml/pull/536) Adding feth method to be able retrieve attributes based on regex
15
+ * Reduce size of built gem by excluding the test folder
16
+ * Improve protection on Zlib deflate decompression bomb attack.
17
+ * Add ValidUntil and cacheDuration support on Metadata generator
18
+ * Add support for cacheDuration at the IdpMetadataParser
19
+ * Support customizable statusCode on generated LogoutResponse
20
+ * [#545](https://github.com/onelogin/ruby-saml/pull/545) More specific error messages for signature validation
21
+ * Support Process Transform
22
+ * Raise SettingError if invoking an action with no endpoint defined on the settings
23
+ * Made IdpMetadataParser more extensible for subclasses
24
+ *[#548](https://github.com/onelogin/ruby-saml/pull/548) Add :skip_audience option
25
+ * [#555](https://github.com/onelogin/ruby-saml/pull/555) Define 'soft' variable to prevent exception when doc cert is invalid
26
+ * Improve documentation
27
+
28
+ ### 1.11.0 (Jul 24, 2019)
29
+
30
+ * Deprecate settings.issuer in favor of settings.sp_entity_id
31
+ * Add support for certification expiration
32
+
3
33
  ### 1.10.2 (Apr 29, 2019)
4
34
 
5
35
  * Add valid until, accessor
@@ -79,7 +79,7 @@ module OneLogin
79
79
  self.class.single_value_compatibility ? single(canonize_name(name)) : multi(canonize_name(name))
80
80
  end
81
81
 
82
- # @return [Array] Return all attributes as an array
82
+ # @return [Hash] Return all attributes as a hash
83
83
  #
84
84
  def all
85
85
  attributes
@@ -113,6 +113,29 @@ module OneLogin
113
113
  end
114
114
  end
115
115
 
116
+ # Fetch attribute value using name or regex
117
+ # @param name [String|Regexp] The attribute name
118
+ # @return [String|Array] Depending on the single value compatibility status this returns:
119
+ # - First value if single_value_compatibility = true
120
+ # response.attributes['mail'] # => 'user@example.com'
121
+ # - All values if single_value_compatibility = false
122
+ # response.attributes['mail'] # => ['user@example.com','user@example.net']
123
+ #
124
+ def fetch(name)
125
+ attributes.each_key do |attribute_key|
126
+ if name.is_a?(Regexp)
127
+ if name.respond_to? :match?
128
+ return self[attribute_key] if name.match?(attribute_key)
129
+ else
130
+ return self[attribute_key] if name.match(attribute_key)
131
+ end
132
+ elsif canonize_name(name) == canonize_name(attribute_key)
133
+ return self[attribute_key]
134
+ end
135
+ end
136
+ nil
137
+ end
138
+
116
139
  protected
117
140
 
118
141
  # stringifies all names so both 'email' and :email return the same result
@@ -3,6 +3,7 @@ require "rexml/document"
3
3
  require "onelogin/ruby-saml/logging"
4
4
  require "onelogin/ruby-saml/saml_message"
5
5
  require "onelogin/ruby-saml/utils"
6
+ require "onelogin/ruby-saml/setting_error"
6
7
 
7
8
  # Only supports SAML 2.0
8
9
  module OneLogin
@@ -23,6 +24,10 @@ module OneLogin
23
24
  @uuid = OneLogin::RubySaml::Utils.uuid
24
25
  end
25
26
 
27
+ def request_id
28
+ @uuid
29
+ end
30
+
26
31
  # Creates the AuthNRequest string.
27
32
  # @param settings [OneLogin::RubySaml::Settings|nil] Toolkit settings
28
33
  # @param params [Hash] Some extra parameters to be added in the GET for example the RelayState
@@ -30,14 +35,14 @@ module OneLogin
30
35
  #
31
36
  def create(settings, params = {})
32
37
  params = create_params(settings, params)
33
- params_prefix = (settings.idp_sso_target_url =~ /\?/) ? '&' : '?'
38
+ params_prefix = (settings.idp_sso_service_url =~ /\?/) ? '&' : '?'
34
39
  saml_request = CGI.escape(params.delete("SAMLRequest"))
35
40
  request_params = "#{params_prefix}SAMLRequest=#{saml_request}"
36
41
  params.each_pair do |key, value|
37
42
  request_params << "&#{key.to_s}=#{CGI.escape(value.to_s)}"
38
43
  end
39
- raise "Invalid settings, idp_sso_target_url is not set!" if settings.idp_sso_target_url.nil?
40
- @login_url = settings.idp_sso_target_url + request_params
44
+ raise SettingError.new "Invalid settings, idp_sso_service_url is not set!" if settings.idp_sso_service_url.nil? or settings.idp_sso_service_url.empty?
45
+ @login_url = settings.idp_sso_service_url + request_params
41
46
  end
42
47
 
43
48
  # Creates the Get parameters for the request.
@@ -107,7 +112,7 @@ module OneLogin
107
112
  root.attributes['ID'] = uuid
108
113
  root.attributes['IssueInstant'] = time
109
114
  root.attributes['Version'] = "2.0"
110
- root.attributes['Destination'] = settings.idp_sso_target_url unless settings.idp_sso_target_url.nil?
115
+ root.attributes['Destination'] = settings.idp_sso_service_url unless settings.idp_sso_service_url.nil? or settings.idp_sso_service_url.empty?
111
116
  root.attributes['IsPassive'] = settings.passive unless settings.passive.nil?
112
117
  root.attributes['ProtocolBinding'] = settings.protocol_binding unless settings.protocol_binding.nil?
113
118
  root.attributes["AttributeConsumingServiceIndex"] = settings.attributes_index unless settings.attributes_index.nil?
@@ -117,9 +122,9 @@ module OneLogin
117
122
  if settings.assertion_consumer_service_url != nil
118
123
  root.attributes["AssertionConsumerServiceURL"] = settings.assertion_consumer_service_url
119
124
  end
120
- if settings.issuer != nil
125
+ if settings.sp_entity_id != nil
121
126
  issuer = root.add_element "saml:Issuer"
122
- issuer.text = settings.issuer
127
+ issuer.text = settings.sp_entity_id
123
128
  end
124
129
 
125
130
  if settings.name_identifier_value_requested != nil