devise_saml_authenticatable 1.3.2 → 1.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 269c0505d92b49c3b9a79d1b8aece87533018b10
4
- data.tar.gz: 259f7e012808aabe3ab06e854a01deab8959843a
3
+ metadata.gz: 9a26db022c02d24566654e1d965c374a0e3b3380
4
+ data.tar.gz: 1341712900741f3c7326ddb7f099468bbc1d1066
5
5
  SHA512:
6
- metadata.gz: 83a89cbe087accbcf239e047027188a35793c9cdcb3198fd207edeb95652bb6e8957ef8e0aeaa9b919f01cbb91677bf4c5ade49fae0a85b86cf95edc4b09592b
7
- data.tar.gz: 230f5490186a0853cd63f401b390afa29129b8f103de04cbb64a734274edd88de9467030784122cccdc743fbd5eb7babf75ad3635be5b51d2a5af467d4e17b1f
6
+ metadata.gz: 9ee3d6d7075cccdb05b87c8cea6e7f9feab58d3f2a0ae4fc1cbc9d6e679b82d1c59e675195c520867903808070cc8e9fb49ff99028b7816f039e029f0d455a6a
7
+ data.tar.gz: 9ea8211cda495a8347e5e2672214e5fc8448e232ca1d961645dde9f22b18eaf9bd6bcf8e6876dea110cbe2292a8d01fdc303039629cbe781f3901a15ab73efc8
@@ -32,6 +32,10 @@ matrix:
32
32
  - rvm: "2.1.10"
33
33
  gemfile: spec/support/Gemfile.ruby-saml-1.3
34
34
 
35
+ before_install:
36
+ # update bundler to avoid https://github.com/travis-ci/travis-ci/issues/5239
37
+ - gem install bundler
38
+
35
39
  script:
36
40
  - bundle exec rake
37
41
 
data/README.md CHANGED
@@ -69,8 +69,9 @@ In `config/initializers/devise.rb`:
69
69
  # and implements a #handle method. This method can then redirect the user, return error messages, etc.
70
70
  # config.saml_failed_callback = nil
71
71
 
72
- # Configure with your SAML settings (see [ruby-saml][] for more information).
72
+ # Configure with your SAML settings (see ruby-saml's README for more information: https://github.com/onelogin/ruby-saml).
73
73
  config.saml_configure do |settings|
74
+ # assertion_consumer_service_url is required starting with ruby-saml 1.4.3: https://github.com/onelogin/ruby-saml#updating-from-142-to-143
74
75
  settings.assertion_consumer_service_url = "http://localhost:3000/users/saml/auth"
75
76
  settings.assertion_consumer_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
76
77
  settings.name_identifier_format = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
@@ -159,6 +160,7 @@ class IdPSettingsAdapter
159
160
  end
160
161
  end
