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.
Files changed (31) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +16 -0
  3. data/MIT-LICENSE +20 -0
  4. data/Rakefile +25 -0
  5. data/app/controller/federated_rails/auth_controller.rb +55 -0
  6. data/app/views/federated_rails/auth/_loginerror.html.erb +11 -0
  7. data/app/views/federated_rails/auth/federatedlogin.html.erb +14 -0
  8. data/app/views/federated_rails/auth/locallogin.html.erb +2 -0
  9. data/app/views/federated_rails/auth/login.html.erb +53 -0
  10. data/app/views/federated_rails/auth/logout.html.erb +2 -0
  11. data/app/views/federated_rails/auth/unauthenticated.html.erb +11 -0
  12. data/config/routes.rb +11 -0
  13. data/lib/federated_rails.rb +10 -0
  14. data/lib/federated_rails/acts_as_federated.rb +22 -0
  15. data/lib/federated_rails/authentication_controller_extension.rb +12 -0
  16. data/lib/federated_rails/development_strategy.rb +64 -0
  17. data/lib/federated_rails/engine.rb +9 -0
  18. data/lib/federated_rails/federation_strategy.rb +66 -0
  19. data/lib/federated_rails/provisioning_manager.rb +33 -0
  20. data/lib/federated_rails/railtie.rb +12 -0
  21. data/lib/federated_rails/security_manager.rb +14 -0
  22. data/lib/generators/federated_rails/install/install_generator.rb +41 -0
  23. data/lib/generators/federated_rails/templates/create_session_records.rb.erb +16 -0
  24. data/lib/generators/federated_rails/templates/create_subjects.rb.erb +14 -0
  25. data/lib/generators/federated_rails/templates/federation.rb.erb +27 -0
  26. data/lib/generators/federated_rails/templates/provisioning_manager.rb.erb +23 -0
  27. data/lib/generators/federated_rails/templates/security_manager.rb.erb +11 -0
  28. data/lib/generators/federated_rails/templates/session_record.rb.erb +6 -0
  29. data/lib/generators/federated_rails/templates/subject.rb.erb +13 -0
  30. data/lib/generators/federated_rails/templates/warden.rb.erb +10 -0
  31. metadata +73 -0
@@ -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
@@ -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.
@@ -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,11 @@
1
+ <h2>Login Denied</h2>
2
+ Login attempt was halted.
3
+
4
+ <h2>Headers</h2>
5
+ <table border="1">
6
+ <% for header in request.env %>
7
+ <tr>
8
+ <td><%=header[0]%></td><td><%=header[1]%></td>
9
+ </tr>
10
+ <% end %>
11
+ </table>
@@ -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,2 @@
1
+ <h1>Auth#locallogin</h1>
2
+ <p>Find me in app/views/auth/locallogin.html.erb</p>
@@ -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 %>
@@ -0,0 +1,2 @@
1
+ <h1>Auth#logout</h1>
2
+ <p>Find me in app/views/auth/logout.html.erb</p>
@@ -0,0 +1,11 @@
1
+ problem ? [troll]
2
+
3
+ <br>
4
+ <h2>Headers</h2>
5
+ <table border="1">
6
+ <% for header in request.env %>
7
+ <tr>
8
+ <td><%=header[0]%></td><td><%=header[1]%></td>
9
+ </tr>
10
+ <% end %>
11
+ </table>
@@ -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,9 @@
1
+
2
+ require "federated_rails"
3
+ require "rails"
4
+
5
+ module FederatedRails
6
+ class Engine < Rails::Engine
7
+
8
+ end
9
+ 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,14 @@
1
+ module FederatedRails
2
+ class SecurityManager
3
+ attr_accessor :warden
4
+ def initialize(w)
5
+ @warden = w
6
+ end
7
+ def method_missing(name, *args)
8
+ warden.send name, *args
9
+ end
10
+ def subject
11
+ warden.user
12
+ end
13
+ end
14
+ 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,11 @@
1
+
2
+ # This allows us to extend how security is managed
3
+ # to suit the explict needs of the host application
4
+
5
+ FederatedRails::SecurityManager.class_eval do
6
+
7
+ def <%= model.downcase %>
8
+ warden.user
9
+ end
10
+
11
+ end
@@ -0,0 +1,6 @@
1
+ class SessionRecord < ActiveRecord::Base
2
+ belongs_to :<%= model.downcase %>
3
+
4
+ validates_presence_of :credential, :remote_host, :user_agent
5
+ attr_accessible :credential, :remote_host, :user_agent
6
+ 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: []