federated_rails 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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: []