161
162
  ```
163
+ Settings specified in the adapter will override settings in `config/initializers/devise.rb`. This is useful for establishing common settings or defaults across all IdPs.
162
164
 
163
165
  Detecting the entity ID passed to the `settings` method is done by `config.idp_entity_id_reader`.
164
166
 
@@ -192,10 +194,12 @@ Logout requests from the IDP are supported by the `idp_sign_out` endpoint. Dire
192
194
 
193
195
  `saml_session_index_key` must be configured to support this feature.
194
196
 
195
- ## Signing and Encrypting Authentication Requests
197
+ ## Signing and Encrypting Authentication Requests and Assertions
196
198
 
197
199
  ruby-saml 1.0.0 supports signature and decrypt. The only requirement is to set the public certificate and the private key. For more information, see [the ruby-saml documentation](https://github.com/onelogin/ruby-saml#signing).
198
200
 
201
+ If you have multiple IdPs, the certificate and private key must be in the shared settings in `config/initializers/devise.rb`.
202
+
199
203
  ## Thanks
200
204
 
201
205
  The continued maintenance of this gem could not have been possible without the hard work of [Adam Stegman](https://github.com/adamstegman) and [Mitch Lindsay](https://github.com/mitch-lindsay). Thank you guys for keeping this project alive.
@@ -53,8 +53,9 @@ class Devise::SamlSessionsController < Devise::SessionsController
53
53
 
54
54
  # Override devise to send user to IdP logout for SLO
55
55
  def after_sign_out_path_for(_)
56
+ idp_entity_id = get_idp_entity_id(params)
56
57
  request = OneLogin::RubySaml::Logoutrequest.new
57
- request.create(saml_config)
58
+ request.create(saml_config(idp_entity_id))
58
59
  end
59
60
 
60
61
  def generate_idp_logout_response(saml_config, logout_request_id)
@@ -7,6 +7,7 @@ Gem::Specification.new do |gem|
7
7
  gem.description = %q{SAML Authentication for devise}
8
8
  gem.summary = %q{SAML Authentication for devise }
9
9
  gem.homepage = ""
10
+ gem.license = "MIT"
10
11
 
11
12
  gem.files = `git ls-files`.split($\)
12
13
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -94,7 +94,7 @@ module Devise
94
94
  end
95
95
 
96
96
  # Proc that is called if Devise.saml_update_user and/or Devise.saml_create_user are true.
97
- # Recieves the user object, saml_response and auth_value, and defines how the object's values are
97
+ # Receives the user object, saml_response and auth_value, and defines how the object's values are
98
98
  # updated with regards to the SAML response. See saml_default_update_resource_hook for an example.
99
99
  mattr_accessor :saml_update_resource_hook
100
100
  @@saml_update_resource_hook = @@saml_default_update_resource_hook
@@ -107,7 +107,7 @@ module Devise
107
107
  end
108
108
 
109
109
  # Proc that is called to resolve the saml_response and auth_value into the correct user object.
110
- # Recieves a copy of the ActiveRecord::Model, saml_response and auth_value. Is expected to return
110
+ # Receives a copy of the ActiveRecord::Model, saml_response and auth_value. Is expected to return
111
111
  # one instance of the provided model that is the matched account, or nil if none exists.
112
112
  # See saml_default_resource_locator above for an example.
113
113
  mattr_accessor :saml_resource_locator
@@ -4,11 +4,13 @@ module DeviseSamlAuthenticatable
4
4
  if params[:SAMLRequest]
5
5
  OneLogin::RubySaml::SloLogoutrequest.new(
6
6
  params[:SAMLRequest],
7
+ settings: Devise.saml_config,
7
8
  allowed_clock_drift: Devise.allowed_clock_drift_in_seconds,
8
9
  ).issuer
9
10
  elsif params[:SAMLResponse]
10
11
  OneLogin::RubySaml::Response.new(
11
12
  params[:SAMLResponse],
13
+ settings: Devise.saml_config,
12
14
  allowed_clock_drift: Devise.allowed_clock_drift_in_seconds,
13
15
  ).issuers.first
14
16
  end
@@ -8,6 +8,7 @@ module Devise
8
8
  if params[:SAMLResponse]
9
9
  OneLogin::RubySaml::Response.new(
10
10
  params[:SAMLResponse],
11
+ settings: Devise.saml_config,
11
12
  allowed_clock_drift: Devise.allowed_clock_drift_in_seconds,
12
13
  )
13
14
  else
@@ -1,3 +1,3 @@
1
1
  module DeviseSamlAuthenticatable
2
- VERSION = "1.3.2"
2
+ VERSION = "1.4.0"
3
3
  end
@@ -66,6 +66,7 @@ describe Devise::SamlSessionsController, type: :controller do
66
66
  it "uses the DefaultIdpEntityIdReader" do
67
67
  expect(DeviseSamlAuthenticatable::DefaultIdpEntityIdReader).to receive(:entity_id)
68
68
  do_get
69
+ expect(idp_providers_adapter).to have_received(:settings).with(nil)
69
70
  end
70
71
 
71
72
  context "with a relay_state lambda defined" do
@@ -104,6 +105,7 @@ describe Devise::SamlSessionsController, type: :controller do
104
105
 
105
106
  it "redirects to the associated IdP SSO target url" do
106
107
  do_get
108
+ expect(idp_providers_adapter).to have_received(:settings).with("http://www.example.com")
107
109
  expect(response).to redirect_to(%r(\Ahttp://idp_sso_url\?SAMLRequest=))
108
110
  end
109
111
  end
@@ -147,10 +149,57 @@ describe Devise::SamlSessionsController, type: :controller do
147
149
  end
148
150
 
149
151
  describe '#destroy' do
150
- it 'signs out and redirects to the IdP' do
151
- expect(controller).to receive(:sign_out)
152
- delete :destroy
153
- expect(response).to redirect_to(%r(\Ahttp://localhost:8009/saml/logout\?SAMLRequest=))
152
+ context "when using the default saml config" do
153
+ it 'signs out and redirects to the IdP' do
154
+ expect(controller).to receive(:sign_out)
155
+ delete :destroy
156
+ expect(response).to redirect_to(%r(\Ahttp://localhost:8009/saml/logout\?SAMLRequest=))
157
+ end
158
+ end
159
+
160
+ context "with a specified idp" do
161
+ before do
162
+ Devise.idp_settings_adapter = idp_providers_adapter
163
+ end
164
+
165
+ it "redirects to the associated IdP SSO target url" do
166
+ expect(controller).to receive(:sign_out)
167
+ expect(DeviseSamlAuthenticatable::DefaultIdpEntityIdReader).to receive(:entity_id)
168
+ delete :destroy
169
+ expect(response).to redirect_to(%r(\Ahttp://idp_slo_url\?SAMLRequest=))
170
+ end
171
+
172
+ context "with a specified idp entity id reader" do
173
+ class OurIdpEntityIdReader
174
+ def self.entity_id(params)
175
+ params[:entity_id]
176
+ end
177
+ end
178
+
179
+ subject(:do_delete) {
180
+ if Rails::VERSION::MAJOR > 4
181
+ delete :destroy, params: {entity_id: "http://www.example.com"}
182
+ else
183
+ delete :destroy, entity_id: "http://www.example.com"
184
+ end
185
+ }
186
+
187
+ before do
188
+ @default_reader = Devise.idp_entity_id_reader
189
+ Devise.idp_entity_id_reader = OurIdpEntityIdReader # which will have some different behavior
190
+ end
191
+
192
+ after do
193
+ Devise.idp_entity_id_reader = @default_reader
194
+ end
195
+
196
+ it "redirects to the associated IdP SLO target url" do
197
+ expect(controller).to receive(:sign_out)
198
+ do_delete
199
+ expect(idp_providers_adapter).to have_received(:settings).with("http://www.example.com")
200
+ expect(response).to redirect_to(%r(\Ahttp://idp_slo_url\?SAMLRequest=))
201
+ end
202
+ end
154
203
  end
155
204
  end
156
205
 
@@ -138,7 +138,6 @@ describe "SAML Authentication", type: :feature do
138
138
  end
139
139
 
140
140
  context "when the idp_settings_adapter key is set" do
141
-
142
141
  before(:each) do
143
142
  create_app('idp', 'INCLUDE_SUBJECT_IN_ATTRIBUTES' => "false")
144
143
  create_app('sp', 'USE_SUBJECT_TO_AUTHENTICATE' => "true", 'IDP_SETTINGS_ADAPTER' => "IdpSettingsAdapter", 'IDP_ENTITY_ID_READER' => "OurEntityIdReader")
@@ -156,7 +155,24 @@ describe "SAML Authentication", type: :feature do
156
155
  create_user("you@example.com")
157
156
 
158
157
  visit 'http://localhost:8020/users/saml/sign_in/?entity_id=http%3A%2F%2Flocalhost%3A8020%2Fsaml%2Fmetadata'
159
- expect(current_url).to match(%r(\Ahttp://www.example.com/\?SAMLRequest=))
158
+ expect(current_url).to match(%r(\Ahttp://www.example.com/sso\?SAMLRequest=))
159
+ end
160
+
161
+ it "logs a user out of the IdP via the SP" do
162
+ sign_in
163
+
164
+ # prove user is still signed in
165
+ visit 'http://localhost:8020/'
166
+ expect(page).to have_content("you@example.com")
167
+ expect(current_url).to eq("http://localhost:8020/")
168
+
169
+ click_on "Log out"
170
+ #confirm the logout response redirected to the SP which in turn attempted to sign th e
171
+ expect(current_url).to match(%r(\Ahttp://www.example.com/slo\?SAMLRequest=))
172
+
173
+ # prove user is now signed out
174
+ visit 'http://localhost:8020/users/saml/sign_in/?entity_id=http%3A%2F%2Flocalhost%3A8020%2Fsaml%2Fmetadata'
175
+ expect(current_url).to match(%r(\Ahttp://www.example.com/sso\?SAMLRequest=))
160
176
  end
161
177
  end
162
178
 
@@ -4,7 +4,6 @@ source 'https://rubygems.org'
4
4
  gemspec path: '../..'
5
5
 
6
6
  group :test do
7
- gem 'rake'
8
7
  gem 'rspec', '~> 3.0'
9
8
  gem 'rails', '~> 4.0'
10
9
  gem 'rspec-rails'
@@ -16,7 +15,15 @@ group :test do
16
15
  if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new("2.0")
17
16
  gem 'addressable', '~> 2.4.0'
18
17
  gem 'mime-types', '~> 2.99'
18
+ gem 'public_suffix', '~> 1.4.6'
19
+ gem 'rake', '~> 12.2.0'
20
+ elsif Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new("2.1")
21
+ gem 'public_suffix', '~> 2.0.5'
22
+ gem 'rake'
23
+ else
24
+ gem 'rake'
19
25
  end
26
+
20
27
  if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new("2.1")
21
28
  gem 'devise', '~> 3.5'
22
29
  gem 'nokogiri', '~> 1.6.8'
@@ -14,11 +14,9 @@ group :test do
14
14
  gem 'poltergeist'
15
15
 
16
16
  # Lock down versions of gems for older versions of Ruby
17
- if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new("2.0")
18
- gem 'mime-types', '~> 2.99'
19
- end
20
17
  if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new("2.1")
21
18
  gem 'devise', '~> 3.5'
19
+ gem 'public_suffix', '~> 2.0.5'
22
20
  gem 'nokogiri', '~> 1.6.8'
23
21
  end
24
22
  end
@@ -8,8 +8,8 @@ class IdpSettingsAdapter
8
8
  issuer: "sp_issuer",
9
9
  idp_entity_id: "http://localhost:8020/saml/metadata",
10
10
  authn_context: "",
11
- idp_slo_target_url: "http://www.example.com",
12
- idp_sso_target_url: "http://www.example.com",
11
+ idp_slo_target_url: "http://www.example.com/slo",
12
+ idp_sso_target_url: "http://www.example.com/sso",
13
13
  idp_cert: "idp_cert"
14
14
  }
15
15
  else
@@ -68,7 +68,7 @@ after_bundle do
68
68
  insert_into_file('app/views/home/index.html.erb', after: /\z/) {
69
69
  <<-HOME
70
70
  <%= current_user.email %> <%= current_user.name %>
71
- <%= form_tag destroy_user_session_path, method: :delete do %>
71
+ <%= form_tag destroy_user_session_path(entity_id: "http://localhost:8020/saml/metadata"), method: :delete do %>
72
72
  <%= submit_tag "Log out" %>
73
73
  <% end %>
74
74
  HOME
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise_saml_authenticatable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josef Sauter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-22 00:00:00.000000000 Z
11
+ date: 2018-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: devise
@@ -85,7 +85,8 @@ files:
85
85
  - spec/support/saml_idp_controller.rb.erb
86
86
  - spec/support/sp_template.rb
87
87
  homepage: ''
88
- licenses: []
88
+ licenses:
89
+ - MIT
89
90
  metadata: {}
90
91
  post_install_message:
91
92
  rdoc_options: []