omniauth-multi-provider-saml 0.1.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 +7 -0
- data/README.md +88 -0
- data/lib/omniauth-multi-provider-saml.rb +18 -0
- data/lib/omniauth/saml/multi_provider/handler.rb +84 -0
- data/lib/omniauth/saml/multi_provider/version.rb +7 -0
- metadata +118 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b88dcbe4376a25239e1c08ecec6bf330caaa7245
|
4
|
+
data.tar.gz: e17b2e7949d80d1f7228172d6874e3d4d2f48d53
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 654e98112ec38319203941522c5c0db8a2d37bf1157cb540da7925e9bb03acfb6f1e670d5c42fcf878b4cc8a525632418995c402720f39d27c42726e4c7ffca4
|
7
|
+
data.tar.gz: 9c390eddac7e7c6334e1324158e746ea129f464a8ede1faae610af3b92c832e5cf849b07b5298b442937e7d70e6a96960d95cd13752a99eb2f2c41cbd8de613f
|
data/README.md
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# Omniauth Multiple Provider SAML
|
2
|
+
|
3
|
+
This is a simple extension to [omniauth-saml](https://github.com/PracticallyGreen/omniauth-saml) for supporting multiple identity providers based on a URL path segment e.g. dispatching requests to `/auth/saml/foo` to identity provider "foo" and `/app/saml/bar` to identity provider "bar".
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'omniauth-multi-provider-saml', github: 'salsify/omniauth-multi-provider-saml'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
## Setup
|
18
|
+
|
19
|
+
**I would highly recommend first getting [omniauth-saml](https://github.com/PracticallyGreen/omniauth-saml) setup to work with a single identity provider before attempting to use this gem.**
|
20
|
+
|
21
|
+
The setup process consists of the following steps:
|
22
|
+
|
23
|
+
1. Add an omniauth-saml monkey patch for omniauth-saml PR [#56](https://github.com/PracticallyGreen/omniauth-saml/pull/56).
|
24
|
+
1. Configure your routes to handle SAML routes for multiple identity providers
|
25
|
+
1. Configure omniauth-saml to choose the appropriate identity provider
|
26
|
+
|
27
|
+
### Monkey Patch omniauth-saml
|
28
|
+
|
29
|
+
This step will only be necessary until omniauth-saml PR [#56](https://github.com/PracticallyGreen/omniauth-saml/pull/56) merges. Place the following in an initializer:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
require 'omniauth-saml'
|
33
|
+
|
34
|
+
OmniAuth::Strategies::SAML.class_eval do
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def initialize_copy(orig)
|
39
|
+
super
|
40
|
+
@options = @options.deep_dup
|
41
|
+
end
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
### Configure SAML Routes
|
46
|
+
|
47
|
+
Add something like the following to your routes assuming you're using Rails (your actual URL structure may vary):
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
MyApplication::Application.routes.draw do
|
51
|
+
match '/auth/saml/:identity_provider_id/callback',
|
52
|
+
via: [:get, :post],
|
53
|
+
to: 'omniauth_callbacks#saml',
|
54
|
+
as: 'user_omniauth_callback'
|
55
|
+
|
56
|
+
match '/auth/saml/:identity_provider_id',
|
57
|
+
via: [:get, :post],
|
58
|
+
to: 'omniauth_callbacks#passthru',
|
59
|
+
as: 'user_omniauth_authorize'
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
### Configure omniauth-saml to use multiple identity providers
|
64
|
+
|
65
|
+
The basic configuration looks something like this:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
Rails.application.config.middleware.use OmniAuth::Builder do
|
69
|
+
OmniAuth::SAML::MultiProvider.register(self, issuer: 'Salsify') do |identity_provider_id, rack_env|
|
70
|
+
# Customize this code to return the appropriate SAML options for the given identity provider
|
71
|
+
# See omniauth-saml for details on the supported options
|
72
|
+
identity_provider = IdentityProvider.find_by!(uuid: identity_provider_id)
|
73
|
+
identity_provider.options
|
74
|
+
end
|
75
|
+
end
|
76
|
+
```
|
77
|
+
The `OmniAuth::SAML::MultiProvider.register` method takes a hash of static omniauth-saml options and a block to generate any request specific options. It also takes the following options:
|
78
|
+
* `identity_provider_id_regex` - The regex for a valid identity provider id. Defaults to `/\w+/`
|
79
|
+
|
80
|
+
## Contributing
|
81
|
+
|
82
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/salsify/omniauth-multi-provider-saml.
|
83
|
+
|
84
|
+
|
85
|
+
## License
|
86
|
+
|
87
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
88
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'omniauth/saml/multi_provider/handler'
|
2
|
+
require 'omniauth/saml/multi_provider/version'
|
3
|
+
|
4
|
+
module OmniAuth
|
5
|
+
module SAML
|
6
|
+
module MultiProvider
|
7
|
+
def self.register(builder, path_prefix: OmniAuth.config.path_prefix,
|
8
|
+
identity_provider_id_regex: /\w+/, **options, &dynamic_options_generator)
|
9
|
+
|
10
|
+
handler = OmniAuth::SAML::MultiProvider::Handler.new(path_prefix: path_prefix,
|
11
|
+
identity_provider_id_regex: identity_provider_id_regex,
|
12
|
+
&dynamic_options_generator)
|
13
|
+
static_options = options.merge(path_prefix: path_prefix)
|
14
|
+
builder.provider(:saml, static_options.merge(handler.provider_options))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'omniauth'
|
2
|
+
require 'omniauth-saml'
|
3
|
+
|
4
|
+
module OmniAuth
|
5
|
+
module SAML
|
6
|
+
module MultiProvider
|
7
|
+
class Handler
|
8
|
+
attr_reader :path_prefix, :identity_provider_id_regex
|
9
|
+
|
10
|
+
def initialize(path_prefix: OmniAuth.config.path_prefix,
|
11
|
+
identity_provider_id_regex: /\w+/, &identity_provider_options_generator)
|
12
|
+
raise 'Missing provider options generator block' unless block_given?
|
13
|
+
|
14
|
+
@path_prefix = path_prefix
|
15
|
+
@identity_provider_id_regex = identity_provider_id_regex
|
16
|
+
@identity_provider_options_generator = identity_provider_options_generator
|
17
|
+
|
18
|
+
# Eagerly compute these since lazy evaluation will not be threadsafe
|
19
|
+
@provider_path_prefix = "#{@path_prefix}/saml"
|
20
|
+
@saml_path_regex = /^#{@provider_path_prefix}\/(?<identity_provider_id>#{@identity_provider_id_regex})/
|
21
|
+
@request_path_regex = /#{saml_path_regex}\/?$/
|
22
|
+
@callback_path_regex = /#{saml_path_regex}\/callback\/?$/
|
23
|
+
end
|
24
|
+
|
25
|
+
def provider_options
|
26
|
+
{
|
27
|
+
request_path: method(:request_path?),
|
28
|
+
callback_path: method(:callback_path?),
|
29
|
+
setup: method(:setup)
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
attr_reader :provider_path_prefix, :saml_path_regex, :request_path_regex, :callback_path_regex,
|
36
|
+
:identity_provider_options_generator
|
37
|
+
|
38
|
+
def setup(env)
|
39
|
+
identity_provider_id = extract_identity_provider_id(env)
|
40
|
+
if identity_provider_id
|
41
|
+
strategy = env['omniauth.strategy']
|
42
|
+
add_path_options(strategy, identity_provider_id)
|
43
|
+
add_identity_provider_options(strategy, env, identity_provider_id)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_path_options(strategy, identity_provider_id)
|
48
|
+
strategy.options.merge!(
|
49
|
+
request_path: "#{provider_path_prefix}/#{identity_provider_id}",
|
50
|
+
callback_path: "#{provider_path_prefix}/#{identity_provider_id}/callback"
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
def add_identity_provider_options(strategy, env, identity_provider_id)
|
55
|
+
identity_provider_options = identity_provider_options_generator.call(identity_provider_id, env) || {}
|
56
|
+
strategy.options.merge!(identity_provider_options)
|
57
|
+
rescue => e
|
58
|
+
result = strategy.fail!(:invalid_identity_provider, e)
|
59
|
+
throw :warden, result
|
60
|
+
end
|
61
|
+
|
62
|
+
def request_path?(env)
|
63
|
+
path = current_path(env)
|
64
|
+
!!request_path_regex.match(path)
|
65
|
+
end
|
66
|
+
|
67
|
+
def callback_path?(env)
|
68
|
+
path = current_path(env)
|
69
|
+
!!callback_path_regex.match(path)
|
70
|
+
end
|
71
|
+
|
72
|
+
def current_path(env)
|
73
|
+
env['PATH_INFO']
|
74
|
+
end
|
75
|
+
|
76
|
+
def extract_identity_provider_id(env)
|
77
|
+
path = current_path(env)
|
78
|
+
match = saml_path_regex.match(path)
|
79
|
+
match ? match[:identity_provider_id] : nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
metadata
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: omniauth-multi-provider-saml
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joel Turkel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: omniauth
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: omniauth-saml
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.10'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.10'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- jturkel@salsify.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- README.md
|
91
|
+
- lib/omniauth-multi-provider-saml.rb
|
92
|
+
- lib/omniauth/saml/multi_provider/handler.rb
|
93
|
+
- lib/omniauth/saml/multi_provider/version.rb
|
94
|
+
homepage: https://github.com/salsify/omniauth-multi-provider-saml
|
95
|
+
licenses:
|
96
|
+
- MIT
|
97
|
+
metadata: {}
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
requirements: []
|
113
|
+
rubyforge_project:
|
114
|
+
rubygems_version: 2.4.8
|
115
|
+
signing_key:
|
116
|
+
specification_version: 4
|
117
|
+
summary: An extension to omniauth-saml for handling multiple identity providers
|
118
|
+
test_files: []
|