ruby-saml 1.10.0 → 1.12.1

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.
Files changed (159) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +28 -14
  3. data/README.md +96 -26
  4. data/changelog.md +37 -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 +71 -22
  8. data/lib/onelogin/ruby-saml/logging.rb +3 -3
  9. data/lib/onelogin/ruby-saml/logoutrequest.rb +9 -3
  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 +68 -22
  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 +29 -16
  18. data/lib/onelogin/ruby-saml/utils.rb +74 -1
  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 -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 -1619
  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
1
  ---
2
- SHA1:
3
- metadata.gz: 8c5ca7da83f66d1548ef03b3ffe920eea1a07eff
4
- data.tar.gz: f27e46ad0136bb5325d55189f30bc8dac861b5d6
2
+ SHA256:
3
+ metadata.gz: 3ac80594648fe4830b965c65366f8bb261a4edfe148c9e929f352b39a1b3428f
4
+ data.tar.gz: b6379aa66a89f2074f434e8c97163022d533e1cdc30c20555135c2e4c82353b4
5
5
  SHA512:
6
- metadata.gz: 49ac1e001e3b676f080d5ca0d5955c18034cd6a7d7371c99840fece91cb5ac55ce2bd68abfb2ae901f9a192589c997db1e77b6050d9569b66b0aa7311c2875f3
7
- data.tar.gz: b6a30ef8efe897fcf8e69eb638b1214077cfd5027f83ab438164b3436d7396a7a4ee1a89f04f055e96d57c0b589e437c48ef5fd658ac2a136560b6b8620fa040
6
+ metadata.gz: b1a380101d7684431209f4e8cc2704c8118621465c3b0a8efc623d573377e14706a4368eae6ea9ef1666da4c36e5e6a61ccae845d9f87e1bab98fbf2cd626ad6
7
+ data.tar.gz: e251b75351483f04d21bc4228af9752cab4d0cc4568952835960363671c28f9e38e62f9b727bde5d62b3a39e095593041e1e7dea9d93084fe6a87aef45a0f8ab
data/.travis.yml CHANGED
@@ -1,18 +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
- - 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
13
13
  - jruby-1.7.27
14
14
  - jruby-9.1.17.0
15
- - jruby-9.2.0.0
15
+ - jruby-9.2.13.0
16
16
  gemfile:
17
17
  - Gemfile
18
18
  - gemfiles/nokogiri-1.5.gemfile
@@ -20,15 +20,29 @@ before_install:
20
20
  - gem update bundler
21
21
  matrix:
22
22
  exclude:
23
- - rvm: 1.8.7
24
- gemfile: Gemfile
25
- - rvm: ree
26
- gemfile: Gemfile
27
23
  - rvm: jruby-1.7.27
28
24
  gemfile: gemfiles/nokogiri-1.5.gemfile
29
25
  - rvm: jruby-9.1.17.0
30
26
  gemfile: gemfiles/nokogiri-1.5.gemfile
31
- - rvm: jruby-9.2.0.0
27
+ - rvm: jruby-9.2.13.0
28
+ gemfile: gemfiles/nokogiri-1.5.gemfile
29
+ - rvm: 2.1.5
30
+ gemfile: gemfiles/nokogiri-1.5.gemfile
31
+ - rvm: 2.1.10
32
+ gemfile: gemfiles/nokogiri-1.5.gemfile
33
+ - rvm: 2.2.10
34
+ gemfile: gemfiles/nokogiri-1.5.gemfile
35
+ - rvm: 2.3.8
36
+ gemfile: gemfiles/nokogiri-1.5.gemfile
37
+ - rvm: 2.4.6
38
+ gemfile: gemfiles/nokogiri-1.5.gemfile
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
32
46
  gemfile: gemfiles/nokogiri-1.5.gemfile
33
47
  env:
34
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
@@ -106,9 +122,13 @@ We created a demo project for Rails4 that uses the latest version of this librar
106
122
  * 2.3.x
107
123
  * 2.4.x
108
124
  * 2.5.x
109
- * JRuby 1.7.19
110
- * JRuby 9.0.0.0
111
- * JRuby 9.2.0.0
125
+ * 2.6.x
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
112
132
 
