ruby-saml 0.8.8 → 0.8.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ruby-saml might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
- ---
2
- SHA512:
3
- metadata.gz: 4841fc584fcb21a2d195ca2a0a7a3835301b4888d6eb10a916db75aaae47baa2db3142ea816cced287cda13e0e94261e33096532888e0c4dbfb88f3e815a561c
4
- data.tar.gz: e1c81d64bc9cd5d3c9930934b02bbbe0b974b6a2606aae95ac81a0934a445971692f5ee6d5575baa5ca118f113776d824c581829fbf6f493a93041c7c6f74752
5
- SHA256:
6
- metadata.gz: 660a02871864e652d4676233c6c3f9afb36b5584a30dc6c12db8d683a891f609
7
- data.tar.gz: 317d540f0b08fc67e91d74e3d46f553a50634cf9b1d199084470d1f099b79b51
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 646f99f7f6a7590eb22b51fad5f183cfed8038be
4
+ data.tar.gz: 008e10e85a4aea26fdf2c067cc8f6112d18f55a7
5
+ SHA512:
6
+ metadata.gz: 7d239d7038cf7041e4dab1dd27dd92e5bb1f53d777ace0aa0c4ed9f08b4a9b077555e7d1eeed2ed8a8e21767039267747b9194172148e74bac7703205b862a16
7
+ data.tar.gz: 151df4d9fc610fbef47e5c93c73b8f25f9297b0bd457106e6fcd427933eebbe164c415d807ca9f70749937d5df66a4e49fb5423a7be2de6b1cd24641a077f94e
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Ruby SAML [![Build Status](https://secure.travis-ci.org/onelogin/ruby-saml.png)](http://travis-ci.org/onelogin/ruby-saml)
2
2
 
3
+ # Updating from 0.8.8 to 0.8.9
4
+ Version `0.8.9` deprecates the use of settings.issuer, use instead settings.sp_entity_id. Deprecates assertion_consumer_logout_service_url and assertion_consumer_logout_service_binding as well, use instead single_logout_service_url and single_logout_service_binding. Adds validate_audience.
5
+
3
6
  # Updating from 0.8.7 to 0.8.8
4
7
  Version `0.8.8` adds support for ForceAuthn and Subjects on AuthNRequests by the new name_identifier_value_requested setting
5
8
 
@@ -52,7 +55,7 @@ def saml_settings
52
55
  settings = OneLogin::RubySaml::Settings.new
53
56
 
54
57
  settings.assertion_consumer_service_url = "http://#{request.host}/saml/finalize"
55
- settings.issuer = request.host
58
+ settings.sp_entity_id = request.host
56
59
  settings.idp_sso_target_url = "https://app.onelogin.com/saml/signon/#{OneLoginAppId}"
57
60
  settings.idp_cert_fingerprint = OneLoginAppCertFingerPrint
58
61
  settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
@@ -90,7 +93,7 @@ class SamlController < ApplicationController
90
93
  settings = OneLogin::RubySaml::Settings.new
91
94
 
92
95
  settings.assertion_consumer_service_url = "http://#{request.host}/saml/consume"
93
- settings.issuer = request.host
96
+ settings.sp_entity_id = request.host
94
97
  settings.idp_sso_target_url = "https://app.onelogin.com/saml/signon/#{OneLoginAppId}"
95
98
  settings.idp_cert_fingerprint = OneLoginAppCertFingerPrint
96
99
  settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
@@ -56,9 +56,9 @@ module OneLogin
56
56
  if settings.assertion_consumer_service_url != nil
57
57
  root.attributes["AssertionConsumerServiceURL"] = settings.assertion_consumer_service_url
58
58
  end
59
- if settings.issuer != nil
59
+ if settings.sp_entity_id != nil
60
60
  issuer = root.add_element "saml:Issuer"
61
- issuer.text = settings.issuer
61
+ issuer.text = settings.sp_entity_id
62
62
  end
63
63
 
64
64
  if settings.name_identifier_value_requested != nil
@@ -47,9 +47,9 @@ module OneLogin
47
47
  root.attributes['IssueInstant'] = time
48
48
  root.attributes['Version'] = "2.0"
49
49
 
50
- if settings.issuer
50
+ if settings.sp_entity_id
51
51
  issuer = root.add_element "saml:Issuer", { "xmlns:saml" => "urn:oasis:names:tc:SAML:2.0:assertion" }
52
- issuer.text = settings.issuer
52
+ issuer.text = settings.sp_entity_id
53
53
  end
54
54
 
55
55
  if settings.name_identifier_value
@@ -117,8 +117,8 @@ module OneLogin
117
117
  return soft ? false : validation_error("No settings on response")
118
118
  end
119
119
 
120
- if settings.issuer.nil?
121
- return soft ? false : validation_error("No issuer in settings")
120
+ if settings.sp_entity_id.nil?
121
+ return soft ? false : validation_error("No sp_entity_id in settings")
122
122
  end
123
123
 
124
124
  if settings.idp_cert_fingerprint.nil? && settings.idp_cert.nil?
@@ -139,8 +139,8 @@ module OneLogin
139
139
  end
140
140
 
141
141
  def valid_issuer?(soft = true)
142
- unless URI.parse(issuer) == URI.parse(self.settings.issuer)
143
- return soft ? false : validation_error("Doesn't match the issuer, expected: <#{self.settings.issuer}>, but was: <#{issuer}>")
142
+ unless URI.parse(issuer) == URI.parse(self.settings.sp_entity_id)
143
+ return soft ? false : validation_error("Doesn't match the issuer, expected: <#{self.settings.sp_entity_id}>, but was: <#{issuer}>")
144
144
  end
145
145
  true
146
146
  end
@@ -22,15 +22,15 @@ module OneLogin
22
22
  # However we would like assertions signed if idp_cert_fingerprint or idp_cert is set
23
23
  "WantAssertionsSigned" => (!settings.idp_cert_fingerprint.nil? || !settings.idp_cert.nil?)
24
24
  }
25
- if settings.issuer != nil
26
- root.attributes["entityID"] = settings.issuer
25
+ if settings.sp_entity_id != nil
26
+ root.attributes["entityID"] = settings.sp_entity_id
27
27
  end
28
- if settings.assertion_consumer_logout_service_url != nil
28
+ if settings.single_logout_service_url != nil
29
29
  sp_sso.add_element "md:SingleLogoutService", {
30
30
  # Add this as a setting to create different bindings?
31
31
  "Binding" => "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect",
32
- "Location" => settings.assertion_consumer_logout_service_url,
33
- "ResponseLocation" => settings.assertion_consumer_logout_service_url,
32
+ "Location" => settings.single_logout_service_url,
33
+ "ResponseLocation" => settings.single_logout_service_url,
34
34
  "isDefault" => true,
35
35
  "index" => 0
36
36
  }
@@ -131,6 +131,15 @@ module OneLogin
131
131
  end
132
132
  end
133
133
 
134
+ # @return [Array] The Audience elements from the Contitions of the SAML Response.
135
+ #
136
+ def audiences
137
+ @audiences ||= begin
138
+ nodes = xpath_from_signed_assertion('/a:Conditions/a:AudienceRestriction/a:Audience')
139
+ nodes.map { |node| Utils.element_text(node) }.reject(&:empty?)
140
+ end
141
+ end
142
+
134
143
  private
135
144
 
136
145
  def validation_error(message)
@@ -141,6 +150,7 @@ module OneLogin
141
150
  validate_structure(soft) &&
142
151
  validate_response_state(soft) &&
143
152
  validate_conditions(soft) &&
153
+ validate_audience(soft) &&
144
154
  document.validate_document(get_fingerprint, soft) &&
145
155
  success?
146
156
  end
@@ -240,6 +250,23 @@ module OneLogin
240
250
  Time.parse(node.attributes[attribute])
241
251
  end
242
252
  end
253
+
254
+ # Validates the Audience, (If the Audience match the Service Provider EntityID)
255
+ # If fails, the error is added to the errors array
256
+ # @return [Boolean] True if there is an Audience Element that match the Service Provider EntityID, otherwise False if soft=True
257
+ # @raise [ValidationError] if soft == false and validation fails
258
+ #
259
+ def validate_audience(soft = true)
260
+ return true if audiences.empty? || settings.sp_entity_id.nil? || settings.sp_entity_id.empty?
261
+
262
+ unless audiences.include? settings.sp_entity_id
263
+ s = audiences.count > 1 ? 's' : '';
264
+ error_msg = "Invalid Audience#{s}. The audience#{s} #{audiences.join(',')}, did not match the expected audience #{settings.sp_entity_id}"
265
+ return soft ? false : validation_error(error_msg)
266
+ end
267
+
268
+ true
269
+ end
243
270
  end
244
271
  end
245
272
  end
@@ -8,7 +8,7 @@ module OneLogin
8
8
  self.send(acc, v) if self.respond_to? acc
9
9
  end
10
10
  end
11
- attr_accessor :assertion_consumer_service_url, :issuer, :sp_name_qualifier
11
+ attr_accessor :assertion_consumer_service_url, :sp_entity_id, :sp_name_qualifier
12
12
  attr_accessor :idp_sso_target_url, :idp_cert_fingerprint, :idp_cert, :name_identifier_format
13
13
  attr_accessor :authn_context
14
14
  attr_accessor :idp_slo_target_url
@@ -22,9 +22,84 @@ module OneLogin
22
22
  attr_accessor :passive
23
23
  attr_accessor :protocol_binding
24
24
 
25
+ # Compability
26
+ attr_accessor :issuer
27
+ attr_accessor :assertion_consumer_logout_service_url
28
+ attr_accessor :assertion_consumer_logout_service_binding
29
+
30
+ # @return [String] SP Entity ID
31
+ #
32
+ def sp_entity_id
33
+ val = nil
34
+ if @sp_entity_id.nil?
35
+ if @issuer
36
+ val = @issuer
37
+ end
38
+ else
39
+ val = @sp_entity_id
40
+ end
41
+ val
42
+ end
43
+
44
+ # Setter for SP Entity ID.
45
+ # @param val [String].
46
+ #
47
+ def sp_entity_id=(val)
48
+ @sp_entity_id = val
49
+ end
50
+
51
+ # @return [String] Single Logout Service URL.
52
+ #
53
+ def single_logout_service_url
54
+ val = nil
55
+ if @single_logout_service_url.nil?
56
+ if @assertion_consumer_logout_service_url
57
+ val = @assertion_consumer_logout_service_url
58
+ end
59
+ else
60
+ val = @single_logout_service_url
61
+ end
62
+ val
63
+ end
64
+
65
+ # Setter for the Single Logout Service URL.
66
+ # @param url [String].
67
+ #
68
+ def single_logout_service_url=(url)
69
+ @single_logout_service_url = url
70
+ end
71
+
72
+ # @return [String] Single Logout Service Binding.
73
+ #
74
+ def single_logout_service_binding
75
+ val = nil
76
+ if @single_logout_service_binding.nil?
77
+ if @assertion_consumer_logout_service_binding
78
+ val = @assertion_consumer_logout_service_binding
79
+ end
80
+ else
81
+ val = @single_logout_service_binding
82
+ end
83
+ val
84
+ end
85
+
86
+ # Setter for Single Logout Service Binding.
87
+ #
88
+ # (Currently we only support "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect")
89
+ # @param url [String]
90
+ #
91
+ def single_logout_service_binding=(url)
92
+ @single_logout_service_binding = url
93
+ end
94
+
25
95
  private
26
96
 
27
- DEFAULTS = {:compress_request => true, :double_quote_xml_attribute_values => false}
97
+ DEFAULTS = {
98
+ :compress_request => true,
99
+ :double_quote_xml_attribute_values => false,
100
+ :assertion_consumer_service_binding => "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST".freeze,
101
+ :single_logout_service_binding => "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect".freeze
102
+ }
28
103
  end
29
104
  end
30
105
  end
@@ -1,5 +1,5 @@
1
1
  module OneLogin
2
2
  module RubySaml
3
- VERSION = '0.8.8'
3
+ VERSION = '0.8.9'
4
4
  end
5
5
  end
@@ -36,7 +36,7 @@ class RubySamlTest < Test::Unit::TestCase
36
36
 
37
37
  assert logoutresponse.validate
38
38
 
39
- assert_equal settings.issuer, logoutresponse.issuer
39
+ assert_equal settings.sp_entity_id, logoutresponse.issuer
40
40
  assert_equal in_relation_to_request_id, logoutresponse.in_response_to
41
41
 
42
42
  assert logoutresponse.success?
@@ -92,9 +92,10 @@ class RubySamlTest < Test::Unit::TestCase
92
92
  assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate! }
