federated_rails 0.2.2
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/Gemfile +16 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +25 -0
- data/app/controller/federated_rails/auth_controller.rb +55 -0
- data/app/views/federated_rails/auth/_loginerror.html.erb +11 -0
- data/app/views/federated_rails/auth/federatedlogin.html.erb +14 -0
- data/app/views/federated_rails/auth/locallogin.html.erb +2 -0
- data/app/views/federated_rails/auth/login.html.erb +53 -0
- data/app/views/federated_rails/auth/logout.html.erb +2 -0
- data/app/views/federated_rails/auth/unauthenticated.html.erb +11 -0
- data/config/routes.rb +11 -0
- data/lib/federated_rails.rb +10 -0
- data/lib/federated_rails/acts_as_federated.rb +22 -0
- data/lib/federated_rails/authentication_controller_extension.rb +12 -0
- data/lib/federated_rails/development_strategy.rb +64 -0
- data/lib/federated_rails/engine.rb +9 -0
- data/lib/federated_rails/federation_strategy.rb +66 -0
- data/lib/federated_rails/provisioning_manager.rb +33 -0
- data/lib/federated_rails/railtie.rb +12 -0
- data/lib/federated_rails/security_manager.rb +14 -0
- data/lib/generators/federated_rails/install/install_generator.rb +41 -0
- data/lib/generators/federated_rails/templates/create_session_records.rb.erb +16 -0
- data/lib/generators/federated_rails/templates/create_subjects.rb.erb +14 -0
- data/lib/generators/federated_rails/templates/federation.rb.erb +27 -0
- data/lib/generators/federated_rails/templates/provisioning_manager.rb.erb +23 -0
- data/lib/generators/federated_rails/templates/security_manager.rb.erb +11 -0
- data/lib/generators/federated_rails/templates/session_record.rb.erb +6 -0
- data/lib/generators/federated_rails/templates/subject.rb.erb +13 -0
- data/lib/generators/federated_rails/templates/warden.rb.erb +10 -0
- metadata +73 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: eb55e97af1673e142ca61d53be8860f6b11690b4
|
4
|
+
data.tar.gz: 0bf597bfa4538c80007358f8efafab5200d0d1f0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2ba093decda6fee395fc2fb5df843ed11ffa983b8cd7e4c99abed6d5321ee8c5ac080e47542508291e0c72cef8b06648febe80d01f5cb07442d68023e8c6c907
|
7
|
+
data.tar.gz: 45eb56f25228e209a2c6c69ff513279583505205557ce133c51476acb0f78acd0ce922616181908639ecb9c9288cc0d5fa8ef54ab0d21b3863c5ee0c2728a4d2
|
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem "rails", "3.0.9"
|
4
|
+
gem "sqlite3"
|
5
|
+
|
6
|
+
gem "rails_warden", "~> 0.5.5"
|
7
|
+
|
8
|
+
group :development do
|
9
|
+
gem "bundler", "~> 1.0.0"
|
10
|
+
gem "rcov", ">= 0"
|
11
|
+
end
|
12
|
+
|
13
|
+
group :test, :development do
|
14
|
+
gem "rspec-rails", "~> 2.6"
|
15
|
+
gem "factory_girl_rails", "~> 1.1"
|
16
|
+
end
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2011 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'rubygems'
|
3
|
+
begin
|
4
|
+
require 'bundler/setup'
|
5
|
+
rescue LoadError
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rake'
|
10
|
+
require 'rake/rdoctask'
|
11
|
+
|
12
|
+
require 'rspec/core'
|
13
|
+
require 'rspec/core/rake_task'
|
14
|
+
|
15
|
+
RSpec::Core::RakeTask.new(:spec)
|
16
|
+
|
17
|
+
task :default => :spec
|
18
|
+
|
19
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
20
|
+
rdoc.rdoc_dir = 'rdoc'
|
21
|
+
rdoc.title = 'FederatedRails'
|
22
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
23
|
+
rdoc.rdoc_files.include('README.rdoc')
|
24
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
25
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
|
2
|
+
class FederatedRails::AuthController < ApplicationController
|
3
|
+
|
4
|
+
skip_before_filter :ensure_valid_subject
|
5
|
+
|
6
|
+
def login
|
7
|
+
# Integrates with Shibboleth NativeSPSessionCreationParameters as per https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPSessionCreationParameters
|
8
|
+
login_url = "#{Rails.application.config.federation.ssoendpoint}?target=#{url_for(:controller => 'auth', :action => 'federation_login')}"
|
9
|
+
if Rails.application.config.federation.automatelogin
|
10
|
+
redirect_to login_url
|
11
|
+
return
|
12
|
+
end
|
13
|
+
|
14
|
+
@spsession_url = login_url
|
15
|
+
end
|
16
|
+
|
17
|
+
def logout
|
18
|
+
uri = url_for root_path
|
19
|
+
logger.info "Logging out principal #{security_manager.subject.principal} and directing to #{uri.inspect}" if security_manager.subject
|
20
|
+
warden.logout
|
21
|
+
redirect_to uri
|
22
|
+
end
|
23
|
+
|
24
|
+
def unauthenticated
|
25
|
+
end
|
26
|
+
|
27
|
+
def federation_login
|
28
|
+
if Rails.application.config.federation.federationactive
|
29
|
+
warden.authenticate!(:federation_login)
|
30
|
+
|
31
|
+
uri = session[:security_manager_return_to] ||= url_for(root_path)
|
32
|
+
logger.info "Redirecting principal #{security_manager.subject.principal} to #{uri.inspect}"
|
33
|
+
redirect_to uri
|
34
|
+
else
|
35
|
+
logger.error "Attempt utilize federation login when federation disabled"
|
36
|
+
render :partial => "loginerror", :nothing => true, :status => :forbidden
|
37
|
+
return
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def development_login
|
42
|
+
if Rails.application.config.federation.developmentactive
|
43
|
+
warden.authenticate!(:development_login)
|
44
|
+
|
45
|
+
uri = session[:security_manager_return_to] ||= url_for(root_path)
|
46
|
+
logger.info "Redirecting principal #{security_manager.subject.principal} to #{uri.inspect}"
|
47
|
+
redirect_to uri
|
48
|
+
else
|
49
|
+
logger.error "Attempt utilize development login when development is disabled"
|
50
|
+
render :partial => "loginerror", :nothing => true, :status => 403
|
51
|
+
return
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
<%= request.env['HTTP_PERSISTENT_ID'] %><br>
|
3
|
+
<%= request.env['HTTP_SHIB_SESSION_ID'] %><br>
|
4
|
+
<%= request.env['HTTP_SHIB_IDENTITY_PROVIDER'] %><br>
|
5
|
+
<%= request.env['HTTP_SHIB_APPLICATION_ID'] %><br>
|
6
|
+
<%= request.env['HTTP_SHIB_AUTHENTICATION_INSTANT'] %><br>
|
7
|
+
|
8
|
+
<br>
|
9
|
+
|
10
|
+
<%= request.env['HTTP_DISPLAYNAME'] %><br>
|
11
|
+
<%= request.env['HTTP_MAIL'] %><br>
|
12
|
+
<%= request.env['HTTP_ENTITLEMENT'] %><br>
|
13
|
+
<%= request.env['HTTP_HOMEORGANIZATION'] %><br>
|
14
|
+
<%= request.env['HTTP_HOMEORGANIZATIONTYPE'] %><br>
|
@@ -0,0 +1,53 @@
|
|
1
|
+
<h1>Application Login</h1>
|
2
|
+
|
3
|
+
<%= link_to "Shib", @spsession_url %>
|
4
|
+
|
5
|
+
<h2>Select login account</h2>
|
6
|
+
|
7
|
+
<h3>Fred Bloggs</h3>
|
8
|
+
<p>Principal: https://idp.one.edu.au/idp/shibboleth!-!d2404817-6fb9-4165-90d8-1</p>
|
9
|
+
<%= form_tag(:controller => 'auth', :action => 'development_login') do %>
|
10
|
+
<%= hidden_field_tag(:principal, 'https://idp.one.edu.au/idp/shibboleth!-!d2404817-6fb9-4165-90d8-1') %>
|
11
|
+
<%= hidden_field_tag(:credential, 'fake-sessionid-webform') %>
|
12
|
+
|
13
|
+
<%= hidden_field :attributes, :cn, :value => 'Fred Bloggs' %>
|
14
|
+
<%= hidden_field :attributes, :email, :value => 'fredbloggs@one.edu.au' %>
|
15
|
+
<%= hidden_field :attributes, :shared_token, :value => 'zxcvSFDsfgsgf#$%' %>
|
16
|
+
<%= hidden_field :attributes, :entityID, :value => 'https://idp.one.edu.au/idp/shibboleth' %>
|
17
|
+
<%= hidden_field :attributes, :homeOrganization, :value => 'one.edu.au' %>
|
18
|
+
<%= hidden_field :attributes, :homeOrganizationType, :value => 'university:australia' %>
|
19
|
+
|
20
|
+
<%= submit_tag('Login') %>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<h3>Joe Schmoe</h3>
|
24
|
+
<p>Principal: https://idp.one.edu.au/idp/shibboleth!-!d2404817-6fb9-4165-90d8-2</p>
|
25
|
+
<%= form_tag(:controller => 'auth', :action => 'development_login') do %>
|
26
|
+
<%= hidden_field_tag(:principal, 'https://idp.one.edu.au/idp/shibboleth!-!d2404817-6fb9-4165-90d8-2') %>
|
27
|
+
<%= hidden_field_tag(:credential, 'fake-sessionid-webform') %>
|
28
|
+
|
29
|
+
<%= hidden_field :attributes, :cn, :value => 'Joe Schmoe' %>
|
30
|
+
<%= hidden_field :attributes, :email, :value => 'joeschmoe@one.edu.au' %>
|
31
|
+
<%= hidden_field :attributes, :shared_token, :value => 'qwerSFDsfgsgf#$%' %>
|
32
|
+
<%= hidden_field :attributes, :entityID, :value => 'https://idp.one.edu.au/idp/shibboleth' %>
|
33
|
+
<%= hidden_field :attributes, :homeOrganization, :value => 'one.edu.au' %>
|
34
|
+
<%= hidden_field :attributes, :homeOrganizationType, :value => 'university:australia' %>
|
35
|
+
|
36
|
+
<%= submit_tag('Login') %>
|
37
|
+
<% end %>
|
38
|
+
|
39
|
+
<h3>Max Mustermann</h3>
|
40
|
+
<p>Principal: https://idp.one.edu.au/idp/shibboleth!-!d2404817-6fb9-4165-90d8-3</p>
|
41
|
+
<%= form_tag(:controller => 'auth', :action => 'development_login') do %>
|
42
|
+
<%= hidden_field_tag(:principal, 'https://idp.one.edu.au/idp/shibboleth!-!d2404817-6fb9-4165-90d8-3') %>
|
43
|
+
<%= hidden_field_tag(:credential, 'fake-sessionid-webform') %>
|
44
|
+
|
45
|
+
<%= hidden_field :attributes, :cn, :value => 'Max Mustermann' %>
|
46
|
+
<%= hidden_field :attributes, :email, :value => 'maxmustermann@one.edu.au' %>
|
47
|
+
<%= hidden_field :attributes, :shared_token, :value => 'adsfSFDsfgsgf#$%' %>
|
48
|
+
<%= hidden_field :attributes, :entityID, :value => 'https://idp.one.edu.au/idp/shibboleth' %>
|
49
|
+
<%= hidden_field :attributes, :homeOrganization, :value => 'one.edu.au' %>
|
50
|
+
<%= hidden_field :attributes, :homeOrganizationType, :value => 'university:australia' %>
|
51
|
+
|
52
|
+
<%= submit_tag('Login') %>
|
53
|
+
<% end %>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
|
3
|
+
scope :module => 'federated_rails' do
|
4
|
+
match '/login', :to => 'auth#login', :as => :login
|
5
|
+
match '/logout', :to => 'auth#logout', :as => :logout
|
6
|
+
match '/loginerror', :to => 'auth#unauthenticated'
|
7
|
+
match '/auth/federation', :to => 'auth#federation_login'
|
8
|
+
match '/auth/development', :to => 'auth#development_login'
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'rails_warden'
|
3
|
+
|
4
|
+
module FederatedRails
|
5
|
+
require 'federated_rails/engine' if defined?(Rails)
|
6
|
+
require 'federated_rails/railtie' if defined?(Rails)
|
7
|
+
|
8
|
+
require 'federated_rails/federation_strategy'
|
9
|
+
require 'federated_rails/development_strategy'
|
10
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
module FederatedRails
|
4
|
+
|
5
|
+
module ActsAsFederated
|
6
|
+
module InstanceMethods
|
7
|
+
protected
|
8
|
+
def ensure_valid_subject
|
9
|
+
unless security_manager.authenticated?
|
10
|
+
session[:security_manager_return_to] = request.fullpath if request.get?
|
11
|
+
redirect_to :login
|
12
|
+
false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def security_manager
|
17
|
+
@security_manager ||= SecurityManager.new request.env['warden']
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module FederatedRails
|
2
|
+
module ActionControllerExtension
|
3
|
+
module ClassMethods
|
4
|
+
def acts_as_federated
|
5
|
+
# At this point, 'self' is the ApplicationController
|
6
|
+
self.send :include, ::FederatedRails::ActsAsFederated::InstanceMethods
|
7
|
+
self.before_filter :ensure_valid_subject
|
8
|
+
self.helper_method :security_manager
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
|
2
|
+
require 'federated_rails/provisioning_manager'
|
3
|
+
|
4
|
+
module FederatedRails
|
5
|
+
class DevelopmentStrategy < Warden::Strategies::Base
|
6
|
+
|
7
|
+
include ProvisioningManager
|
8
|
+
|
9
|
+
def authenticate!
|
10
|
+
|
11
|
+
if Rails.application.config.federation.developmentactive
|
12
|
+
principal = params[:principal]
|
13
|
+
unless principal
|
14
|
+
return fail! 'Authentication Error - Development environment did not supply persistent ID'
|
15
|
+
end
|
16
|
+
|
17
|
+
credential = params[:credential]
|
18
|
+
unless credential
|
19
|
+
return fail! 'Authentication Error - Development environment did not supply session ID'
|
20
|
+
end
|
21
|
+
|
22
|
+
subject = host_subject.find_or_initialize_by_principal(params[:principal])
|
23
|
+
|
24
|
+
if subject.new_record?
|
25
|
+
unless Rails.application.config.federation.autoprovision
|
26
|
+
logger.error 'Authentication Error - Automatic provisioning is disabled in configuration'
|
27
|
+
return fail! 'Authentication Error - Automatic provisioning is disabled in configuration'
|
28
|
+
end
|
29
|
+
|
30
|
+
logger.info "Creating new subject for principal #{subject.principal}"
|
31
|
+
|
32
|
+
# The default implementation simply stores the principal
|
33
|
+
# Customize provision_subject_development within an application initializer to meet your specific needs
|
34
|
+
provision_development subject
|
35
|
+
else
|
36
|
+
logger.info "Updating returning #{subject} from development source"
|
37
|
+
|
38
|
+
# If you have attributes specific to your application that may change on the IdP side
|
39
|
+
# such as names, email addresses and entitlemenets these will need to be updated at session establishment.
|
40
|
+
# Customize update_subject_development within an application initializer to meet your specific needs.
|
41
|
+
update_development subject
|
42
|
+
end
|
43
|
+
|
44
|
+
# Store details about this session
|
45
|
+
remote_host = request.env['HTTP_X_FORWARDED_FOR'] ||= request.remote_ip()
|
46
|
+
user_agent = request.env['HTTP_USER_AGENT']
|
47
|
+
sr = SessionRecord.new( :credential => credential, :remote_host => remote_host, :user_agent => user_agent )
|
48
|
+
subject.session_records << sr
|
49
|
+
|
50
|
+
unless subject.save
|
51
|
+
logger.error "Unable to persist development subject"
|
52
|
+
subject.errors.each do |error|
|
53
|
+
logger.error error
|
54
|
+
end
|
55
|
+
return fail! 'Authentication Error - Unable to persist development subject'
|
56
|
+
end
|
57
|
+
|
58
|
+
success!(subject)
|
59
|
+
else
|
60
|
+
return fail! 'Authentication Error - Development source is not enabled'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
|
2
|
+
require 'federated_rails/provisioning_manager'
|
3
|
+
|
4
|
+
class FederatedRails::FederationStrategy < Warden::Strategies::Base
|
5
|
+
|
6
|
+
include FederatedRails::ProvisioningManager
|
7
|
+
|
8
|
+
def authenticate!
|
9
|
+
if Rails.application.config.federation.federationactive
|
10
|
+
|
11
|
+
principal = retrieve_federated_value :principal
|
12
|
+
unless principal
|
13
|
+
logger.error 'Authentication Error - Federation did not supply persistent ID'
|
14
|
+
return fail! 'Authentication Error - Federation did not supply persistent ID'
|
15
|
+
end
|
16
|
+
|
17
|
+
credential = retrieve_federated_value :credential
|
18
|
+
unless credential
|
19
|
+
logger.error 'Authentication Error - Federation did not supply session ID'
|
20
|
+
return fail! 'Authentication Error - Federation did not supply session ID'
|
21
|
+
end
|
22
|
+
|
23
|
+
subject = host_subject.find_or_initialize_by_principal(principal)
|
24
|
+
|
25
|
+
if subject.new_record?
|
26
|
+
unless Rails.application.config.federation.autoprovision
|
27
|
+
logger.error 'Authentication Error - Automatic provisioning is disabled in configuration'
|
28
|
+
return fail! 'Authentication Error - Automatic provisioning is disabled in configuration'
|
29
|
+
end
|
30
|
+
|
31
|
+
logger.info "Creating new subject for principal #{subject.principal}"
|
32
|
+
|
33
|
+
# The default implementation simply stores the principal
|
34
|
+
# Customize provision_subject within an application initializer to meet your specific needs
|
35
|
+
provision subject
|
36
|
+
else
|
37
|
+
logger.info "Updating returning #{subject} from federated source"
|
38
|
+
|
39
|
+
# If you have attributes specific to your application that may change on the IdP side
|
40
|
+
# such as names, email addresses and entitlemenets these will need to be updated at session establishment.
|
41
|
+
# Customize update_subject within an application initializer to meet your specific needs.
|
42
|
+
update subject
|
43
|
+
end
|
44
|
+
|
45
|
+
# Store details about this session
|
46
|
+
remote_host = request.env['HTTP_X_FORWARDED_FOR'] ||= request.remote_ip()
|
47
|
+
user_agent = request.env['HTTP_USER_AGENT']
|
48
|
+
sr = SessionRecord.new( :credential => credential, :remote_host => remote_host, :user_agent => user_agent )
|
49
|
+
subject.session_records << sr
|
50
|
+
|
51
|
+
unless subject.save
|
52
|
+
logger.error "Unable to persist federated subject"
|
53
|
+
logger.debug sr.inspect
|
54
|
+
subject.errors.each do |error|
|
55
|
+
logger.error error
|
56
|
+
end
|
57
|
+
return fail! 'Authentication Error - Unable to persist federated subject'
|
58
|
+
end
|
59
|
+
|
60
|
+
success! subject
|
61
|
+
else
|
62
|
+
return fail! 'Authentication Error - Federated source is not enabled'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module FederatedRails
|
2
|
+
module ProvisioningManager
|
3
|
+
|
4
|
+
def provision (subject)
|
5
|
+
logger.debug "Executed default NOOP provisioner against #{subject}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def update (subject)
|
9
|
+
logger.debug "Executed default NOOP updater against #{subject}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def provision_development (subject)
|
13
|
+
logger.debug "Executed default NOOP development provisioning against #{subject}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def update_development (subject)
|
17
|
+
logger.debug "Executed default NOOP development updater against #{subject}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def retrieve_federated_value(attr)
|
21
|
+
if Rails.application.config.federation.attributes
|
22
|
+
request.env[ Rails.application.config.federation.mapping[attr][:env] ]
|
23
|
+
else
|
24
|
+
request.env[ Rails.application.config.federation.mapping[attr][:header] ]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def host_subject
|
29
|
+
Object::const_get(Rails.application.config.federation.subject)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
|
2
|
+
require 'federated_rails/acts_as_federated'
|
3
|
+
require 'federated_rails/authentication_controller_extension'
|
4
|
+
require 'federated_rails/security_manager'
|
5
|
+
|
6
|
+
module FederatedRails
|
7
|
+
class Railtie < Rails::Railtie
|
8
|
+
initializer 'federated_rails.action_controller_federated_extension' do |app|
|
9
|
+
ActionController::Base.send :extend, ::FederatedRails::ActionControllerExtension::ClassMethods
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rails/generators/migration'
|
2
|
+
|
3
|
+
module FederatedRails
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < ::Rails::Generators::Base
|
6
|
+
argument :model, :type => :string, :desc => "The model name to represent the applications subject (recommend: Subject)"
|
7
|
+
class_option :createsubject, :optional => true, :type => :boolean, :default => true, :desc => "Create the subject model and migrations? False if object exists."
|
8
|
+
include Rails::Generators::Migration
|
9
|
+
source_root File.expand_path('../../templates', __FILE__)
|
10
|
+
desc "add the migrations"
|
11
|
+
|
12
|
+
def self.next_migration_number(dirname)
|
13
|
+
if ActiveRecord::Base.timestamped_migrations
|
14
|
+
Time.now.utc.to_f
|
15
|
+
else
|
16
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def copy_initializers
|
21
|
+
template "warden.rb.erb", "config/initializers/warden.rb"
|
22
|
+
template "federation.rb.erb", "config/initializers/federation.rb"
|
23
|
+
template "provisioning_manager.rb.erb", "config/initializers/provisioning_manager.rb"
|
24
|
+
template "security_manager.rb.erb", "config/initializers/security_manager.rb"
|
25
|
+
end
|
26
|
+
|
27
|
+
def copy_models
|
28
|
+
if options[:createsubject]
|
29
|
+
template "subject.rb.erb", "app/models/#{model.downcase}.rb"
|
30
|
+
template "session_record.rb.erb", "app/models/session_record.rb"
|
31
|
+
|
32
|
+
migration_template "create_subjects.rb.erb", "db/migrate/create_#{model.downcase}s.rb"
|
33
|
+
migration_template "create_session_records.rb.erb", "db/migrate/create_session_records.rb"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateSessionRecords < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :session_records do |t|
|
4
|
+
t.string :credential
|
5
|
+
t.string :remote_host
|
6
|
+
t.string :user_agent
|
7
|
+
t.references :<%= model.downcase %>
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
drop_table :session_records
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Create<%= model %>s < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :<%= model.downcase %>s do |t|
|
4
|
+
t.string :principal
|
5
|
+
t.boolean :enabled, :default => false
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.down
|
12
|
+
drop_table :<%= model.downcase %>s
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<%= Rails.application.class.name %>.instance_eval do
|
2
|
+
config.federation = ActiveSupport::OrderedOptions.new
|
3
|
+
federation = config.federation
|
4
|
+
|
5
|
+
# Key integration configuration
|
6
|
+
federation.automatelogin = false
|
7
|
+
federation.federationactive = false
|
8
|
+
federation.developmentactive = false
|
9
|
+
federation.autoprovision = false
|
10
|
+
federation.subject = '<%= model %>'
|
11
|
+
|
12
|
+
# SP session init endpoint
|
13
|
+
federation.ssoendpoint = '/Shibboleth.sso/Login'
|
14
|
+
federation.attributes = false
|
15
|
+
|
16
|
+
# Attribute mappings
|
17
|
+
federation.mapping = ActiveSupport::OrderedOptions.new
|
18
|
+
federation.mapping.principal = {:header => 'HTTP_PERSISTENT_ID', :env => 'persistent-id'} # The unique and persistent ID used to identify this principal for current and subsequent sessions (eduPersonTargetedID)
|
19
|
+
federation.mapping.credential = {:header => 'HTTP_SHIB_SESSION_ID', :env => 'Shib-Session-ID'} # The internal session key assigned to the session associated with the request and hence the credential used
|
20
|
+
federation.mapping.entityID = {:header => 'HTTP_SHIB_IDENTITY_PROVIDER', :env => 'Shib-Identity-Provider'} # The entityID of the IdP that authenticated the user associated with the request.
|
21
|
+
federation.mapping.applicationID = {:header => 'HTTP_SHIB_APPLICATION_ID', :env => 'Shib-Application-ID'} # The applicationId property derived for the request.
|
22
|
+
federation.mapping.idpAuthenticationInstant = {:header => 'HTTP_SHIB_AUTHENTICATION_INSTANT', :env => 'Shib-Authentication-Instant'} # The ISO timestamp provided by the IdP indicating the time of authentication.
|
23
|
+
|
24
|
+
## See mappings in your attribute-map.xml file to enable more attributes - some common additional requirements
|
25
|
+
# federation.mapping.displayName = {:header => 'HTTP_DISPLAYNAME', :env => 'displayName'}
|
26
|
+
# federation.mapping.email = {:header => 'HTTP_MAIL', :env => 'mail'}
|
27
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
# This allows us to extend how <%= model %> is provisioned and updated
|
3
|
+
# to suit the explict needs of the host application
|
4
|
+
|
5
|
+
FederatedRails::ProvisioningManager.module_eval do
|
6
|
+
|
7
|
+
# Customize <%= model %> management within production deployment
|
8
|
+
|
9
|
+
# def provision( <%= model.downcase %> )
|
10
|
+
# end
|
11
|
+
|
12
|
+
# def update ( <%= model.downcase %> )
|
13
|
+
# end
|
14
|
+
|
15
|
+
# Customize <%= model %> management within development deployment
|
16
|
+
|
17
|
+
# def provision_development ( <%= model.downcase %> )
|
18
|
+
# end
|
19
|
+
|
20
|
+
# def update_development ( <%= model.downcase %> )
|
21
|
+
# end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class <%= model %> < ActiveRecord::Base
|
2
|
+
has_many :session_records
|
3
|
+
|
4
|
+
validates_presence_of :principal
|
5
|
+
validates_uniqueness_of :principal
|
6
|
+
validates_associated :session_records
|
7
|
+
|
8
|
+
attr_accessible :administrator, :subject
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
"<%= model.downcase %> [#{self.id}, #{self.principal}]"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Rails.configuration.middleware.use RailsWarden::Manager do |manager|
|
2
|
+
manager.default_strategies :federation_login
|
3
|
+
manager.failure_app = FederatedRails::AuthController
|
4
|
+
end
|
5
|
+
|
6
|
+
Warden::Manager.serialize_into_session { |<%= model.downcase %>| <%= model.downcase %>.id }
|
7
|
+
Warden::Manager.serialize_from_session { |id| <%= model %>.find_by_id(id) }
|
8
|
+
|
9
|
+
Warden::Strategies.add(:federation_login, FederatedRails::FederationStrategy)
|
10
|
+
Warden::Strategies.add(:development_login, FederatedRails::DevelopmentStrategy)
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: federated_rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bradley Beddoes
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-16 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Allows Ruby on Rails applications to easily integrate to federated authentication
|
14
|
+
sources particuarly those served by Shibboleth service providers.
|
15
|
+
email:
|
16
|
+
- bradleybeddoes@gmail.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- app/controller/federated_rails/auth_controller.rb
|
22
|
+
- app/views/federated_rails/auth/_loginerror.html.erb
|
23
|
+
- app/views/federated_rails/auth/federatedlogin.html.erb
|
24
|
+
- app/views/federated_rails/auth/locallogin.html.erb
|
25
|
+
- app/views/federated_rails/auth/login.html.erb
|
26
|
+
- app/views/federated_rails/auth/logout.html.erb
|
27
|
+
- app/views/federated_rails/auth/unauthenticated.html.erb
|
28
|
+
- lib/federated_rails/acts_as_federated.rb
|
29
|
+
- lib/federated_rails/authentication_controller_extension.rb
|
30
|
+
- lib/federated_rails/development_strategy.rb
|
31
|
+
- lib/federated_rails/engine.rb
|
32
|
+
- lib/federated_rails/federation_strategy.rb
|
33
|
+
- lib/federated_rails/provisioning_manager.rb
|
34
|
+
- lib/federated_rails/railtie.rb
|
35
|
+
- lib/federated_rails/security_manager.rb
|
36
|
+
- lib/federated_rails.rb
|
37
|
+
- lib/generators/federated_rails/install/install_generator.rb
|
38
|
+
- lib/generators/federated_rails/templates/create_session_records.rb.erb
|
39
|
+
- lib/generators/federated_rails/templates/create_subjects.rb.erb
|
40
|
+
- lib/generators/federated_rails/templates/federation.rb.erb
|
41
|
+
- lib/generators/federated_rails/templates/provisioning_manager.rb.erb
|
42
|
+
- lib/generators/federated_rails/templates/security_manager.rb.erb
|
43
|
+
- lib/generators/federated_rails/templates/session_record.rb.erb
|
44
|
+
- lib/generators/federated_rails/templates/subject.rb.erb
|
45
|
+
- lib/generators/federated_rails/templates/warden.rb.erb
|
46
|
+
- config/routes.rb
|
47
|
+
- MIT-LICENSE
|
48
|
+
- Rakefile
|
49
|
+
- Gemfile
|
50
|
+
homepage: https://github.com/ausaccessfed/federatedrails
|
51
|
+
licenses: []
|
52
|
+
metadata: {}
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options: []
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
requirements: []
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 2.0.14
|
70
|
+
signing_key:
|
71
|
+
specification_version: 4
|
72
|
+
summary: SAML federation authentication and access control
|
73
|
+
test_files: []
|