113
133
  ## Adding Features, Pull Requests
114
134
  * Fork the repository
@@ -122,6 +142,17 @@ We created a demo project for Rails4 that uses the latest version of this librar
122
142
 
123
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.
124
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
+
125
156
  ## Getting Started
126
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:
127
158
 
@@ -129,7 +160,7 @@ Using `Gemfile`
129
160
 
130
161
  ```ruby
131
162
  # latest stable
132
- gem 'ruby-saml', '~> 1.9.0'
163
+ gem 'ruby-saml', '~> 1.11.0'
133
164
 
134
165
  # or track master for bleeding-edge
135
166
  gem 'ruby-saml', :github => 'onelogin/ruby-saml'
@@ -216,6 +247,7 @@ def consume
216
247
  session[:attributes] = response.attributes
217
248
  else
218
249
  authorize_failure # This method shows an error message
250
+ # List of errors is available in response.errors array
219
251
  end
220
252
  end
221
253
  ```
@@ -237,10 +269,10 @@ def saml_settings
237
269
  settings = OneLogin::RubySaml::Settings.new
238
270
 
239
271
  settings.assertion_consumer_service_url = "http://#{request.host}/saml/consume"
240
- settings.issuer = "http://#{request.host}/saml/metadata"
272
+ settings.sp_entity_id = "http://#{request.host}/saml/metadata"
241
273
  settings.idp_entity_id = "https://app.onelogin.com/saml/metadata/#{OneLoginAppId}"
242
- settings.idp_sso_target_url = "https://app.onelogin.com/trust/saml2/http-post/sso/#{OneLoginAppId}"
243
- 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}"
244
276
  settings.idp_cert_fingerprint = OneLoginAppCertFingerPrint
245
277
  settings.idp_cert_fingerprint_algorithm = "http://www.w3.org/2000/09/xmldsig#sha1"
246
278
  settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
@@ -261,6 +293,8 @@ def saml_settings
261
293
  end
262
294
  ```
263
295
 
296
+ The use of settings.issuer is deprecated in favour of settings.sp_entity_id since version 1.11.0
297
+
264
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:
265
299
 
266
300
  ```ruby
@@ -268,6 +302,7 @@ response = OneLogin::RubySaml::Response.new(params[:SAMLResponse], {skip_authnst
268
302
  response = OneLogin::RubySaml::Response.new(params[:SAMLResponse], {skip_conditions: true}) # skips conditions
269
303
  response = OneLogin::RubySaml::Response.new(params[:SAMLResponse], {skip_subject_confirmation: true}) # skips subject confirmation
270
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
271
306
  ```
272
307
 
273
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:
@@ -291,6 +326,7 @@ class SamlController < ApplicationController
291
326
  session[:attributes] = response.attributes
292
327
  else
293
328
  authorize_failure # This method shows an error message
329
+ # List of errors is available in response.errors array
294
330
  end
295
331
  end
296
332
 
@@ -300,8 +336,8 @@ class SamlController < ApplicationController
300
336
  settings = OneLogin::RubySaml::Settings.new
301
337
 
302
338
  settings.assertion_consumer_service_url = "http://#{request.host}/saml/consume"
303
- settings.issuer = "http://#{request.host}/saml/metadata"
304
- 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}"
305
341
  settings.idp_cert_fingerprint = OneLoginAppCertFingerPrint
306
342
  settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
307
343
 
@@ -363,7 +399,7 @@ def saml_settings
363
399
  settings = idp_metadata_parser.parse_remote("https://example.com/auth/saml2/idp/metadata")
364
400
 
365
401
  settings.assertion_consumer_service_url = "http://#{request.host}/saml/consume"
366
- settings.issuer = "http://#{request.host}/saml/metadata"
402
+ settings.sp_entity_id = "http://#{request.host}/saml/metadata"
367
403
  settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
368
404
  # Optional for most SAML IdPs
369
405
  settings.authn_context = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
@@ -374,11 +410,11 @@ end
374
410
  The following attributes are set:
375
411
  * idp_entity_id
376
412
  * name_identifier_format
377
- * idp_sso_target_url
378
- * idp_slo_target_url
413
+ * idp_sso_service_url
414
+ * idp_slo_service_url
379
415
  * idp_attribute_names
380
- * idp_cert
381
- * idp_cert_fingerprint
416
+ * idp_cert
417
+ * idp_cert_fingerprint
382
418
  * idp_cert_multi
383
419
 
384
420
  ### Retrieve one Entity Descriptor when many exist in Metadata
@@ -441,6 +477,9 @@ Imagine this `saml:AttributeStatement`
441
477
  <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
442
478
  <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="1"/>
443
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>
444
483
  </saml:AttributeStatement>
445
484
  ```
446
485
 
@@ -451,7 +490,8 @@ pp(response.attributes) # is an OneLogin::RubySaml::Attributes object
451
490
  "another_value"=>["value1", "value2"],
452
491
  "role"=>["role1", "role2", "role3"],
453
492
  "attribute_with_nil_value"=>[nil],
454
- "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"]}>
455
495
 