93
93
  end
94
94
 
95
- should "raise validation error when in lack of issuer setting" do
95
+ should "raise validation error when in lack of sp_entity_id setting" do
96
96
  bad_settings = settings
97
97
  bad_settings.issuer = nil
98
+ bad_settings.sp_entity_id = nil
98
99
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_response, bad_settings)
99
100
  assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate! }
100
101
  end
@@ -159,6 +159,39 @@ class RubySamlTest < Test::Unit::TestCase
159
159
  assert_equal "support@onelogin.com", response.name_id
160
160
  assert_equal "smith", response.attributes["surname"]
161
161
  end
162
+
163
+ context '#validate_audience' do
164
+ should "return true when sp_entity_id not set or empty" do
165
+ response = OneLogin::RubySaml::Response.new(response_document_4)
166
+ response.stubs(:conditions).returns(nil)
167
+ settings = OneLogin::RubySaml::Settings.new
168
+ response.settings = settings
169
+ settings.idp_cert_fingerprint = signature_fingerprint_1
170
+ assert response.is_valid?
171
+ settings.sp_entity_id = ''
172
+ assert response.is_valid?
173
+ end
174
+
175
+ should "return false when sp_entity_id set to incorrectly" do
176
+ response = OneLogin::RubySaml::Response.new(response_document_4)
177
+ response.stubs(:conditions).returns(nil)
178
+ settings = OneLogin::RubySaml::Settings.new
179
+ response.settings = settings
180
+ settings.idp_cert_fingerprint = signature_fingerprint_1
181
+ settings.sp_entity_id = 'wrong_audience'
182
+ assert !response.is_valid?
183
+ end
184
+
185
+ should "return true when sp_entity_id set to correctly" do
186
+ response = OneLogin::RubySaml::Response.new(response_document_4)
187
+ response.stubs(:conditions).returns(nil)
188
+ settings = OneLogin::RubySaml::Settings.new
189
+ response.settings = settings
190
+ settings.idp_cert_fingerprint = signature_fingerprint_1
191
+ settings.sp_entity_id = 'audience'
192
+ assert response.is_valid?
193
+ end
194
+ end
162
195
  end
