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.
@@ -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
@@ -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
@@ -0,0 +1,7 @@
1
+ module OmniAuth
2
+ module SAML
3
+ module MultiProvider
4
+ VERSION = '0.1.0'
5
+ end
6
+ end
7
+ 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: []