ruby-saml 1.10.1 → 1.12.2

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.

Files changed (159) hide show
  1. checksums.yaml +7 -7
  2. data/.travis.yml +21 -20
  3. data/README.md +95 -26
  4. data/changelog.md +40 -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 +70 -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 +72 -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 +161 -383
  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 -587
  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 -329
  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
- ---
2
- SHA256:
3
- data.tar.gz: 86263fd67d7746f38da8cec765cb629d896969ce7c2200fcb4679c41f8eea29b
4
- metadata.gz: 33fa6461088803b5669388641d0ba21a6bb1d5a96e470cd6ae29766b75a541db
5
- SHA512:
6
- data.tar.gz: b51331bec28c256f8affcb416334bb905e16b6defc4c3e86eb487bed1239e23bb27dc526a269d01ff1b5588475631213a14eaab4efb88a34fe2054b0e2c8b09b
7
- metadata.gz: b0ec516728497bf9be7098429beeb370d447b784e5168a517bb0de36e72797d3d730977ba5ed70a5c91c8f3daae89694d3cd9c7323186a0c1b4a8e2f58ba0147
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 25c4115dff650511c702291e7e6e3277a2c50c43b603c4cf68ae1473b3c061b5
4
+ data.tar.gz: 375b631e4059b50e112f4fc5b890e48c000ddae894fdef7cc665b9a58bad5b7a
5
+ SHA512:
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,4 +1,44 @@
1
1
  # RubySaml Changelog
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
+
33
+ ### 1.10.2 (Apr 29, 2019)
34
+
35
+ * Add valid until, accessor
36
+ * Fix Rubygem metadata that requested nokogiri <= 1.5.11
37
+
38
+ ### 1.10.1 (Apr 08, 2019)
39
+
40
+ * Fix ruby 1.8.7 incompatibilities
41
+
2
42
  ### 1.10.0 (Mar 21, 2019)
3
43
  * Add Subject support on AuthNRequest to allow SPs provide info to the IdP about the user to be authenticated
4
44
  * Improves IdpMetadataParser to allow parse multiple IDPSSODescriptors
@@ -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