devise_saml_authenticatable 1.2.1 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.rspec +1 -0
- data/.travis.yml +1 -1
- data/Gemfile +1 -2
- data/README.md +2 -2
- data/app/controllers/devise/saml_sessions_controller.rb +6 -8
- data/lib/devise_saml_authenticatable/model.rb +4 -2
- data/lib/devise_saml_authenticatable/saml_config.rb +3 -1
- data/lib/devise_saml_authenticatable/strategy.rb +3 -3
- data/lib/devise_saml_authenticatable/version.rb +1 -1
- data/spec/devise_saml_authenticatable/saml_config_spec.rb +1 -1
- data/spec/devise_saml_authenticatable/strategy_spec.rb +1 -1
- data/spec/features/saml_authentication_spec.rb +38 -5
- data/spec/rails_helper.rb +2 -2
- data/spec/support/idp_template.rb +2 -2
- data/spec/support/rails_app.rb +2 -13
- data/spec/support/sp_template.rb +3 -2
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
MDY1NTJiZTA4NjhlOTc2YmM2ZjlhYWMxNDcyMDNiMzUxMTBiNTBkNA==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d2e501ba6f2facaaa55601864a66fbf5799f2b93
|
4
|
+
data.tar.gz: 644a41f1ef4dafdac806600b8a5646e3a00acbf6
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
NjMwMTg4YWVhMDQyM2NhNWVkYzNiY2JmYWViNzY5ZWJjN2FkMzk2ZGExNzlh
|
11
|
-
ZGMzNzU0NWU2MDZiZjM5MTMxNTNkZjA1MGUxZTgwOTljYTNhODE=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
ZDYzODA0NzBlMWFmMjNhMjZmNzE4ZjBmMDllYzkyMzM3YWYxOGY4NTNiMTEy
|
14
|
-
ZTJhYjZmYTg4MDY5MDAyZmVmYzkzYWMzNjY0YzRkZGQxMzZlOWJkMzkwMzQx
|
15
|
-
NDYxMzAwMDU0OTE1ZTZlYWI5MTE3YzJlZjU1YzM4NjkxY2M3YmE=
|
6
|
+
metadata.gz: a4096feb553134033f04079e7c10a1ace113fc048f79dbf712ee0fe5b478ce6696ccd4434c5c05f4aecced1c55e79f13415027bfa613ca2937a216e8bb6949cd
|
7
|
+
data.tar.gz: 20c0f29acc30f4db788fa8ada4bfbff4df88421d48403f52b39cdb9876f1907be732a3641a0d9cdd7e3997f63809f71894769e8791014183a226333bedc2353e
|
data/.rspec
CHANGED
data/.travis.yml
CHANGED
@@ -11,7 +11,7 @@ script:
|
|
11
11
|
notifications:
|
12
12
|
hipchat:
|
13
13
|
rooms:
|
14
|
-
secure:
|
14
|
+
secure: cuDak5a6fBeg+sp61COqxQfzdcFEsjwCqtwvCISso0RNh5SR8v+uVYKcA8rlK+GE1l9uR7tLRHeHF3ZmzvFSOat07NvpScvjZXi+OSpWlc6rwQ6Pl6bBP6gu6sREiKVe0eT/uGrvJloyWKZaXIhiiBzQ+ZERx/ssGA9WMmNkhlwy1OgGnPNurNNHZLBjEZn1V6kdyxiXx6QPASNpjNEgN1G8dUh3qzcWUGVQGNZSJk65A6ie1MveNyecTjDhw+ADBU8nS28Ja4y6ohRm4FzofSgespYrvfygIZ5rYF0HPMj5FW1ZDWtM5355ojCk8RLT+ZkuhssCn1OJk7ogaOVjnYcOFRxEfpu3eIbjtMmUz3j4umatFqbgas+6SXMVIPkr5HUoTrP8HNFssIpcEBOnPwAF8QCpx+daHc0r2cc8lGuXhtJfpW0P2F0dmwJNiQ7//nz2y2xs84x4Gb7MV9tEDYp0FqEClMuFBkPNizBljarm04PkiLSrqvR52aMDfQz7YAX2oXAvFjPzI1GC0K8x7xX8TuHT9yuHy7fI+rUSNivZYLKO+IEZqPPDdJpXISUbVwanZoNvmQYk5PZV21MfDSGwQrz8eO/uFiAblj18yIlNbAfb2hdZDVYsm4EvWxELJtfaTxgrj6M3Y3m/KbCbCoDp+2jE307M2rxL0Gum2gk=
|
15
15
|
template:
|
16
16
|
- '%{repository}<a href="%{build_url}">#%{build_number}</a> (%{branch} - <a href="%{compare_url}">%{commit}</a> : %{author}): %{message}'
|
17
17
|
format: html
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -127,9 +127,9 @@ Logout support is included by immediately terminating the local session and then
|
|
127
127
|
Logout requests from the IDP are supported by the `idp_sign_out` end point. Directing logout requests to `users/saml/idp_sign_out` will logout the respective user by invalidating their current sessions.
|
128
128
|
`saml_session_index_key` must be configured to support this feature.
|
129
129
|
|
130
|
-
##
|
130
|
+
## Signing and Encrypting Authentication Requests
|
131
131
|
|
132
|
-
1.
|
132
|
+
ruby-saml 1.0.0 supports signature and decrypt. Teh only requirement is to place the public certificate and the private key. Please reffer to these features in the ruby-saml documentation [here](https://github.com/onelogin/ruby-saml#signing)
|
133
133
|
|
134
134
|
## Thanks
|
135
135
|
|
@@ -3,23 +3,22 @@ require "ruby-saml"
|
|
3
3
|
class Devise::SamlSessionsController < Devise::SessionsController
|
4
4
|
include DeviseSamlAuthenticatable::SamlConfig
|
5
5
|
unloadable if Rails::VERSION::MAJOR < 4
|
6
|
-
before_filter :get_saml_config
|
7
6
|
skip_before_filter :verify_authenticity_token
|
8
7
|
|
9
8
|
def new
|
10
9
|
request = OneLogin::RubySaml::Authrequest.new
|
11
|
-
action = request.create(
|
10
|
+
action = request.create(saml_config)
|
12
11
|
redirect_to action
|
13
12
|
end
|
14
|
-
|
13
|
+
|
15
14
|
def metadata
|
16
15
|
meta = OneLogin::RubySaml::Metadata.new
|
17
|
-
render :xml => meta.generate(
|
16
|
+
render :xml => meta.generate(saml_config)
|
18
17
|
end
|
19
18
|
|
20
19
|
def idp_sign_out
|
21
20
|
if params[:SAMLRequest] && Devise.saml_session_index_key
|
22
|
-
logout_request = OneLogin::RubySaml::SloLogoutrequest.new(params[:SAMLRequest], settings:
|
21
|
+
logout_request = OneLogin::RubySaml::SloLogoutrequest.new(params[:SAMLRequest], settings: saml_config)
|
23
22
|
resource_class.reset_session_key_for(logout_request.name_id)
|
24
23
|
|
25
24
|
redirect_to generate_idp_logout_response(logout_request)
|
@@ -42,12 +41,11 @@ class Devise::SamlSessionsController < Devise::SessionsController
|
|
42
41
|
# Override devise to send user to IdP logout for SLO
|
43
42
|
def after_sign_out_path_for(_)
|
44
43
|
request = OneLogin::RubySaml::Logoutrequest.new
|
45
|
-
request.create(
|
44
|
+
request.create(saml_config)
|
46
45
|
end
|
47
46
|
|
48
47
|
def generate_idp_logout_response(logout_request)
|
49
48
|
logout_request_id = logout_request.id
|
50
|
-
OneLogin::RubySaml::SloLogoutresponse.new.create(
|
49
|
+
OneLogin::RubySaml::SloLogoutresponse.new.create(saml_config, logout_request_id, nil)
|
51
50
|
end
|
52
51
|
end
|
53
|
-
|
@@ -25,13 +25,15 @@ module Devise
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def after_saml_authentication(session_index)
|
28
|
-
if self.respond_to?
|
28
|
+
if Devise.saml_session_index_key && self.respond_to?(Devise.saml_session_index_key)
|
29
29
|
self.update_attribute(Devise.saml_session_index_key, session_index)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
33
|
def authenticatable_salt
|
34
|
-
if
|
34
|
+
if Devise.saml_session_index_key &&
|
35
|
+
self.respond_to?(Devise.saml_session_index_key) &&
|
36
|
+
self.send(Devise.saml_session_index_key).present?
|
35
37
|
self.send(Devise.saml_session_index_key)
|
36
38
|
else
|
37
39
|
super
|
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'ruby-saml'
|
2
2
|
module DeviseSamlAuthenticatable
|
3
3
|
module SamlConfig
|
4
|
-
def
|
4
|
+
def saml_config
|
5
|
+
return @saml_config if @saml_config
|
6
|
+
|
5
7
|
idp_config_path = "#{Rails.root}/config/idp.yml"
|
6
8
|
# Support 0.0.x-style configuration via a YAML file
|
7
9
|
if File.exists?(idp_config_path)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'devise/strategies/authenticatable'
|
1
|
+
require 'devise/strategies/authenticatable'
|
2
2
|
|
3
3
|
module Devise
|
4
4
|
module Strategies
|
@@ -6,7 +6,7 @@ module Devise
|
|
6
6
|
include DeviseSamlAuthenticatable::SamlConfig
|
7
7
|
def valid?
|
8
8
|
if params[:SAMLResponse]
|
9
|
-
response = OneLogin::RubySaml::Logoutresponse.new(params[:SAMLResponse],
|
9
|
+
response = OneLogin::RubySaml::Logoutresponse.new(params[:SAMLResponse], saml_config)
|
10
10
|
!(response.response.include? 'LogoutResponse')
|
11
11
|
else
|
12
12
|
false
|
@@ -14,7 +14,7 @@ module Devise
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def authenticate!
|
17
|
-
@response = OneLogin::RubySaml::Response.new(params[:SAMLResponse], settings:
|
17
|
+
@response = OneLogin::RubySaml::Response.new(params[:SAMLResponse], settings: saml_config)
|
18
18
|
resource = mapping.to.authenticate_with_saml(@response)
|
19
19
|
if @response.is_valid? && resource
|
20
20
|
resource.after_saml_authentication(@response.sessionindex)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe DeviseSamlAuthenticatable::SamlConfig do
|
4
|
-
subject(:saml_config) { controller.
|
4
|
+
subject(:saml_config) { controller.saml_config }
|
5
5
|
let(:controller) { Class.new { include DeviseSamlAuthenticatable::SamlConfig }.new }
|
6
6
|
|
7
7
|
# Replace global config since this test changes it
|
@@ -11,7 +11,7 @@ describe Devise::Strategies::SamlAuthenticatable do
|
|
11
11
|
|
12
12
|
let(:saml_config) { OneLogin::RubySaml::Settings.new }
|
13
13
|
before do
|
14
|
-
allow(strategy).to receive(:
|
14
|
+
allow(strategy).to receive(:saml_config).and_return(saml_config)
|
15
15
|
end
|
16
16
|
|
17
17
|
let(:mapping) { double(:mapping, to: user_class) }
|
@@ -63,8 +63,10 @@ describe "SAML Authentication", type: :feature do
|
|
63
63
|
visit 'http://localhost:8020/'
|
64
64
|
expect(current_url).to match(%r(\Ahttp://localhost:8009/saml/auth\?SAMLRequest=))
|
65
65
|
end
|
66
|
+
end
|
66
67
|
|
67
|
-
|
68
|
+
shared_examples_for "it logs a user out via the IdP" do
|
69
|
+
it 'logs a user out of the SP via the IdP' do
|
68
70
|
sign_in
|
69
71
|
|
70
72
|
visit "http://localhost:#{idp_port}/saml/sp_sign_out"
|
@@ -76,8 +78,8 @@ describe "SAML Authentication", type: :feature do
|
|
76
78
|
|
77
79
|
context "when the attributes are used to authenticate" do
|
78
80
|
before(:each) do
|
79
|
-
create_app('idp',
|
80
|
-
create_app('sp',
|
81
|
+
create_app('idp', 'INCLUDE_SUBJECT_IN_ATTRIBUTES' => "true")
|
82
|
+
create_app('sp', 'USE_SUBJECT_TO_AUTHENTICATE' => "false")
|
81
83
|
@idp_pid = start_app('idp', idp_port)
|
82
84
|
@sp_pid = start_app('sp', sp_port)
|
83
85
|
end
|
@@ -91,8 +93,39 @@ describe "SAML Authentication", type: :feature do
|
|
91
93
|
|
92
94
|
context "when the subject is used to authenticate" do
|
93
95
|
before(:each) do
|
94
|
-
create_app('idp',
|
95
|
-
create_app('sp',
|
96
|
+
create_app('idp', 'INCLUDE_SUBJECT_IN_ATTRIBUTES' => "false")
|
97
|
+
create_app('sp', 'USE_SUBJECT_TO_AUTHENTICATE' => "true")
|
98
|
+
@idp_pid = start_app('idp', idp_port)
|
99
|
+
@sp_pid = start_app('sp', sp_port)
|
100
|
+
end
|
101
|
+
after(:each) do
|
102
|
+
stop_app(@idp_pid)
|
103
|
+
stop_app(@sp_pid)
|
104
|
+
end
|
105
|
+
|
106
|
+
it_behaves_like "it authenticates and creates users"
|
107
|
+
end
|
108
|
+
|
109
|
+
context "when the session index key is set" do
|
110
|
+
before(:each) do
|
111
|
+
create_app('idp', 'INCLUDE_SUBJECT_IN_ATTRIBUTES' => "false")
|
112
|
+
create_app('sp', 'USE_SUBJECT_TO_AUTHENTICATE' => "true", 'SAML_SESSION_INDEX_KEY' => ":session_index")
|
113
|
+
@idp_pid = start_app('idp', idp_port)
|
114
|
+
@sp_pid = start_app('sp', sp_port)
|
115
|
+
end
|
116
|
+
after(:each) do
|
117
|
+
stop_app(@idp_pid)
|
118
|
+
stop_app(@sp_pid)
|
119
|
+
end
|
120
|
+
|
121
|
+
it_behaves_like "it authenticates and creates users"
|
122
|
+
it_behaves_like "it logs a user out via the IdP"
|
123
|
+
end
|
124
|
+
|
125
|
+
context "when the session index key is not set" do
|
126
|
+
before(:each) do
|
127
|
+
create_app('idp', 'INCLUDE_SUBJECT_IN_ATTRIBUTES' => "false")
|
128
|
+
create_app('sp', 'USE_SUBJECT_TO_AUTHENTICATE' => "true", 'SAML_SESSION_INDEX_KEY' => "nil")
|
96
129
|
@idp_pid = start_app('idp', idp_port)
|
97
130
|
@sp_pid = start_app('sp', sp_port)
|
98
131
|
end
|
data/spec/rails_helper.rb
CHANGED
@@ -2,7 +2,7 @@ ENV["RAILS_ENV"] ||= 'test'
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
create_app('sp',
|
5
|
+
create_app('sp', 'USE_SUBJECT_TO_AUTHENTICATE' => "false")
|
6
6
|
require 'support/sp/config/environment'
|
7
7
|
require 'rspec/rails'
|
8
8
|
|
@@ -17,4 +17,4 @@ end
|
|
17
17
|
Devise.setup do |config|
|
18
18
|
config.saml_default_user_key = :email
|
19
19
|
config.saml_session_index_key = :session_index
|
20
|
-
end
|
20
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# Set up a SAML IdP
|
2
2
|
|
3
|
-
@include_subject_in_attributes =
|
3
|
+
@include_subject_in_attributes = ENV.fetch('INCLUDE_SUBJECT_IN_ATTRIBUTES')
|
4
4
|
|
5
5
|
gem 'ruby-saml-idp'
|
6
6
|
gem 'thin'
|
@@ -18,4 +18,4 @@ gsub_file 'config/application.rb', /end[\n\w]*end$/, <<-CONFIG
|
|
18
18
|
config.slo_sp_url = "http://localhost:8020/users/saml/idp_sign_out"
|
19
19
|
end
|
20
20
|
end
|
21
|
-
CONFIG
|
21
|
+
CONFIG
|
data/spec/support/rails_app.rb
CHANGED
@@ -11,24 +11,13 @@ def app_ready?(pid, port)
|
|
11
11
|
system("lsof -i:#{port}", out: '/dev/null')
|
12
12
|
end
|
13
13
|
|
14
|
-
def create_app(name,
|
14
|
+
def create_app(name, env = {})
|
15
15
|
rails_new_options = %w(-T -J -S --skip-spring)
|
16
16
|
rails_new_options << "-O" if name == 'idp'
|
17
17
|
Bundler.with_clean_env do
|
18
18
|
Dir.chdir(File.expand_path('../../support', __FILE__)) do
|
19
19
|
FileUtils.rm_rf(name)
|
20
|
-
|
21
|
-
while answers.any?
|
22
|
-
question = stdout.gets
|
23
|
-
answer = answers.shift
|
24
|
-
stdin.puts answer
|
25
|
-
$stdout.puts "#{question} #{answer}"
|
26
|
-
end
|
27
|
-
wait_thread.join
|
28
|
-
|
29
|
-
$stdout.puts stdout.read
|
30
|
-
$stderr.puts stderr.read
|
31
|
-
end
|
20
|
+
system(env, "rails", "new", name, *rails_new_options, "-m", "#{name}_template.rb")
|
32
21
|
end
|
33
22
|
end
|
34
23
|
end
|
data/spec/support/sp_template.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Set up a SAML Service Provider
|
2
2
|
|
3
|
-
|
3
|
+
saml_session_index_key = ENV.fetch('SAML_SESSION_INDEX_KEY', ":session_index")
|
4
|
+
use_subject_to_authenticate = ENV.fetch('USE_SUBJECT_TO_AUTHENTICATE')
|
4
5
|
|
5
6
|
gem 'devise_saml_authenticatable', path: '../../..'
|
6
7
|
gem 'thin'
|
@@ -32,7 +33,7 @@ after_bundle do
|
|
32
33
|
generate 'devise:install'
|
33
34
|
gsub_file 'config/initializers/devise.rb', /^end$/, <<-CONFIG
|
34
35
|
config.saml_default_user_key = :email
|
35
|
-
config.saml_session_index_key =
|
36
|
+
config.saml_session_index_key = #{saml_session_index_key}
|
36
37
|
|
37
38
|
config.saml_use_subject = #{use_subject_to_authenticate}
|
38
39
|
config.saml_create_user = true
|
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise_saml_authenticatable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josef Sauter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: devise
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 2.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 2.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: ruby-saml
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.0'
|
41
41
|
description: SAML Authentication for devise
|
@@ -45,9 +45,9 @@ executables: []
|
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
|
-
- .gitignore
|
49
|
-
- .rspec
|
50
|
-
- .travis.yml
|
48
|
+
- ".gitignore"
|
49
|
+
- ".rspec"
|
50
|
+
- ".travis.yml"
|
51
51
|
- Gemfile
|
52
52
|
- LICENSE
|
53
53
|
- README.md
|
@@ -84,12 +84,12 @@ require_paths:
|
|
84
84
|
- lib
|
85
85
|
required_ruby_version: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
91
|
requirements:
|
92
|
-
- -
|
92
|
+
- - ">="
|
93
93
|
- !ruby/object:Gem::Version
|
94
94
|
version: '0'
|
95
95
|
requirements: []
|