163
196
 
164
197
  context "#name_id" do
@@ -15,9 +15,9 @@ def valid_response(opts = {})
15
15
  xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
16
16
  ID=\"#{random_id}\" Version=\"2.0\"
17
17
  IssueInstant=\"#{opts[:issue_instant]}\"
18
- Destination=\"#{opts[:settings].assertion_consumer_logout_service_url}\"
18
+ Destination=\"#{opts[:settings].single_logout_service_url}\"
19
19
  InResponseTo=\"#{opts[:uuid]}\">
20
- <saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].issuer}</saml:Issuer>
20
+ <saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].sp_entity_id}</saml:Issuer>
21
21
  <samlp:Status xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">
22
22
  <samlp:StatusCode xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
23
23
  Value=\"urn:oasis:names:tc:SAML:2.0:status:Success\">
@@ -33,9 +33,9 @@ def unsuccessful_response(opts = {})
33
33
  xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
34
34
  ID=\"#{random_id}\" Version=\"2.0\"
35
35
  IssueInstant=\"#{opts[:issue_instant]}\"
36
- Destination=\"#{opts[:settings].assertion_consumer_logout_service_url}\"
36
+ Destination=\"#{opts[:settings].single_logout_service_url}\"
37
37
  InResponseTo=\"#{opts[:uuid]}\">
