ruby-saml 1.16.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +3 -0
- data/.github/workflows/test.yml +49 -3
- data/CHANGELOG.md +31 -8
- data/README.md +96 -69
- data/UPGRADING.md +9 -0
- data/lib/onelogin/ruby-saml/authrequest.rb +7 -8
- data/lib/onelogin/ruby-saml/idp_metadata_parser.rb +6 -8
- data/lib/onelogin/ruby-saml/logoutrequest.rb +6 -6
- data/lib/onelogin/ruby-saml/logoutresponse.rb +2 -1
- data/lib/onelogin/ruby-saml/metadata.rb +21 -25
- data/lib/onelogin/ruby-saml/response.rb +116 -52
- data/lib/onelogin/ruby-saml/saml_message.rb +21 -11
- data/lib/onelogin/ruby-saml/settings.rb +132 -31
- data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +7 -6
- data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +7 -7
- data/lib/onelogin/ruby-saml/utils.rb +86 -22
- data/lib/onelogin/ruby-saml/version.rb +1 -1
- data/lib/xml_security.rb +116 -36
- data/ruby-saml.gemspec +6 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59cce47afe1159fc5674f2eaf8f0392d12df280cc97fa2a4ccd7926daf989445
|
4
|
+
data.tar.gz: 30a49c237e7a88328745b788d62e9ea92e87342fc571d20e002eb4feddd964ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c67ec4923ca4bc5e07736717d1e40f604296c95c00d1fe8ec7d28c586988b368d566a16782c676c2ce27d38d6d7e1386a5347bfbb40efc98eb033525605f5dcb
|
7
|
+
data.tar.gz: 4944ad0dc2a3999e78da570aa8faa6282e26868606a5011d2b623a6ef0a9150d2e6ee08a4245d090e5d4837a9dc9ffaa78bf46d84fe466ea9384662d305d4c94
|
data/.github/FUNDING.yml
ADDED
data/.github/workflows/test.yml
CHANGED
@@ -8,11 +8,57 @@ jobs:
|
|
8
8
|
strategy:
|
9
9
|
fail-fast: false
|
10
10
|
matrix:
|
11
|
-
os:
|
12
|
-
|
11
|
+
os:
|
12
|
+
- ubuntu-20.04
|
13
|
+
- macos-latest
|
14
|
+
- windows-latest
|
15
|
+
ruby-version:
|
16
|
+
- 2.1
|
17
|
+
- 2.2
|
18
|
+
- 2.3
|
19
|
+
- 2.4
|
20
|
+
- 2.5
|
21
|
+
- 2.6
|
22
|
+
- 2.7
|
23
|
+
- 3.0
|
24
|
+
- 3.1
|
25
|
+
- 3.2
|
26
|
+
- 3.3
|
27
|
+
- jruby-9.1
|
28
|
+
- jruby-9.2
|
29
|
+
- jruby-9.3
|
30
|
+
- jruby-9.4
|
31
|
+
- truffleruby
|
32
|
+
exclude:
|
33
|
+
- os: macos-latest
|
34
|
+
ruby-version: 2.1
|
35
|
+
- os: macos-latest
|
36
|
+
ruby-version: 2.2
|
37
|
+
- os: macos-latest
|
38
|
+
ruby-version: 2.3
|
39
|
+
- os: macos-latest
|
40
|
+
ruby-version: 2.4
|
41
|
+
- os: macos-latest
|
42
|
+
ruby-version: 2.5
|
43
|
+
- os: macos-latest
|
44
|
+
ruby-version: jruby-9.1
|
45
|
+
- os: macos-latest
|
46
|
+
ruby-version: jruby-9.2
|
47
|
+
- os: windows-latest
|
48
|
+
ruby-version: 2.1
|
49
|
+
- os: windows-latest
|
50
|
+
ruby-version: jruby-9.1
|
51
|
+
- os: windows-latest
|
52
|
+
ruby-version: jruby-9.2
|
53
|
+
- os: windows-latest
|
54
|
+
ruby-version: jruby-9.3
|
55
|
+
- os: windows-latest
|
56
|
+
ruby-version: jruby-9.4
|
57
|
+
- os: windows-latest
|
58
|
+
ruby-version: truffleruby
|
13
59
|
runs-on: ${{ matrix.os }}
|
14
60
|
steps:
|
15
|
-
- uses: actions/checkout@
|
61
|
+
- uses: actions/checkout@v4
|
16
62
|
- name: Set up Ruby ${{ matrix.ruby-version }}
|
17
63
|
uses: ruby/setup-ruby@v1
|
18
64
|
with:
|
data/CHANGELOG.md
CHANGED
@@ -1,11 +1,28 @@
|
|
1
1
|
# Ruby SAML Changelog
|
2
|
+
|
3
|
+
### 1.18.0 (Mar 12, 2025)
|
4
|
+
* [#750](https://github.com/SAML-Toolkits/ruby-saml/pull/750) Fix vulnerabilities: CVE-2025-25291, CVE-2025-25292: SAML authentication bypass via Signature Wrapping attack allowed due parser differential. Fix vulnerability: CVE-2025-25293: Potential DOS abusing of compressed messages.
|
5
|
+
* [#718](https://github.com/SAML-Toolkits/ruby-saml/pull/718/) Add support to retrieve from SAMLResponse the AuthnInstant and AuthnContextClassRef values
|
6
|
+
* [#720](https://github.com/SAML-Toolkits/ruby-saml/pull/720) Fix ambiguous regex warnings
|
7
|
+
* [#715](https://github.com/SAML-Toolkits/ruby-saml/pull/715) Fix typo in SPNameQualifier error text
|
8
|
+
|
9
|
+
### 1.17.0 (Sep 10, 2024)
|
10
|
+
* Fix for critical vulnerability CVE-2024-45409: SAML authentication bypass via Incorrect XPath selector
|
11
|
+
* [#687](https://github.com/SAML-Toolkits/ruby-saml/pull/687) Add CI coverage for Ruby 3.3 and Windows.
|
12
|
+
* [#673](https://github.com/SAML-Toolkits/ruby-saml/pull/673) Add `Settings#sp_cert_multi` paramter to facilitate SP certificate and key rotation.
|
13
|
+
* [#673](https://github.com/SAML-Toolkits/ruby-saml/pull/673) Support multiple simultaneous SP decryption keys via `Settings#sp_cert_multi` parameter.
|
14
|
+
* [#673](https://github.com/SAML-Toolkits/ruby-saml/pull/673) Deprecate `Settings#certificate_new` parameter.
|
15
|
+
* [#673](https://github.com/SAML-Toolkits/ruby-saml/pull/673) `:check_sp_cert_expiration` will use the first non-expired certificate/key when signing/decrypting. It will raise an error only if there are no valid certificates/keys.
|
16
|
+
* [#673](https://github.com/SAML-Toolkits/ruby-saml/pull/673) `:check_sp_cert_expiration` now validates the certificate `not_before` condition; previously it was only validating `not_after`.
|
17
|
+
* [#673](https://github.com/SAML-Toolkits/ruby-saml/pull/673) `:check_sp_cert_expiration` now causes the generated SP metadata to exclude any inactive/expired certificates.
|
18
|
+
|
2
19
|
### 1.16.0 (Oct 09, 2023)
|
3
20
|
* [#671](https://github.com/SAML-Toolkits/ruby-saml/pull/671) Add support on LogoutRequest with Encrypted NameID
|
4
21
|
|
5
22
|
### 1.15.0 (Jan 04, 2023)
|
6
23
|
* [#650](https://github.com/SAML-Toolkits/ruby-saml/pull/650) Replace strip! by strip on compute_digest method
|
7
|
-
* [#638](https://github.com/SAML-Toolkits/ruby-saml/pull/638) Fix dateTime format for the validUntil attribute of the generated metadata
|
8
|
-
* [#576](https://github.com/SAML-Toolkits/ruby-saml/pull/576) Support
|
24
|
+
* [#638](https://github.com/SAML-Toolkits/ruby-saml/pull/638) Fix dateTime format for the validUntil attribute of the generated metadata
|
25
|
+
* [#576](https://github.com/SAML-Toolkits/ruby-saml/pull/576) Support `Settings#idp_cert_multi` with string keys
|
9
26
|
* [#567](https://github.com/SAML-Toolkits/ruby-saml/pull/567) Improve Code quality
|
10
27
|
* Add info about new repo, new maintainer, new security contact
|
11
28
|
* Fix tests, Adjust dependencies, Add ruby 3.2 and new jruby versions tests to the CI. Add coveralls support
|
@@ -29,6 +46,12 @@
|
|
29
46
|
* Add warning about the use of IdpMetadataParser class and SSRF
|
30
47
|
* CI: Migrate from Travis to Github Actions
|
31
48
|
|
49
|
+
### 1.12.4 (Mar 12, 2025)
|
50
|
+
* [#750](https://github.com/SAML-Toolkits/ruby-saml/pull/750) Fix vulnerabilities: CVE-2025-25291, CVE-2025-25292: SAML authentication bypass via Signature Wrapping attack allowed due parser differential. Fix vulnerability: CVE-2025-25293: Potential DOS abusing of compressed messages.
|
51
|
+
|
52
|
+
### 1.12.3 (Sep 10, 2024)
|
53
|
+
* Fix for critical vulnerability CVE-2024-45409: SAML authentication bypass via Incorrect XPath selector
|
54
|
+
|
32
55
|
### 1.12.2 (Apr 08, 2021)
|
33
56
|
* [#575](https://github.com/onelogin/ruby-saml/pull/575) Fix SloLogoutresponse bug on LogoutRequest
|
34
57
|
|
@@ -38,7 +61,7 @@
|
|
38
61
|
|
39
62
|
### 1.12.0 (Feb 18, 2021)
|
40
63
|
* Support AES-128-GCM, AES-192-GCM, and AES-256-GCM encryptions
|
41
|
-
* Parse & return SLO ResponseLocation in IDPMetadataParser & Settings
|
64
|
+
* Parse & return SLO ResponseLocation in IDPMetadataParser & Settings
|
42
65
|
* Adding idp_sso_service_url and idp_slo_service_url settings
|
43
66
|
* [#536](https://github.com/onelogin/ruby-saml/pull/536) Adding feth method to be able retrieve attributes based on regex
|
44
67
|
* Reduce size of built gem by excluding the test folder
|
@@ -170,7 +193,7 @@
|
|
170
193
|
* Fix response_test.rb of gem 1.3.0
|
171
194
|
* Add reference to Security Guidelines
|
172
195
|
* Update License
|
173
|
-
* [#334](https://github.com/onelogin/ruby-saml/pull/334) Keep API backward-compatibility on IdpMetadataParser fingerprint method.
|
196
|
+
* [#334](https://github.com/onelogin/ruby-saml/pull/334) Keep API backward-compatibility on IdpMetadataParser fingerprint method.
|
174
197
|
|
175
198
|
### 1.3.0 (June 24, 2016)
|
176
199
|
* [Security Fix](https://github.com/onelogin/ruby-saml/commit/a571f52171e6bfd87db59822d1d9e8c38fb3b995) Add extra validations to prevent Signature wrapping attacks
|
@@ -188,7 +211,7 @@
|
|
188
211
|
* [#316](https://github.com/onelogin/ruby-saml/pull/316) Fix Misspelling of transation_id to transaction_id
|
189
212
|
* [#321](https://github.com/onelogin/ruby-saml/pull/321) Support Attribute Names on IDPSSODescriptor parser
|
190
213
|
* Changes on empty URI of Signature reference management
|
191
|
-
* [#320](https://github.com/onelogin/ruby-saml/pull/320) Dont mutate document to fix lack of reference URI
|
214
|
+
* [#320](https://github.com/onelogin/ruby-saml/pull/320) Dont mutate document to fix lack of reference URI
|
192
215
|
* [#306](https://github.com/onelogin/ruby-saml/pull/306) Support WantAssertionsSigned
|
193
216
|
|
194
217
|
### 1.1.2 (February 15, 2016)
|
@@ -205,9 +228,9 @@
|
|
205
228
|
* [#270](https://github.com/onelogin/ruby-saml/pull/270) Allow SAML elements to come from any namespace (at decryption process)
|
206
229
|
* [#261](https://github.com/onelogin/ruby-saml/pull/261) Allow validate_subject_confirmation Response validation to be skipped
|
207
230
|
* [#258](https://github.com/onelogin/ruby-saml/pull/258) Fix allowed_clock_drift on the validate_session_expiration test
|
208
|
-
* [#256](https://github.com/onelogin/ruby-saml/pull/256) Separate the create_authentication_xml_doc in two methods.
|
231
|
+
* [#256](https://github.com/onelogin/ruby-saml/pull/256) Separate the create_authentication_xml_doc in two methods.
|
209
232
|
* [#255](https://github.com/onelogin/ruby-saml/pull/255) Refactor validate signature.
|
210
|
-
* [#254](https://github.com/onelogin/ruby-saml/pull/254) Handle empty URI references
|
233
|
+
* [#254](https://github.com/onelogin/ruby-saml/pull/254) Handle empty URI references
|
211
234
|
* [#251](https://github.com/onelogin/ruby-saml/pull/251) Support qualified and unqualified NameID in attributes
|
212
235
|
* [#234](https://github.com/onelogin/ruby-saml/pull/234) Add explicit support for JRuby
|
213
236
|
|
@@ -215,7 +238,7 @@
|
|
215
238
|
* [#247](https://github.com/onelogin/ruby-saml/pull/247) Avoid entity expansion (XEE attacks)
|
216
239
|
* [#246](https://github.com/onelogin/ruby-saml/pull/246) Fix bug generating Logout Response (issuer was at wrong order)
|
217
240
|
* [#243](https://github.com/onelogin/ruby-saml/issues/243) and [#244](https://github.com/onelogin/ruby-saml/issues/244) Fix metadata builder errors. Fix metadata xsd.
|
218
|
-
* [#241](https://github.com/onelogin/ruby-saml/pull/241) Add decrypt support (EncryptID and EncryptedAssertion). Improve compatibility with namespaces.
|
241
|
+
* [#241](https://github.com/onelogin/ruby-saml/pull/241) Add decrypt support (EncryptID and EncryptedAssertion). Improve compatibility with namespaces.
|
219
242
|
* [#240](https://github.com/onelogin/ruby-saml/pull/240) and [#238](https://github.com/onelogin/ruby-saml/pull/238) Improve test coverage and refactor.
|
220
243
|
* [#239](https://github.com/onelogin/ruby-saml/pull/239) Improve security: Add more validations to SAMLResponse, LogoutRequest and LogoutResponse. Refactor code and improve tests coverage.
|
221
244
|
* [#237](https://github.com/onelogin/ruby-saml/pull/237) Don't pretty print metadata by default.
|
data/README.md
CHANGED
@@ -4,16 +4,45 @@
|
|
4
4
|
[](https://badge.fury.io/rb/ruby-saml)
|
5
5
|
[](https://badge.fury.io/gh/SAML-Toolkits%2Fruby-saml)   
|
6
6
|
|
7
|
-
|
7
|
+
Minor and patch versions of Ruby SAML may introduce breaking changes. Please read
|
8
8
|
[UPGRADING.md](UPGRADING.md) for guidance on upgrading to new Ruby SAML versions.
|
9
9
|
|
10
|
+
### Pay it Forward: Support RubySAML and Strengthen Open-Source Security
|
11
|
+
|
12
|
+
RubySAML is a trusted authentication library used by startups and enterprises alike.
|
13
|
+
|
14
|
+
But security doesn't happen in a vacuum. Vulnerabilities in authentication libraries can
|
15
|
+
have widespread consequences. Maintaining open-source security requires continuous
|
16
|
+
effort, expertise, and funding. By supporting RubySAML, you’re not just securing your
|
17
|
+
own systems—you’re strengthening auth security globally.
|
18
|
+
|
19
|
+
#### How you can help
|
20
|
+
|
21
|
+
* Sponsor RubySAML: [GitHub Sponsors](https://github.com/sponsors/SAML-Toolkits)
|
22
|
+
* Contribute to secure-by-design improvements
|
23
|
+
* Responsibly report vulnerabilities (see "Vulnerability Reporting" above)
|
24
|
+
|
25
|
+
Security is a shared responsibility. If RubySAML has helped your organization, please
|
26
|
+
consider giving back. Together, we can keep authentication secure.
|
27
|
+
|
28
|
+
### Sponsors
|
29
|
+
|
30
|
+
Thanks to the following sponsors for securing the open source ecosystem,
|
31
|
+
|
32
|
+
[<img alt="84codes" src="https://avatars.githubusercontent.com/u/5353257" width="75px">](https://www.84codes.com)
|
33
|
+
|
34
|
+
|
35
|
+
## Vulnerabilities
|
36
|
+
|
37
|
+
There are critical vulnerabilities affecting ruby-saml < 1.18.0, two of them allows SAML authentication bypass (CVE-2025-25291, CVE-2025-25292, CVE-2025-25293). Please upgrade to a fixed version (1.18.0)
|
38
|
+
|
10
39
|
## Overview
|
11
40
|
|
12
41
|
The Ruby SAML library is for implementing the client side of a SAML authorization,
|
13
42
|
i.e. it provides a means for managing authorization initialization and confirmation
|
14
43
|
requests from identity providers.
|
15
44
|
|
16
|
-
SAML authorization is a two
|
45
|
+
SAML authorization is a two-step process and you are expected to implement support for both.
|
17
46
|
|
18
47
|
We created a demo project for Rails 4 that uses the latest version of this library:
|
19
48
|
[ruby-saml-example](https://github.com/saml-toolkits/ruby-saml-example)
|
@@ -22,37 +51,17 @@ We created a demo project for Rails 4 that uses the latest version of this libra
|
|
22
51
|
|
23
52
|
The following Ruby versions are covered by CI testing:
|
24
53
|
|
25
|
-
* 2.1.
|
26
|
-
*
|
27
|
-
* 2.3.x
|
28
|
-
* 2.4.x
|
29
|
-
* 2.5.x
|
30
|
-
* 2.6.x
|
31
|
-
* 2.7.x
|
32
|
-
* 3.0.x
|
33
|
-
* 3.1
|
34
|
-
* 3.2
|
35
|
-
* JRuby 9.1.x
|
36
|
-
* JRuby 9.2.x
|
37
|
-
* JRuby 9.3.X
|
38
|
-
* JRuby 9.4.0
|
54
|
+
* Ruby (MRI) 2.1 to 3.3
|
55
|
+
* JRuby 9.1 to 9.4
|
39
56
|
* TruffleRuby (latest)
|
40
57
|
|
41
|
-
In addition, the following may work but are untested:
|
42
|
-
|
43
|
-
* 1.8.7
|
44
|
-
* 1.9.x
|
45
|
-
* 2.0.x
|
46
|
-
* JRuby 1.7.x
|
47
|
-
* JRuby 9.0.x
|
48
|
-
|
49
58
|
## Adding Features, Pull Requests
|
50
59
|
|
51
60
|
* Fork the repository
|
52
61
|
* Make your feature addition or bug fix
|
53
62
|
* Add tests for your new features. This is important so we don't break any features in a future version unintentionally.
|
54
63
|
* Ensure all tests pass by running `bundle exec rake test`.
|
55
|
-
* Do not change
|
64
|
+
* Do not change Rakefile, version, or history.
|
56
65
|
* Open a pull request, following [this template](https://gist.github.com/Lordnibbler/11002759).
|
57
66
|
|
58
67
|
## Security Guidelines
|
@@ -63,21 +72,20 @@ by mail to the maintainer: sixto.martin.garcia+security@gmail.com
|
|
63
72
|
### Security Warning
|
64
73
|
|
65
74
|
Some tools may incorrectly report ruby-saml is a potential security vulnerability.
|
66
|
-
ruby-saml depends on Nokogiri, and it
|
75
|
+
ruby-saml depends on Nokogiri, and it is possible to use Nokogiri in a dangerous way
|
67
76
|
(by enabling its DTDLOAD option and disabling its NONET option).
|
68
77
|
This dangerous Nokogiri configuration, which is sometimes used by other components,
|
69
78
|
can create an XML External Entity (XXE) vulnerability if the XML data is not trusted.
|
70
79
|
However, ruby-saml never enables this dangerous Nokogiri configuration;
|
71
80
|
ruby-saml never enables DTDLOAD, and it never disables NONET.
|
72
81
|
|
73
|
-
The OneLogin::RubySaml::IdpMetadataParser class does not validate
|
74
|
-
that is introduced in order to be parsed.
|
82
|
+
The OneLogin::RubySaml::IdpMetadataParser class does not validate the provided URL before parsing.
|
75
83
|
|
76
|
-
Usually the same administrator
|
84
|
+
Usually, the same administrator who handles the Service Provider also sets the URL to
|
77
85
|
the IdP, which should be a trusted resource.
|
78
86
|
|
79
|
-
But there are other scenarios, like a
|
80
|
-
delegates this functionality to other users. In this case, extra
|
87
|
+
But there are other scenarios, like a SaaS app where the administrator of the app
|
88
|
+
delegates this functionality to other users. In this case, extra precautions should
|
81
89
|
be taken in order to validate such URL inputs and avoid attacks like SSRF.
|
82
90
|
|
83
91
|
## Getting Started
|
@@ -89,7 +97,7 @@ Using `Gemfile`
|
|
89
97
|
|
90
98
|
```ruby
|
91
99
|
# latest stable
|
92
|
-
gem 'ruby-saml', '~> 1.
|
100
|
+
gem 'ruby-saml', '~> 1.17.0'
|
93
101
|
|
94
102
|
# or track master for bleeding-edge
|
95
103
|
gem 'ruby-saml', :github => 'saml-toolkit/ruby-saml'
|
@@ -134,8 +142,8 @@ gem install nokogiri --version '~> 1.5.10'
|
|
134
142
|
### Configuring Logging
|
135
143
|
|
136
144
|
When troubleshooting SAML integration issues, you will find it extremely helpful to examine the
|
137
|
-
output of this gem's business logic. By default, log messages are emitted to RAILS_DEFAULT_LOGGER
|
138
|
-
when the gem is used in a Rails context, and to STDOUT when the gem is used outside of Rails.
|
145
|
+
output of this gem's business logic. By default, log messages are emitted to `RAILS_DEFAULT_LOGGER`
|
146
|
+
when the gem is used in a Rails context, and to `STDOUT` when the gem is used outside of Rails.
|
139
147
|
|
140
148
|
To override the default behavior and control the destination of log messages, provide
|
141
149
|
a ruby Logger object to the gem's logging singleton:
|
@@ -158,7 +166,7 @@ def init
|
|
158
166
|
end
|
159
167
|
```
|
160
168
|
|
161
|
-
If the SP knows who should be authenticated in the IdP,
|
169
|
+
If the SP knows who should be authenticated in the IdP, it can provide that info as follows:
|
162
170
|
|
163
171
|
```ruby
|
164
172
|
def init
|
@@ -236,7 +244,7 @@ def saml_settings
|
|
236
244
|
end
|
237
245
|
```
|
238
246
|
|
239
|
-
The use of settings.issuer is deprecated in
|
247
|
+
The use of `settings.issuer` is deprecated in favor of `settings.sp_entity_id` since version 1.11.0
|
240
248
|
|
241
249
|
Some assertion validations can be skipped by passing parameters to `OneLogin::RubySaml::Response.new()`.
|
242
250
|
For example, you can skip the `AuthnStatement`, `Conditions`, `Recipient`, or the `SubjectConfirmation`
|
@@ -391,11 +399,11 @@ IdpMetadataParser by its Entity Id value:
|
|
391
399
|
)
|
392
400
|
```
|
393
401
|
|
394
|
-
### Retrieve one Entity Descriptor with
|
402
|
+
### Retrieve one Entity Descriptor with a specific binding and nameid format when several are available
|
395
403
|
|
396
|
-
If the
|
397
|
-
|
398
|
-
by the values of binding and
|
404
|
+
If the metadata contains multiple bindings and NameID formats, the relevant ones
|
405
|
+
can be specified when retrieving the settings from the IdpMetadataParser
|
406
|
+
by the values of binding and NameID:
|
399
407
|
|
400
408
|
```ruby
|
401
409
|
validate_cert = true
|
@@ -459,13 +467,13 @@ if valid
|
|
459
467
|
entity_id: "<entity_id_of_the_entity_to_be_retrieved>"
|
460
468
|
)
|
461
469
|
else
|
462
|
-
print "Metadata
|
470
|
+
print "Metadata Signature failed to be verified with the cert provided"
|
463
471
|
end
|
464
472
|
```
|
465
473
|
|
466
474
|
## Retrieving Attributes
|
467
475
|
|
468
|
-
If you are using `saml:AttributeStatement` to transfer data
|
476
|
+
If you are using `saml:AttributeStatement` to transfer data, such as the username, you can access all the attributes through `response.attributes`. It contains all the `saml:AttributeStatement`s with its 'Name' as an indifferent key and one or more `saml:AttributeValue`s as values. The value returned depends on the value of the
|
469
477
|
`single_value_compatibility` (when activated, only the first value is returned)
|
470
478
|
|
471
479
|
```ruby
|
@@ -688,7 +696,7 @@ Next, you may specify the specific SP SAML messages you would like to sign:
|
|
688
696
|
settings.security[:logout_responses_signed] = true # Enable signature on Logout Response
|
689
697
|
```
|
690
698
|
|
691
|
-
Signatures will be handled automatically for both `HTTP-Redirect` and `HTTP-
|
699
|
+
Signatures will be handled automatically for both `HTTP-Redirect` and `HTTP-POST` Binding.
|
692
700
|
Note that the RelayState parameter is used when creating the Signature on the `HTTP-Redirect` Binding.
|
693
701
|
Remember to provide it to the Signature builder if you are sending a `GET RelayState` parameter or the
|
694
702
|
signature validation process will fail at the Identity Provider.
|
@@ -735,10 +743,52 @@ validation fails. You may disable such exceptions using the `settings.security[:
|
|
735
743
|
settings.security[:soft] = true # Do not raise error on failed signature/certificate validations
|
736
744
|
```
|
737
745
|
|
746
|
+
#### Advanced SP Certificate Usage & Key Rollover
|
747
|
+
|
748
|
+
Ruby SAML provides the `settings.sp_cert_multi` parameter to enable the following
|
749
|
+
advanced usage scenarios:
|
750
|
+
- Rotating SP certificates and private keys without disruption of service.
|
751
|
+
- Specifying separate SP certificates for signing and encryption.
|
752
|
+
|
753
|
+
The `sp_cert_multi` parameter replaces `certificate` and `private_key`
|
754
|
+
(you may not specify both pparameters at the same time.) `sp_cert_multi` has the following shape:
|
755
|
+
|
756
|
+
```ruby
|
757
|
+
settings.sp_cert_multi = {
|
758
|
+
signing: [
|
759
|
+
{ certificate: cert1, private_key: private_key1 },
|
760
|
+
{ certificate: cert2, private_key: private_key2 }
|
761
|
+
],
|
762
|
+
encryption: [
|
763
|
+
{ certificate: cert1, private_key: private_key1 },
|
764
|
+
{ certificate: cert3, private_key: private_key1 }
|
765
|
+
],
|
766
|
+
}
|
767
|
+
```
|
768
|
+
|
769
|
+
Certificate rotation is acheived by inserting new certificates at the bottom of each list,
|
770
|
+
and then removing the old certificates from the top of the list once your IdPs have migrated.
|
771
|
+
A common practice is for apps to publish the current SP metadata at a URL endpoint and have
|
772
|
+
the IdP regularly poll for updates.
|
773
|
+
|
774
|
+
Note the following:
|
775
|
+
- You may re-use the same certificate and/or private key in multiple places, including for both signing and encryption.
|
776
|
+
- The IdP should attempt to verify signatures with *all* `:signing` certificates,
|
777
|
+
and permit if *any one* succeeds. When signing, Ruby SAML will use the first SP certificate
|
778
|
+
in the `sp_cert_multi[:signing]` array. This will be the first active/non-expired certificate
|
779
|
+
in the array if `settings.security[:check_sp_cert_expiration]` is true.
|
780
|
+
- The IdP may encrypt with any of the SP certificates in the `sp_cert_multi[:encryption]`
|
781
|
+
array. When decrypting, Ruby SAML attempt to decrypt with each SP private key in
|
782
|
+
`sp_cert_multi[:encryption]` until the decryption is successful. This will skip private
|
783
|
+
keys for inactive/expired certificates if `:check_sp_cert_expiration` is true.
|
784
|
+
- If `:check_sp_cert_expiration` is true, the generated SP metadata XML will not include
|
785
|
+
inactive/expired certificates. This avoids validation errors when the IdP reads the SP
|
786
|
+
metadata.
|
787
|
+
|
738
788
|
#### Audience Validation
|
739
789
|
|
740
790
|
A service provider should only consider a SAML response valid if the IdP includes an <AudienceRestriction>
|
741
|
-
element
|
791
|
+
element containing an <Audience> element that uniquely identifies the service provider. Unless you specify
|
742
792
|
the `skip_audience` option, Ruby SAML will validate that each SAML response includes an <Audience> element
|
743
793
|
whose contents matches `settings.sp_entity_id`.
|
744
794
|
|
@@ -758,29 +808,6 @@ is invalid using the `settings.security[:strict_audience_validation]` parameter.
|
|
758
808
|
settings.security[:strict_audience_validation] = true
|
759
809
|
```
|
760
810
|
|
761
|
-
#### Key Rollover
|
762
|
-
|
763
|
-
To update the SP X.509 certificate and private key without disruption of service, you may define the parameter
|
764
|
-
`settings.certificate_new`. This will publish the new SP certificate in your metadata so that your IdP counterparties
|
765
|
-
may cache it in preparation for rollover.
|
766
|
-
|
767
|
-
For example, if you to rollover from `CERT A` to `CERT B`. Before rollover, your settings should look as follows.
|
768
|
-
Both `CERT A` and `CERT B` will now appear in your SP metadata, however `CERT A` will still be used for signing
|
769
|
-
and encryption at this time.
|
770
|
-
|
771
|
-
```ruby
|
772
|
-
settings.certificate = "CERT A"
|
773
|
-
settings.private_key = "PRIVATE KEY FOR CERT A"
|
774
|
-
settings.certificate_new = "CERT B"
|
775
|
-
```
|
776
|
-
|
777
|
-
After the IdP has cached `CERT B`, you may then change your settings as follows:
|
778
|
-
|
779
|
-
```ruby
|
780
|
-
settings.certificate = "CERT B"
|
781
|
-
settings.private_key = "PRIVATE KEY FOR CERT B"
|
782
|
-
```
|
783
|
-
|
784
811
|
## Single Log Out
|
785
812
|
|
786
813
|
Ruby SAML supports SP-initiated Single Logout and IdP-Initiated Single Logout.
|
@@ -939,7 +966,7 @@ end
|
|
939
966
|
|
940
967
|
## Attribute Service
|
941
968
|
|
942
|
-
To request attributes from the IdP the SP
|
969
|
+
To request attributes from the IdP the SP must provide an attribute service within its metadata and reference the index in the assertion.
|
943
970
|
|
944
971
|
```ruby
|
945
972
|
settings = OneLogin::RubySaml::Settings.new
|
@@ -956,7 +983,7 @@ The `attribute_value` option additionally accepts an array of possible values.
|
|
956
983
|
|
957
984
|
## Custom Metadata Fields
|
958
985
|
|
959
|
-
Some IdPs may require
|
986
|
+
Some IdPs may require SPs to add additional fields (Organization, ContactPerson, etc.)
|
960
987
|
into the SP metadata. This can be achieved by extending the `OneLogin::RubySaml::Metadata`
|
961
988
|
class and overriding the `#add_extras` method as per the following example:
|
962
989
|
|
data/UPGRADING.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# Ruby SAML Migration Guide
|
2
2
|
|
3
|
+
## Updating from 1.17.x to 1.18.0
|
4
|
+
|
5
|
+
Version `1.18.0` changes the way the toolkit validates SAML signatures. There is a new order
|
6
|
+
how validation happens in the toolkit and also the toolkit by default will check malformed doc
|
7
|
+
when parsing a SAML Message (`settings.check_malformed_doc`).
|
8
|
+
|
9
|
+
The SignedDocument class defined at xml_security.rb experienced several changes.
|
10
|
+
We don't expect compatibilty issues if you use the main methods offered by ruby-saml, but if you use a fork or customized usage, is possible that you need to adapt your code.
|
11
|
+
|
3
12
|
## Updating from 1.12.x to 1.13.0
|
4
13
|
|
5
14
|
Version `1.13.0` adds `settings.idp_sso_service_binding` and `settings.idp_slo_service_binding`, and
|
@@ -64,7 +64,7 @@ module OneLogin
|
|
64
64
|
request_doc = create_authentication_xml_doc(settings)
|
65
65
|
request_doc.context[:attribute_quote] = :quote if settings.double_quote_xml_attribute_values
|
66
66
|
|
67
|
-
request = ""
|
67
|
+
request = "".dup
|
68
68
|
request_doc.write(request)
|
69
69
|
|
70
70
|
Logging.debug "Created AuthnRequest: #{request}"
|
@@ -72,9 +72,10 @@ module OneLogin
|
|
72
72
|
request = deflate(request) if settings.compress_request
|
73
73
|
base64_request = encode(request)
|
74
74
|
request_params = {"SAMLRequest" => base64_request}
|
75
|
+
sp_signing_key = settings.get_sp_signing_key
|
75
76
|
|
76
|
-
if settings.idp_sso_service_binding == Utils::BINDINGS[:redirect] && settings.security[:authn_requests_signed] &&
|
77
|
-
params['SigAlg']
|
77
|
+
if settings.idp_sso_service_binding == Utils::BINDINGS[:redirect] && settings.security[:authn_requests_signed] && sp_signing_key
|
78
|
+
params['SigAlg'] = settings.security[:signature_method]
|
78
79
|
url_string = OneLogin::RubySaml::Utils.build_query(
|
79
80
|
:type => 'SAMLRequest',
|
80
81
|
:data => base64_request,
|
@@ -82,7 +83,7 @@ module OneLogin
|
|
82
83
|
:sig_alg => params['SigAlg']
|
83
84
|
)
|
84
85
|
sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method])
|
85
|
-
signature =
|
86
|
+
signature = sp_signing_key.sign(sign_algorithm.new, url_string)
|
86
87
|
params['Signature'] = encode(signature)
|
87
88
|
end
|
88
89
|
|
@@ -179,15 +180,13 @@ module OneLogin
|
|
179
180
|
end
|
180
181
|
|
181
182
|
def sign_document(document, settings)
|
182
|
-
|
183
|
-
|
184
|
-
cert = settings.get_sp_cert
|
183
|
+
cert, private_key = settings.get_sp_signing_pair
|
184
|
+
if settings.idp_sso_service_binding == Utils::BINDINGS[:post] && settings.security[:authn_requests_signed] && private_key && cert
|
185
185
|
document.sign_document(private_key, cert, settings.security[:signature_method], settings.security[:digest_method])
|
186
186
|
end
|
187
187
|
|
188
188
|
document
|
189
189
|
end
|
190
|
-
|
191
190
|
end
|
192
191
|
end
|
193
192
|
end
|
@@ -186,8 +186,6 @@ module OneLogin
|
|
186
186
|
idpsso_descriptors.map {|id| IdpMetadata.new(id, id.parent.attributes["entityID"])}
|
187
187
|
end
|
188
188
|
|
189
|
-
private
|
190
|
-
|
191
189
|
# Retrieve the remote IdP metadata from the URL or a cached copy.
|
192
190
|
# @param url [String] Url where the XML of the Identity Provider Metadata is published.
|
193
191
|
# @param validate_cert [Boolean] If true and the URL is HTTPs, the cert of the domain is checked.
|
@@ -220,6 +218,8 @@ module OneLogin
|
|
220
218
|
)
|
221
219
|
end
|
222
220
|
|
221
|
+
private
|
222
|
+
|
223
223
|
class IdpMetadata
|
224
224
|
attr_reader :idpsso_descriptor, :entity_id
|
225
225
|
|
@@ -384,14 +384,12 @@ module OneLogin
|
|
384
384
|
# @return [String|nil] the fingerpint of the X509Certificate if it exists
|
385
385
|
#
|
386
386
|
def fingerprint(certificate, fingerprint_algorithm = XMLSecurity::Document::SHA1)
|
387
|
-
|
388
|
-
return unless certificate
|
387
|
+
return unless certificate
|
389
388
|
|
390
|
-
|
389
|
+
cert = OpenSSL::X509::Certificate.new(Base64.decode64(certificate))
|
391
390
|
|
392
|
-
|
393
|
-
|
394
|
-
end
|
391
|
+
fingerprint_alg = XMLSecurity::BaseDocument.new.algorithm(fingerprint_algorithm).new
|
392
|
+
fingerprint_alg.hexdigest(cert.to_der).upcase.scan(/../).join(":")
|
395
393
|
end
|
396
394
|
|
397
395
|
# @return [Array] the names of all SAML attributes if any exist
|
@@ -61,7 +61,7 @@ module OneLogin
|
|
61
61
|
request_doc = create_logout_request_xml_doc(settings)
|
62
62
|
request_doc.context[:attribute_quote] = :quote if settings.double_quote_xml_attribute_values
|
63
63
|
|
64
|
-
request = ""
|
64
|
+
request = "".dup
|
65
65
|
request_doc.write(request)
|
66
66
|
|
67
67
|
Logging.debug "Created SLO Logout Request: #{request}"
|
@@ -69,8 +69,9 @@ module OneLogin
|
|
69
69
|
request = deflate(request) if settings.compress_request
|
70
70
|
base64_request = encode(request)
|
71
71
|
request_params = {"SAMLRequest" => base64_request}
|
72
|
+
sp_signing_key = settings.get_sp_signing_key
|
72
73
|
|
73
|
-
if settings.idp_slo_service_binding == Utils::BINDINGS[:redirect] && settings.security[:logout_requests_signed] &&
|
74
|
+
if settings.idp_slo_service_binding == Utils::BINDINGS[:redirect] && settings.security[:logout_requests_signed] && sp_signing_key
|
74
75
|
params['SigAlg'] = settings.security[:signature_method]
|
75
76
|
url_string = OneLogin::RubySaml::Utils.build_query(
|
76
77
|
:type => 'SAMLRequest',
|
@@ -79,7 +80,7 @@ module OneLogin
|
|
79
80
|
:sig_alg => params['SigAlg']
|
80
81
|
)
|
81
82
|
sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method])
|
82
|
-
signature = settings.
|
83
|
+
signature = settings.get_sp_signing_key.sign(sign_algorithm.new, url_string)
|
83
84
|
params['Signature'] = encode(signature)
|
84
85
|
end
|
85
86
|
|
@@ -138,9 +139,8 @@ module OneLogin
|
|
138
139
|
|
139
140
|
def sign_document(document, settings)
|
140
141
|
# embed signature
|
141
|
-
|
142
|
-
|
143
|
-
cert = settings.get_sp_cert
|
142
|
+
cert, private_key = settings.get_sp_signing_pair
|
143
|
+
if settings.idp_slo_service_binding == Utils::BINDINGS[:post] && settings.security[:logout_requests_signed] && private_key && cert
|
144
144
|
document.sign_document(private_key, cert, settings.security[:signature_method], settings.security[:digest_method])
|
145
145
|
end
|
146
146
|
|
@@ -150,7 +150,8 @@ module OneLogin
|
|
150
150
|
# @raise [ValidationError] if soft == false and validation fails
|
151
151
|
#
|
152
152
|
def validate_structure
|
153
|
-
|
153
|
+
check_malformed_doc = check_malformed_doc?(settings)
|
154
|
+
unless valid_saml?(document, soft, check_malformed_doc)
|
154
155
|
return append_error("Invalid SAML Logout Response. Not match the saml-schema-protocol-2.0.xsd")
|
155
156
|
end
|
156
157
|
|