ruby-saml 0.8.8 → 0.8.9

Sign up to get free protection for your applications and to get access to all the features.

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