38
- <saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].issuer}</saml:Issuer>
38
+ <saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].sp_entity_id}</saml:Issuer>
39
39
  <samlp:Status xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">
40
40
  <samlp:StatusCode xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
41
41
  Value=\"urn:oasis:names:tc:SAML:2.0:status:Requester\">
@@ -55,8 +55,8 @@ def settings
55
55
  @settings ||= OneLogin::RubySaml::Settings.new(
56
56
  {
57
57
  :assertion_consumer_service_url => "http://app.muda.no/sso/consume",
58
- :assertion_consumer_logout_service_url => "http://app.muda.no/sso/consume_logout",
59
- :issuer => "http://app.muda.no",
58
+ :single_logout_service_url => "http://app.muda.no/sso/consume_logout",
59
+ :sp_entity_id => "http://app.muda.no",
60
60
  :sp_name_qualifier => "http://sso.muda.no",
61
61
  :idp_sso_target_url => "http://sso.muda.no/sso",
62
62
  :idp_slo_target_url => "http://sso.muda.no/slo",
@@ -8,11 +8,11 @@ class SettingsTest < Test::Unit::TestCase
8
8
  end
9
9
  should "should provide getters and settings" do
10
10
  accessors = [
11
- :assertion_consumer_service_url, :issuer, :sp_name_qualifier,
11
+ :assertion_consumer_service_url, :issuer, :sp_entity_id, :sp_name_qualifier,
12
12
  :idp_sso_target_url, :idp_cert_fingerprint, :name_identifier_format,
13
13
  :idp_slo_target_url, :name_identifier_value, :name_identifier_value_requested,
14
14
  :sessionindex, :assertion_consumer_logout_service_url,
15
- :passive, :force_authn, :protocol_binding
15
+ :passive, :force_authn, :protocol_binding, :single_logout_service_url, :single_logout_service_binding
16
16
  ]
17
17
 
18
18
  accessors.each do |accessor|
metadata CHANGED
@@ -1,49 +1,54 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ruby-saml
3
- version: !ruby/object:Gem::Version
4
- version: 0.8.8
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.9
5
5
  platform: ruby
6
- authors:
6
+ authors:
7
7
  - OneLogin LLC
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
-
12
- date: 2019-03-21 00:00:00 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
11
+ date: 2019-05-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
15
14
  name: uuid
16
- prerelease: false
17
- requirement: &id001 !ruby/object:Gem::Requirement
18
- requirements:
19
- - - ~>
20
- - !ruby/object:Gem::Version
21
- version: "2.3"
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.3'
22
20
  type: :runtime
23
- version_requirements: *id001
24
- - !ruby/object:Gem::Dependency
25
- name: nokogiri
26
21
  prerelease: false
27
- requirement: &id002 !ruby/object:Gem::Requirement
28
- requirements:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
29
31
  - - ">="
30
- - !ruby/object:Gem::Version
32
+ - !ruby/object:Gem::Version
31
33
  version: 1.5.0
32
34
  type: :runtime
33
- version_requirements: *id002
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.5.0
34
41
  description: SAML toolkit for Ruby on Rails
35
42
  email: support@onelogin.com
36
43
  executables: []
37
-
38
44
  extensions: []
39
-
40
- extra_rdoc_files:
45
+ extra_rdoc_files:
41
46
  - LICENSE
42
47
  - README.md
43
- files:
44
- - .document
45
- - .gitignore
46
- - .travis.yml
48
+ files:
49
+ - ".document"
50
+ - ".gitignore"
51
+ - ".travis.yml"
47
52
  - Gemfile
48
53
  - LICENSE
49
54
  - README.md
@@ -101,31 +106,29 @@ files:
101
106
  - test/xml_security_test.rb
102
107
  homepage: http://github.com/onelogin/ruby-saml
103
108
  licenses: []
104
-
105
109
  metadata: {}
106
-
107
110
  post_install_message:
108
- rdoc_options:
109
- - --charset=UTF-8
110
- require_paths:
111
+ rdoc_options:
112
+ - "--charset=UTF-8"
113
+ require_paths:
111
114
  - lib
112
- required_ruby_version: !ruby/object:Gem::Requirement
113
- requirements:
114
- - &id003
115
- - ">="
116
- - !ruby/object:Gem::Version
117
- version: "0"
118
- required_rubygems_version: !ruby/object:Gem::Requirement
119
- requirements:
120
- - *id003
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
121
125
  requirements: []
122
-
123
126
  rubyforge_project: http://www.rubygems.org/gems/ruby-saml
124
- rubygems_version: 2.7.7
127
+ rubygems_version: 2.5.2.1
125
128
  signing_key:
126
129
  specification_version: 4
127
130
  summary: SAML Ruby Tookit
128
- test_files:
131
+ test_files:
129
132
  - test/certificates/certificate1
130
133
  - test/certificates/r1_certificate2_base64
131
134
  - test/logoutrequest_test.rb