456
496
  # Active single_value_compatibility
457
497
  OneLogin::RubySaml::Attributes.single_value_compatibility = true
@@ -468,6 +508,9 @@ pp(response.attributes.single(:role))
468
508
  pp(response.attributes.multi(:role))
469
509
  # => ["role1", "role2", "role3"]
470
510
 
511
+ pp(response.attributes.fetch(:role))
512
+ # => "role1"
513
+
471
514
  pp(response.attributes[:attribute_with_nil_value])
472
515
  # => nil
473
516
 
@@ -483,6 +526,9 @@ pp(response.attributes.single(:not_exists))
483
526
  pp(response.attributes.multi(:not_exists))
484
527
  # => nil
485
528
 
529
+ pp(response.attributes.fetch(/givenname/))
530
+ # => "usersName"
531
+
486
532
  # Deactive single_value_compatibility
487
533
  OneLogin::RubySaml::Attributes.single_value_compatibility = false
488
534
 
@@ -498,6 +544,9 @@ pp(response.attributes.single(:role))
498
544
  pp(response.attributes.multi(:role))
499
545
  # => ["role1", "role2", "role3"]
500
546
 
547
+ pp(response.attributes.fetch(:role))
548
+ # => ["role1", "role2", "role3"]
549
+
501
550
  pp(response.attributes[:attribute_with_nil_value])
502
551
  # => [nil]
503
552
 
@@ -512,12 +561,15 @@ pp(response.attributes.single(:not_exists))
512
561
 
513
562
  pp(response.attributes.multi(:not_exists))
514
563
  # => nil
564
+
565
+ pp(response.attributes.fetch(/givenname/))
566
+ # => ["usersName"]
515
567
  ```
516
568
 
517
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').
518
570
  To add a `saml:AuthnContextDeclRef`, define `settings.authn_context_decl_ref`.
519
571
 
520
- 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
521
573
  building the authrequest object.
522
574
 
523
575
 
@@ -547,6 +599,8 @@ The settings related to sign are stored in the `security` attribute of the setti
547
599
  # Embeded signature or HTTP GET parameter signature
548
600
  # Note that metadata signature is always embedded regardless of this value.
549
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
550
604
  ```
551
605
 
552
606
  Notice that the RelayState parameter is used when creating the Signature on the HTTP-Redirect Binding.
