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.
- checksums.yaml +5 -5
- data/.travis.yml +28 -14
- data/README.md +96 -26
- data/changelog.md +37 -0
- data/lib/onelogin/ruby-saml/attributes.rb +24 -1
- data/lib/onelogin/ruby-saml/authrequest.rb +11 -6
- data/lib/onelogin/ruby-saml/idp_metadata_parser.rb +71 -22
- data/lib/onelogin/ruby-saml/logging.rb +3 -3
- data/lib/onelogin/ruby-saml/logoutrequest.rb +9 -3
- data/lib/onelogin/ruby-saml/logoutresponse.rb +21 -2
- data/lib/onelogin/ruby-saml/metadata.rb +11 -3
- data/lib/onelogin/ruby-saml/response.rb +68 -22
- data/lib/onelogin/ruby-saml/saml_message.rb +6 -0
- data/lib/onelogin/ruby-saml/setting_error.rb +6 -0
- data/lib/onelogin/ruby-saml/settings.rb +72 -7
- data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +20 -1
- data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +29 -16
- data/lib/onelogin/ruby-saml/utils.rb +74 -1
- data/lib/onelogin/ruby-saml/version.rb +1 -1
- data/lib/xml_security.rb +34 -6
- data/ruby-saml.gemspec +9 -5
- metadata +36 -282
- data/test/certificates/certificate.der +0 -0
- data/test/certificates/certificate1 +0 -12
- data/test/certificates/certificate_without_head_foot +0 -1
- data/test/certificates/formatted_certificate +0 -14
- data/test/certificates/formatted_chained_certificate +0 -42
- data/test/certificates/formatted_private_key +0 -12
- data/test/certificates/formatted_rsa_private_key +0 -12
- data/test/certificates/invalid_certificate1 +0 -1
- data/test/certificates/invalid_certificate2 +0 -1
- data/test/certificates/invalid_certificate3 +0 -12
- data/test/certificates/invalid_chained_certificate1 +0 -1
- data/test/certificates/invalid_private_key1 +0 -1
- data/test/certificates/invalid_private_key2 +0 -1
- data/test/certificates/invalid_private_key3 +0 -10
- data/test/certificates/invalid_rsa_private_key1 +0 -1
- data/test/certificates/invalid_rsa_private_key2 +0 -1
- data/test/certificates/invalid_rsa_private_key3 +0 -10
- data/test/certificates/ruby-saml-2.crt +0 -15
- data/test/certificates/ruby-saml.crt +0 -14
- data/test/certificates/ruby-saml.key +0 -15
- data/test/idp_metadata_parser_test.rb +0 -587
- data/test/logging_test.rb +0 -62
- data/test/logout_requests/invalid_slo_request.xml +0 -6
- data/test/logout_requests/slo_request.xml +0 -4
- data/test/logout_requests/slo_request.xml.base64 +0 -1
- data/test/logout_requests/slo_request_deflated.xml.base64 +0 -1
- data/test/logout_requests/slo_request_with_name_id_format.xml +0 -4
- data/test/logout_requests/slo_request_with_session_index.xml +0 -5
- data/test/logout_responses/logoutresponse_fixtures.rb +0 -86
- data/test/logoutrequest_test.rb +0 -260
- data/test/logoutresponse_test.rb +0 -409
- data/test/metadata/idp_descriptor.xml +0 -26
- data/test/metadata/idp_descriptor_2.xml +0 -56
- data/test/metadata/idp_descriptor_3.xml +0 -14
- data/test/metadata/idp_descriptor_4.xml +0 -72
- data/test/metadata/idp_metadata_different_sign_and_encrypt_cert.xml +0 -72
- data/test/metadata/idp_metadata_multi_certs.xml +0 -75
- data/test/metadata/idp_metadata_multi_signing_certs.xml +0 -52
- data/test/metadata/idp_metadata_same_sign_and_encrypt_cert.xml +0 -71
- data/test/metadata/idp_multiple_descriptors.xml +0 -59
- data/test/metadata/idp_multiple_descriptors_2.xml +0 -59
- data/test/metadata/no_idp_descriptor.xml +0 -21
- data/test/metadata_test.rb +0 -331
- data/test/request_test.rb +0 -340
- data/test/response_test.rb +0 -1619
- data/test/responses/adfs_response_sha1.xml +0 -46
- data/test/responses/adfs_response_sha256.xml +0 -46
- data/test/responses/adfs_response_sha384.xml +0 -46
- data/test/responses/adfs_response_sha512.xml +0 -46
- data/test/responses/adfs_response_xmlns.xml +0 -45
- data/test/responses/attackxee.xml +0 -13
- data/test/responses/invalids/duplicated_attributes.xml.base64 +0 -1
- data/test/responses/invalids/empty_destination.xml.base64 +0 -1
- data/test/responses/invalids/empty_nameid.xml.base64 +0 -1
- data/test/responses/invalids/encrypted_new_attack.xml.base64 +0 -1
- data/test/responses/invalids/invalid_audience.xml.base64 +0 -1
- data/test/responses/invalids/invalid_issuer_assertion.xml.base64 +0 -1
- data/test/responses/invalids/invalid_issuer_message.xml.base64 +0 -1
- data/test/responses/invalids/invalid_signature_position.xml.base64 +0 -1
- data/test/responses/invalids/invalid_subjectconfirmation_inresponse.xml.base64 +0 -1
- data/test/responses/invalids/invalid_subjectconfirmation_nb.xml.base64 +0 -1
- data/test/responses/invalids/invalid_subjectconfirmation_noa.xml.base64 +0 -1
- data/test/responses/invalids/invalid_subjectconfirmation_recipient.xml.base64 +0 -1
- data/test/responses/invalids/multiple_assertions.xml.base64 +0 -2
- data/test/responses/invalids/multiple_signed.xml.base64 +0 -1
- data/test/responses/invalids/no_authnstatement.xml.base64 +0 -1
- data/test/responses/invalids/no_conditions.xml.base64 +0 -1
- data/test/responses/invalids/no_id.xml.base64 +0 -1
- data/test/responses/invalids/no_issuer_assertion.xml.base64 +0 -1
- data/test/responses/invalids/no_issuer_response.xml.base64 +0 -1
- data/test/responses/invalids/no_nameid.xml.base64 +0 -1
- data/test/responses/invalids/no_saml2.xml.base64 +0 -1
- data/test/responses/invalids/no_signature.xml.base64 +0 -1
- data/test/responses/invalids/no_status.xml.base64 +0 -1
- data/test/responses/invalids/no_status_code.xml.base64 +0 -1
- data/test/responses/invalids/no_subjectconfirmation_data.xml.base64 +0 -1
- data/test/responses/invalids/no_subjectconfirmation_method.xml.base64 +0 -1
- data/test/responses/invalids/response_invalid_signed_element.xml.base64 +0 -1
- data/test/responses/invalids/response_with_concealed_signed_assertion.xml +0 -51
- data/test/responses/invalids/response_with_doubled_signed_assertion.xml +0 -49
- data/test/responses/invalids/signature_wrapping_attack.xml.base64 +0 -1
- data/test/responses/invalids/status_code_responder.xml.base64 +0 -1
- data/test/responses/invalids/status_code_responer_and_msg.xml.base64 +0 -1
- data/test/responses/invalids/wrong_spnamequalifier.xml.base64 +0 -1
- data/test/responses/no_signature_ns.xml +0 -48
- data/test/responses/open_saml_response.xml +0 -56
- data/test/responses/response_assertion_wrapped.xml.base64 +0 -93
- data/test/responses/response_audience_self_closed_tag.xml.base64 +0 -1
- data/test/responses/response_double_status_code.xml.base64 +0 -1
- data/test/responses/response_encrypted_attrs.xml.base64 +0 -1
- data/test/responses/response_encrypted_nameid.xml.base64 +0 -1
- data/test/responses/response_eval.xml +0 -7
- data/test/responses/response_no_cert_and_encrypted_attrs.xml +0 -29
- data/test/responses/response_node_text_attack.xml.base64 +0 -1
- data/test/responses/response_node_text_attack2.xml.base64 +0 -1
- data/test/responses/response_node_text_attack3.xml.base64 +0 -1
- data/test/responses/response_unsigned_xml_base64 +0 -1
- data/test/responses/response_with_ampersands.xml +0 -139
- data/test/responses/response_with_ampersands.xml.base64 +0 -93
- data/test/responses/response_with_ds_namespace_at_the_root.xml.base64 +0 -1
- data/test/responses/response_with_multiple_attribute_statements.xml +0 -72
- data/test/responses/response_with_multiple_attribute_values.xml +0 -67
- data/test/responses/response_with_retrieval_method.xml +0 -26
- data/test/responses/response_with_saml2_namespace.xml.base64 +0 -102
- data/test/responses/response_with_signed_assertion.xml.base64 +0 -66
- data/test/responses/response_with_signed_assertion_2.xml.base64 +0 -1
- data/test/responses/response_with_signed_assertion_3.xml +0 -30
- data/test/responses/response_with_signed_message_and_assertion.xml +0 -34
- data/test/responses/response_with_undefined_recipient.xml.base64 +0 -1
- data/test/responses/response_without_attributes.xml.base64 +0 -79
- data/test/responses/response_without_reference_uri.xml.base64 +0 -1
- data/test/responses/response_wrapped.xml.base64 +0 -150
- data/test/responses/signed_message_encrypted_signed_assertion.xml.base64 +0 -1
- data/test/responses/signed_message_encrypted_unsigned_assertion.xml.base64 +0 -1
- data/test/responses/signed_nameid_in_atts.xml +0 -47
- data/test/responses/signed_unqual_nameid_in_atts.xml +0 -47
- data/test/responses/simple_saml_php.xml +0 -71
- data/test/responses/starfield_response.xml.base64 +0 -1
- data/test/responses/test_sign.xml +0 -43
- data/test/responses/unsigned_encrypted_adfs.xml +0 -23
- data/test/responses/unsigned_message_aes128_encrypted_signed_assertion.xml.base64 +0 -1
- data/test/responses/unsigned_message_aes192_encrypted_signed_assertion.xml.base64 +0 -1
- data/test/responses/unsigned_message_aes256_encrypted_signed_assertion.xml.base64 +0 -1
- data/test/responses/unsigned_message_des192_encrypted_signed_assertion.xml.base64 +0 -1
- data/test/responses/unsigned_message_encrypted_assertion_without_saml_namespace.xml.base64 +0 -1
- data/test/responses/unsigned_message_encrypted_signed_assertion.xml.base64 +0 -1
- data/test/responses/unsigned_message_encrypted_unsigned_assertion.xml.base64 +0 -1
- data/test/responses/valid_response.xml.base64 +0 -1
- data/test/responses/valid_response_with_formatted_x509certificate.xml.base64 +0 -1
- data/test/responses/valid_response_without_x509certificate.xml.base64 +0 -1
- data/test/saml_message_test.rb +0 -56
- data/test/settings_test.rb +0 -329
- data/test/slo_logoutrequest_test.rb +0 -448
- data/test/slo_logoutresponse_test.rb +0 -233
- data/test/test_helper.rb +0 -331
- data/test/utils_test.rb +0 -259
- data/test/xml_security_test.rb +0 -421
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 3ac80594648fe4830b965c65366f8bb261a4edfe148c9e929f352b39a1b3428f
|
|
4
|
+
data.tar.gz: b6379aa66a89f2074f434e8c97163022d533e1cdc30c20555135c2e4c82353b4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
8
|
-
- 2.2.
|
|
9
|
-
- 2.3.
|
|
10
|
-
- 2.4.
|
|
11
|
-
- 2.5.
|
|
12
|
-
-
|
|
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.
|
|
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.
|
|
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 [](http://travis-ci.org/onelogin/ruby-saml) [](http://travis-ci.org/onelogin/ruby-saml) [](https://coveralls.io/r/onelogin/ruby-saml?branch=master)
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
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.
|
|
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.
|
|
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.
|
|
243
|
-
settings.
|
|
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.
|
|
304
|
-
settings.
|
|
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.
|
|
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
|
-
*
|
|
378
|
-
*
|
|
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-
|
|
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
|
|
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.
|
|
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[:
|
|
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 "
|
|
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 [
|
|
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
|