@@ -554,7 +608,7 @@ Remember to provide it to the Signature builder if you are sending a `GET RelayS
554
608
  signature validation process will fail at the Identity Provider.
555
609
 
556
610
  The Service Provider will sign the request/responses with its private key.
557
- 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
558
612
  Service Provider.
559
613
 
560
614
  Notice that this toolkit uses 'settings.certificate' and 'settings.private_key' for the sign and decrypt processes.
@@ -595,21 +649,27 @@ def sp_logout_request
595
649
  # LogoutRequest accepts plain browser requests w/o paramters
596
650
  settings = saml_settings
597
651
 
598
- if settings.idp_slo_target_url.nil?
652
+ if settings.idp_slo_service_url.nil?
599
653
  logger.info "SLO IdP Endpoint not found in settings, executing then a normal logout'"
600
654
  delete_session
601
655
  else
602
656
 
603
- # Since we created a new SAML request, save the transaction_id
604
- # to compare it with the response we get back
605
657
  logout_request = OneLogin::RubySaml::Logoutrequest.new()
606
- session[:transaction_id] = logout_request.uuid
607
- 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}'"
608
659
 
609
660
  if settings.name_identifier_value.nil?
610
661
  settings.name_identifier_value = session[:userid]
611
662
  end
612
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
+
613
673
  relayState = url_for controller: 'saml', action: 'index'
614
674
  redirect_to(logout_request.create(settings, :RelayState => relayState))
615
675
  end
@@ -637,7 +697,7 @@ def process_logout_response
637
697
  logger.error "The SAML Logout Response is invalid"
638
698
  else
639
699
  # Actually log out this session
640
- logger.info "Delete session for '#{session[:userid]}'"
700
+ logger.info "SLO completed for '#{session[:logged_out_user]}'"
641
701
  delete_session
642
702
  end
643
703
  end
@@ -646,6 +706,8 @@ end
646
706
  def delete_session
647
707
  session[:userid] = nil
648
708
  session[:attributes] = nil
709
+ session[:transaction_id] = nil
710
+ session[:logged_out_user] = nil
649
711
  end
650
712
  ```
651
713
 
@@ -658,7 +720,7 @@ def idp_logout_request
658
720
  logout_request = OneLogin::RubySaml::SloLogoutrequest.new(params[:SAMLRequest])
659
721
  if !logout_request.is_valid?
660
722
  logger.error "IdP initiated LogoutRequest was not valid!"
661
- render :inline => logger.error
723
+ return render :inline => logger.error
662
724
  end
663
725
  logger.info "IdP initiated Logout for #{logout_request.name_id}"
664
726
 
@@ -713,6 +775,14 @@ class SamlController < ApplicationController
713
775
  end
714
776
  ```
715
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
+ ```
716
786
 
717
787
  ## Clock Drift
718
788
 
data/changelog.md CHANGED
@@ -1,4 +1,41 @@
1
1
  # RubySaml Changelog
2
+
3
+ ### 1.12.1 (Apr 05, 2022)
4
+ * Fix XPath typo incompatible with Rexml 3.2.5
5
+ * Refactor GCM support
6
+
7
+ ### 1.12.0 (Feb 18, 2021)
8
+ * Support AES-128-GCM, AES-192-GCM, and AES-256-GCM encryptions
9
+ * Parse & return SLO ResponseLocation in IDPMetadataParser & Settings
10
+ * Adding idp_sso_service_url and idp_slo_service_url settings
11
+ * [#536](https://github.com/onelogin/ruby-saml/pull/536) Adding feth method to be able retrieve attributes based on regex
12
+ * Reduce size of built gem by excluding the test folder
13
+ * Improve protection on Zlib deflate decompression bomb attack.
14
+ * Add ValidUntil and cacheDuration support on Metadata generator
15
+ * Add support for cacheDuration at the IdpMetadataParser
16
+ * Support customizable statusCode on generated LogoutResponse
17
+ * [#545](https://github.com/onelogin/ruby-saml/pull/545) More specific error messages for signature validation
18
+ * Support Process Transform
19
+ * Raise SettingError if invoking an action with no endpoint defined on the settings
20
+ * Made IdpMetadataParser more extensible for subclasses
21
+ *[#548](https://github.com/onelogin/ruby-saml/pull/548) Add :skip_audience option
22
+ * [#555](https://github.com/onelogin/ruby-saml/pull/555) Define 'soft' variable to prevent exception when doc cert is invalid
23
+ * Improve documentation
24
+
25
+ ### 1.11.0 (Jul 24, 2019)
26
+
27
+ * Deprecate settings.issuer in favor of settings.sp_entity_id
28
+ * Add support for certification expiration
29
+
30
+ ### 1.10.2 (Apr 29, 2019)
31
+
32
+ * Add valid until, accessor
33
+ * Fix Rubygem metadata that requested nokogiri <= 1.5.11
34
+
35
+ ### 1.10.1 (Apr 08, 2019)
36
+
37
+ * Fix ruby 1.8.7 incompatibilities
38
+
2
39
  ### 1.10.0 (Mar 21, 2019)
3
40
  * Add Subject support on AuthNRequest to allow SPs provide info to the IdP about the user to be authenticated
4
41
  * 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