omniauth-shibboleth-1.2.1/0000755000004100000410000000000012546023335015513 5ustar www-datawww-dataomniauth-shibboleth-1.2.1/Rakefile0000644000004100000410000000023712546023335017162 0ustar www-datawww-datarequire 'bundler' Bundler::GemHelper.install_tasks require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) task :default => :spec task :test => :spec omniauth-shibboleth-1.2.1/Gemfile.lock0000644000004100000410000000144312546023335017737 0ustar www-datawww-dataPATH remote: . specs: omniauth-shibboleth (1.2.0) omniauth (>= 1.0.0) GEM remote: http://rubygems.org/ specs: diff-lcs (1.2.5) hashie (3.4.1) omniauth (1.2.2) hashie (>= 1.2, < 4) rack (~> 1.0) rack (1.6.1) rack-test (0.6.3) rack (>= 1.0) rake (10.4.2) rspec (3.2.0) rspec-core (~> 3.2.0) rspec-expectations (~> 3.2.0) rspec-mocks (~> 3.2.0) rspec-core (3.2.3) rspec-support (~> 3.2.0) rspec-expectations (3.2.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.2.0) rspec-mocks (3.2.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.2.0) rspec-support (3.2.2) PLATFORMS ruby DEPENDENCIES omniauth-shibboleth! rack-test rake rspec (>= 2.8) BUNDLED WITH 1.10.2 omniauth-shibboleth-1.2.1/omniauth-shibboleth.gemspec0000644000004100000410000000164212546023335023030 0ustar www-datawww-data# -*- encoding: utf-8 -*- require File.expand_path('../lib/omniauth-shibboleth/version', __FILE__) Gem::Specification.new do |gem| gem.add_dependency 'omniauth', '>= 1.0.0' gem.add_development_dependency 'rack-test' gem.add_development_dependency 'rake' gem.add_development_dependency 'rspec', '>= 2.8' gem.license = 'MIT' gem.authors = ["Toyokazu Akiyama"] gem.email = ["toyokazu@gmail.com"] gem.description = %q{OmniAuth Shibboleth strategies for OmniAuth 1.x} gem.summary = %q{OmniAuth Shibboleth strategies for OmniAuth 1.x} gem.homepage = "" gem.files = `find . -not \\( -regex ".*\\.git.*" -o -regex "\\./pkg.*" -o -regex "\\./spec.*" \\)`.split("\n").map{ |f| f.gsub(/^.\//, '') } gem.test_files = `find spec/*`.split("\n") gem.name = "omniauth-shibboleth" gem.require_paths = ["lib"] gem.version = OmniAuth::Shibboleth::VERSION end omniauth-shibboleth-1.2.1/Gemfile0000644000004100000410000000004712546023335017007 0ustar www-datawww-datasource 'http://rubygems.org' gemspec omniauth-shibboleth-1.2.1/spec/0000755000004100000410000000000012546023335016445 5ustar www-datawww-dataomniauth-shibboleth-1.2.1/spec/omniauth/0000755000004100000410000000000012546023335020271 5ustar www-datawww-dataomniauth-shibboleth-1.2.1/spec/omniauth/strategies/0000755000004100000410000000000012546023335022443 5ustar www-datawww-dataomniauth-shibboleth-1.2.1/spec/omniauth/strategies/shibboleth_spec.rb0000644000004100000410000003023712546023335026132 0ustar www-datawww-data#require 'pry-byebug' require 'spec_helper' def make_env(path = '/auth/shibboleth', props = {}) { 'REQUEST_METHOD' => 'GET', 'PATH_INFO' => path, 'rack.session' => {}, 'rack.input' => StringIO.new('test=true') }.merge(props) end def without_session_failure_path if OmniAuth::VERSION >= "1.0" && OmniAuth::VERSION < "1.1" "/auth/failure?message=no_shibboleth_session" elsif OmniAuth::VERSION >= "1.1" "/auth/failure?message=no_shibboleth_session&strategy=shibboleth" end end def empty_uid_failure_path if OmniAuth::VERSION >= "1.0" && OmniAuth::VERSION < "1.1" "/auth/failure?message=empty_uid" elsif OmniAuth::VERSION >= "1.1" "/auth/failure?message=empty_uid&strategy=shibboleth" end end describe OmniAuth::Strategies::Shibboleth do let(:app){ Rack::Builder.new do |b| b.use Rack::Session::Cookie, {:secret => "abc123"} b.use OmniAuth::Strategies::Shibboleth b.run lambda{|env| [200, {}, ['Not Found']]} end.to_app } context 'request phase' do before do get '/auth/shibboleth' end it 'is expected to redirect to callback_url' do expect(last_response.status).to eq(302) expect(last_response.location).to eq('/auth/shibboleth/callback') end end context 'callback phase' do context 'without Shibboleth session' do before do get '/auth/shibboleth/callback' end it 'is expected to fail to get Shib-Session-ID environment variable' do expect(last_response.status).to eq(302) expect(last_response.location).to eq(without_session_failure_path) end end context 'with Shibboleth session' do let(:strategy){ OmniAuth::Strategies::Shibboleth.new(app, {}) } it 'is expected to set default omniauth.auth fields' do @dummy_id = 'abcdefg' @eppn = 'test@example.com' @display_name = 'Test User' env = make_env('/auth/shibboleth/callback', 'Shib-Session-ID' => @dummy_id, 'eppn' => @eppn, 'displayName' => @display_name) response = strategy.call!(env) expect(strategy.env['omniauth.auth']['uid']).to eq(@eppn) expect(strategy.env['omniauth.auth']['info']['name']).to eq(@display_name) end end context 'with Shibboleth session and attribute options' do let(:options){ { :shib_session_id_field => 'Shib-Session-ID', :shib_application_id_field => 'Shib-Application-ID', :uid_field => :uid, :name_field => :sn, :info_fields => {}, :extra_fields => [:o, :affiliation] } } let(:app){ lambda{|env| [404, {}, ['Not Found']]}} let(:strategy){ OmniAuth::Strategies::Shibboleth.new(app, options) } it 'is expected to set specified omniauth.auth fields' do @dummy_id = 'abcdefg' @uid = 'test' @sn = 'User' @organization = 'Test Corporation' @affiliation = 'faculty' env = make_env('/auth/shibboleth/callback', 'Shib-Session-ID' => @dummy_id, 'uid' => @uid, 'sn' => @sn, 'o' => @organization, 'affiliation' => @affiliation) response = strategy.call!(env) expect(strategy.env['omniauth.auth']['uid']).to eq(@uid) expect(strategy.env['omniauth.auth']['extra']['raw_info']['o']).to eq(@organization) expect(strategy.env['omniauth.auth']['extra']['raw_info']['affiliation']).to eq(@affiliation) end end context 'with debug options' do let(:options){ { :debug => true} } let(:app){ lambda{|env| [404, {}, ['Not Found']]}} let(:strategy){ OmniAuth::Strategies::Shibboleth.new(app, options) } it 'is expected to raise environment variables' do @dummy_id = 'abcdefg' @eppn = 'test@example.com' @display_name = 'Test User' env = make_env('/auth/shibboleth/callback', 'Shib-Session-ID' => @dummy_id, 'eppn' => @eppn, 'displayName' => @display_name) response = strategy.call!(env) expect(response[0]).to eq(200) end end context 'with request_type = :header' do let(:options){ { :request_type => :header, :shib_session_id_field => 'Shib-Session-ID', :shib_application_id_field => 'Shib-Application-ID', :uid_field => :uid, :name_field => :displayName, :info_fields => {}, :extra_fields => [:o, :affiliation] } } let(:app){ lambda{|env| [200, {}, ['OK']]}} let(:strategy){ OmniAuth::Strategies::Shibboleth.new(app, options) } it 'is expected to handle header variables' do @dummy_id = 'abcdefg' @display_name = 'Test User' @uid = 'test' @organization = 'Test Corporation' @affiliation = 'faculty' env = make_env('/auth/shibboleth/callback', 'HTTP_SHIB_SESSION_ID' => @dummy_id, 'HTTP_DISPLAYNAME' => @display_name, 'HTTP_UID' => @uid, 'HTTP_O' => @organization, 'HTTP_AFFILIATION' => @affiliation) response = strategy.call!(env) expect(strategy.env['omniauth.auth']['uid']).to eq(@uid) expect(strategy.env['omniauth.auth']['info']['name']).to eq(@display_name) expect(strategy.env['omniauth.auth']['extra']['raw_info']['o']).to eq(@organization) expect(strategy.env['omniauth.auth']['extra']['raw_info']['affiliation']).to eq(@affiliation) end end context "with request_type = 'header'" do let(:options){ { :request_type => 'header', :shib_session_id_field => 'Shib-Session-ID', :shib_application_id_field => 'Shib-Application-ID', :uid_field => :uid, :name_field => :displayName, :info_fields => {}, :extra_fields => [:o, :affiliation] } } let(:app){ lambda{|env| [200, {}, ['OK']]}} let(:strategy){ OmniAuth::Strategies::Shibboleth.new(app, options) } it 'is expected to handle header variables' do @dummy_id = 'abcdefg' @display_name = 'Test User' @uid = 'test' @organization = 'Test Corporation' @affiliation = 'faculty' env = make_env('/auth/shibboleth/callback', 'HTTP_SHIB_SESSION_ID' => @dummy_id, 'HTTP_DISPLAYNAME' => @display_name, 'HTTP_UID' => @uid, 'HTTP_O' => @organization, 'HTTP_AFFILIATION' => @affiliation) response = strategy.call!(env) expect(strategy.env['omniauth.auth']['uid']).to eq(@uid) expect(strategy.env['omniauth.auth']['info']['name']).to eq(@display_name) expect(strategy.env['omniauth.auth']['extra']['raw_info']['o']).to eq(@organization) expect(strategy.env['omniauth.auth']['extra']['raw_info']['affiliation']).to eq(@affiliation) end end context 'with request_type = :params' do let(:options){ { :request_type => :params, :shib_session_id_field => 'Shib-Session-ID', :shib_application_id_field => 'Shib-Application-ID', :uid_field => :uid, :name_field => :displayName, :info_fields => {}, :extra_fields => [:o, :affiliation] } } let(:app){ lambda{|env| [200, {}, ['OK']]}} let(:strategy){ OmniAuth::Strategies::Shibboleth.new(app, options) } it 'is expected to handle params variables' do @dummy_id = 'abcdefg' @display_name = 'Test User' @uid = 'test' @organization = 'Test Corporation' @affiliation = 'faculty' env = make_env('/auth/shibboleth/callback', 'QUERY_STRING' => "Shib-Session-ID=#{@dummy_id}&uid=#{@uid}&displayName=#{@display_name}&o=#{@organization}&affiliation=#{@affiliation}") response = strategy.call!(env) expect(strategy.env['omniauth.auth']['uid']).to eq(@uid) expect(strategy.env['omniauth.auth']['info']['name']).to eq(@display_name) expect(strategy.env['omniauth.auth']['extra']['raw_info']['o']).to eq(@organization) expect(strategy.env['omniauth.auth']['extra']['raw_info']['affiliation']).to eq(@affiliation) end end context 'with Proc option' do let(:options){ { :request_type => :env, :shib_session_id_field => 'Shib-Session-ID', :shib_application_id_field => 'Shib-Application-ID', :uid_field => lambda {|request_param| request_param.call('eppn') || request_param.call('mail')}, :name_field => lambda {|request_param| "#{request_param.call('cn')} #{request_param.call('sn')}"}, :info_fields => {:affiliation => lambda {|request_param| "#{request_param.call('affiliation')}@my.localdomain" }}, :extra_fields => [:o, :affiliation] } } let(:app){ lambda{|env| [200, {}, ['OK']]}} let(:strategy){ OmniAuth::Strategies::Shibboleth.new(app, options) } it 'is expected to have eppn as uid and cn + sn as name field.' do @dummy_id = 'abcdefg' @display_name = 'Test User' @uid = 'test' @eppn = 'test@my.localdomain' @cn = 'Test' @sn = 'User' @organization = 'Test Corporation' @affiliation = 'faculty' env = make_env('/auth/shibboleth/callback', 'Shib-Session-ID' => @dummy_id, 'uid' => @uid, 'eppn' => @eppn, 'cn' => @cn, 'sn' => @sn, 'o' => @organization, 'affiliation' => @affiliation) response = strategy.call!(env) expect(strategy.env['omniauth.auth']['uid']).to eq(@eppn) expect(strategy.env['omniauth.auth']['info']['name']).to eq("#{@cn} #{@sn}") expect(strategy.env['omniauth.auth']['info']['affiliation']).to eq("#{@affiliation}@my.localdomain") expect(strategy.env['omniauth.auth']['extra']['raw_info']['o']).to eq(@organization) expect(strategy.env['omniauth.auth']['extra']['raw_info']['affiliation']).to eq(@affiliation) end let(:strategy){ OmniAuth::Strategies::Shibboleth.new(app, options) } it 'is expected to have mail as uid and cn + sn as name field.' do @dummy_id = 'abcdefg' @display_name = 'Test User' @uid = 'test' @mail = 'test@my.localdomain' @cn = 'Test' @sn = 'User' @organization = 'Test Corporation' @affiliation = 'faculty' env = make_env('/auth/shibboleth/callback', 'Shib-Session-ID' => @dummy_id, 'uid' => @uid, 'mail' => @mail, 'cn' => @cn, 'sn' => @sn, 'o' => @organization, 'affiliation' => @affiliation) response = strategy.call!(env) expect(strategy.env['omniauth.auth']['uid']).to eq(@mail) expect(strategy.env['omniauth.auth']['info']['name']).to eq("#{@cn} #{@sn}") expect(strategy.env['omniauth.auth']['info']['affiliation']).to eq("#{@affiliation}@my.localdomain") expect(strategy.env['omniauth.auth']['extra']['raw_info']['o']).to eq(@organization) expect(strategy.env['omniauth.auth']['extra']['raw_info']['affiliation']).to eq(@affiliation) end end context 'empty uid with :fail_with_empty_uid = false' do let(:options){ { :request_type => :env, :fail_with_empty_uid => false, :uid_field => :uid, :name_field => :displayName, :info_fields => {} } } let(:app){ lambda{|env| [200, {}, ['OK']]}} let(:strategy){ OmniAuth::Strategies::Shibboleth.new(app, options) } it 'is expected to output null (empty) uid as it is' do @dummy_id = 'abcdefg' @display_name = 'Test User' @uid = '' env = make_env('/auth/shibboleth/callback', 'Shib-Session-ID' => @dummy_id, 'uid' => @uid, 'displayName' => @display_name) response = strategy.call!(env) expect(strategy.env['omniauth.auth']['uid']).to eq(@uid) end end context 'empty uid with :fail_with_empty_uid = true' do let(:options){ { :request_type => :env, :fail_with_empty_uid => true, :shib_session_id_field => 'Shib-Session-ID', :shib_application_id_field => 'Shib-Application-ID', :uid_field => :uid, :name_field => :displayName, :info_fields => {} } } let(:app){ lambda{|env| [200, {}, ['OK']]}} let(:strategy){ OmniAuth::Strategies::Shibboleth.new(app, options) } it 'is expected to fail because of the empty uid' do @dummy_id = 'abcdefg' @display_name = 'Test User' @uid = '' env = make_env('/auth/shibboleth/callback', 'Shib-Session-ID' => @dummy_id, 'uid' => @uid, 'displayName' => @display_name) response = strategy.call!(env) expect(response[0]).to eq(302) expect(response[1]["Location"]).to eq(empty_uid_failure_path) end end end end omniauth-shibboleth-1.2.1/spec/spec_helper.rb0000644000004100000410000000032012546023335021256 0ustar www-datawww-datarequire 'rspec' require 'rack/test' require 'omniauth' require 'omniauth/version' require 'omniauth-shibboleth' RSpec.configure do |config| config.include Rack::Test::Methods config.color = true end omniauth-shibboleth-1.2.1/lib/0000755000004100000410000000000012546023335016261 5ustar www-datawww-dataomniauth-shibboleth-1.2.1/lib/omniauth/0000755000004100000410000000000012546023335020105 5ustar www-datawww-dataomniauth-shibboleth-1.2.1/lib/omniauth/strategies/0000755000004100000410000000000012546023335022257 5ustar www-datawww-dataomniauth-shibboleth-1.2.1/lib/omniauth/strategies/shibboleth.rb0000644000004100000410000000521012546023335024725 0ustar www-datawww-datamodule OmniAuth module Strategies class Shibboleth include OmniAuth::Strategy option :shib_session_id_field, 'Shib-Session-ID' option :shib_application_id_field, 'Shib-Application-ID' option :uid_field, 'eppn' option :name_field, 'displayName' option :info_fields, {} option :extra_fields, [] option :debug, false option :fail_with_empty_uid, false option :request_type, :env def request_phase [ 302, { 'Location' => script_name + callback_path + query_string, 'Content-Type' => 'text/plain' }, ["You are being redirected to Shibboleth SP/IdP for sign-in."] ] end def request_params case options[:request_type] when :env, 'env', :header, 'header' request.env when :params, 'params' request.params end end def request_param(key) case options[:request_type] when :env, 'env' request.env[key] when :header, 'header' request.env["HTTP_#{key.upcase.gsub('-', '_')}"] when :params, 'params' request.params[key] end end def callback_phase if options[:debug] # dump attributes return [ 200, { 'Content-Type' => 'text/plain' }, ["!!!!! This message is generated by omniauth-shibboleth. To remove it set :debug to false. !!!!!\n#{request_params.sort.map {|i| "#{i[0]}: #{i[1]}" }.join("\n")}"] ] end return fail!(:no_shibboleth_session) unless (request_param(options.shib_session_id_field.to_s) || request_param(options.shib_application_id_field.to_s)) return fail!(:empty_uid) if options[:fail_with_empty_uid] && option_handler(options.uid_field).empty? super end def option_handler(option_field) if option_field.class == String || option_field.class == Symbol request_param(option_field.to_s) elsif option_field.class == Proc option_field.call(self.method(:request_param)) end end uid do option_handler(options.uid_field) end info do res = { :name => option_handler(options.name_field) } options.info_fields.each_pair do |key, field| res[key] = option_handler(field) end res end extra do options.extra_fields.inject({:raw_info => {}}) do |hash, field| hash[:raw_info][field] = request_param(field.to_s) hash end end end end end omniauth-shibboleth-1.2.1/lib/omniauth-shibboleth.rb0000644000004100000410000000024312546023335022552 0ustar www-datawww-datarequire "omniauth-shibboleth/version" require "omniauth" module OmniAuth module Strategies autoload :Shibboleth, 'omniauth/strategies/shibboleth' end end omniauth-shibboleth-1.2.1/lib/omniauth-shibboleth/0000755000004100000410000000000012546023335022226 5ustar www-datawww-dataomniauth-shibboleth-1.2.1/lib/omniauth-shibboleth/version.rb0000644000004100000410000000010412546023335024233 0ustar www-datawww-datamodule OmniAuth module Shibboleth VERSION = "1.2.1" end end omniauth-shibboleth-1.2.1/metadata.yml0000644000004100000410000000520612546023335020021 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: omniauth-shibboleth version: !ruby/object:Gem::Version version: 1.2.1 platform: ruby authors: - Toyokazu Akiyama autorequire: bindir: bin cert_chain: [] date: 2015-06-22 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: omniauth requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 1.0.0 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 1.0.0 - !ruby/object:Gem::Dependency name: rack-test requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: rake requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: rspec requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '2.8' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '2.8' description: OmniAuth Shibboleth strategies for OmniAuth 1.x email: - toyokazu@gmail.com executables: [] extensions: [] extra_rdoc_files: [] files: - Gemfile - Gemfile.lock - README.md - Rakefile - lib/omniauth-shibboleth.rb - lib/omniauth-shibboleth/version.rb - lib/omniauth/strategies/shibboleth.rb - omniauth-shibboleth.gemspec - spec/omniauth/strategies/shibboleth_spec.rb - spec/spec_helper.rb homepage: '' licenses: - MIT metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 2.4.5 signing_key: specification_version: 4 summary: OmniAuth Shibboleth strategies for OmniAuth 1.x test_files: - spec/omniauth/strategies/shibboleth_spec.rb - spec/spec_helper.rb omniauth-shibboleth-1.2.1/README.md0000644000004100000410000002343512546023335017001 0ustar www-datawww-data# OmniAuth Shibboleth strategy [![Gem Version](http://img.shields.io/gem/v/omniauth-shibboleth.svg)](http://rubygems.org/gems/omniauth-shibboleth) [![Build Status](https://travis-ci.org/toyokazu/omniauth-shibboleth.svg?branch=master)](https://travis-ci.org/toyokazu/omniauth-shibboleth) OmniAuth Shibboleth strategy is an OmniAuth strategy for authenticating through Shibboleth (SAML). If you do not know OmniAuth, please visit OmniAuth wiki. https://github.com/intridea/omniauth/wiki The detail of the authentication middleware Shibboleth is introduced in Shibboleth wiki. https://wiki.shibboleth.net/ OmniAuth basically works as a middleware of Rack applications. It provides environment variable named 'omniauth.auth' (auth hash) after authenticating a user. The 'auth hash' includes the user's attributes. By providing user attributes in the fixed format, applications can easily implement authentication function using multiple authentication methods. OmniAuth Shibboleth strategy uses the 'auth hash' for providing user attributes passed by Shibboleth SP. It enables developers to use Shibboleth and the other authentication methods, including local auth, together in one application. Currently, this document is written for Rails applications. If you tried the other environments and it requires some difficulities, please let me know in the Issues page. https://github.com/toyokazu/omniauth-shibboleth/issues ## Getting Started ### Setup Gemfile and Install % cd rails-app % vi Gemfile gem 'omniauth-shibboleth' % bundle install ### Setup Shibboleth Strategy To use OmniAuth Shibboleth strategy as a middleware in your rails application, add the following file to your rails application initializer directory. % vi config/initializer/omniauth.rb Rails.application.config.middleware.use OmniAuth::Builder do provider :shibboleth end % vi config/initializer/omniauth.rb Rails.application.config.middleware.use OmniAuth::Builder do provider :shibboleth, { :shib_session_id_field => "Shib-Session-ID", :shib_application_id_field => "Shib-Application-ID", :debug => false, :extra_fields => [ :"unscoped-affiliation", :entitlement ] } end In the above example, 'unscoped-affiliation' and 'entitlement' attributes are additionally provided in the raw_info field. They can be referred like request.env["omniauth.auth"]["extra"]["raw_info"]["unscoped-affiliation"]. The detail of the omniauth auth hash schema is described in the following page. https://github.com/intridea/omniauth/wiki/Auth-Hash-Schema 'eppn' attribute is used as uid field. 'displayName' attribute is provided as request.env["omniauth.auth"]["info"]["name"]. These can be changed by :uid_field, :name_field option. You can also add any "info" fields defined in Auth-Hash-Schema by using :info_fields option. % vi config/initializer/omniauth.rb Rails.application.config.middleware.use OmniAuth::Builder do provider :shibboleth, { :uid_field => "uid", :name_field => "displayName", :info_fields => { :email => "mail", :location => "contactAddress", :image => "photo_url", :phone => "contactPhone" } } end In the previous example, Shibboleth strategy does not pass any :info fields and use 'uid' attribute as uid fields. ### More flexible attribute configuration If you need more flexible attribute definition, you can use lambda (Proc) to define your attributes. In the following example, 'uid' attribute is chosen from 'eppn' or 'mail', 'info'/'name' attribute is defined as a concatenation of 'cn' and 'sn' and 'info'/'affiliation' attribute is defined as 'affiliation'@my.localdomain. 'request_param' parameter is a method defined in OmniAuth::Shibboleth::Strategy. You can specify attribute names by downcase strings in either request_type, :env, :header and :params. % vi config/initializer/omniauth.rb Rails.application.config.middleware.use OmniAuth::Builder do provider :shibboleth, { :uid_field => lambda {|request_param| request_param.call('eppn') || request_param.call('mail')}, :name_field => lambda {|request_param| "#{request_param.call('cn')} #{request_param.call('sn')}"}, :info_fields => { :affiliation => lambda {|request_param| "#{request_param.call('affiliation')}@my.localdomain"}, :email => "mail", :location => "contactAddress", :image => "photo_url", :phone => "contactPhone" } } end ### !!!NOTICE!!! devise integration issue When you use omniauth with devise, the omniauth configuration is applied before devise configuration and some part of the configuration overwritten by the devise's. It may not work as you assume. So thus, in that case, currently you should write your configuration only in device configuration. config/initializers/devise.rb: ```ruby config.omniauth :shibboleth, {:uid_field => 'eppn', :info_fields => {:email => 'mail', :name => 'cn', :last_name => 'sn'}, :extra_fields => [:schacHomeOrganization] } ``` The detail is discussed in the following thread. https://github.com/plataformatec/devise/issues/2128 ### How to authenticate users In your application, simply direct users to '/auth/shibboleth' to have them sign in via your company's Shibboleth SP and IdP. '/auth/shibboleth' url simply redirect users to '/auth/shibboleth/callback', so thus you must protect '/auth/shibboleth/callback' by Shibboleth SP. Example shibd.conf: AuthType shibboleth ShibRequestSetting requireSession 1 require valid-user Shibboleth strategy just checks the existence of Shib-Session-ID or Shib-Application-ID. If you want to use omniauth-shibboleth without Apache or IIS, you can try **rack-saml**. It supports a part of Shibboleth SP functions. https://github.com/toyokazu/rack-saml Shibboleth strategy assumes the attributes are provided via environment variables because the use of ShibUseHeaders option may cause some problems. The details are discussed in the following page: https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPSpoofChecking To provide Shibboleth attributes via environment variables, we can not use proxy based approach, e.g. mod_proxy_balancer. Currently we can realize it by using Phusion Passenger as an application container. An example construction pattern is shown in presence_checker application (https://github.com/toyokazu/presence_checker/). ### :request_type option You understand the issues using ShibUseHeaders, but and yet if you want to use the proxy based approach, you can use :request_type option. This option enables us to specify what kind of parameters are used to create 'omniauth.auth' (auth hash). This option can also be used to develop your Rails application without local IdP and SP by using :params option. The option values are: - **:env** (default) The environment variables are used to create auth hash. - **:header** The auth hash is created from header vaiables. In the Rack middleware, since header variables are treated as environment variables like HTTP_*, the specified variables are converted as the same as header variables, HTTP_*. This :request_type is basically used for mod_proxy_balancer approach. - **:params** The query string or POST parameters are used to create auth hash. This :request_type is basically used for development phase. You can emulate SP function by providing parameters as query string. In this case, please do not forget to add Shib-Session-ID or Shib-Application-ID value which is used to check the session is created at SP. The following is an example configuration. % vi config/initializer/omniauth.rb Rails.application.config.middleware.use OmniAuth::Builder do provider :shibboleth, { :request_type => :header } end If you use proxy based approach, please be sure to add ShibUseHeaders option in mod_shib configuration. AuthType shibboleth ShibRequestSetting requireSession 1 ShibUseHeaders On require valid-user ### debug mode When you deploy a new application, you may want to confirm the assumed attributes are correctly provided by Shibboleth SP. OmniAuth Shibboleth strategy provides a confirmation option :debug. If you set :debug true, you can see the environment variables provided at the /auth/shibboleth/callback uri. % vi config/initializer/omniauth.rb Rails.application.config.middleware.use OmniAuth::Builder do provider :shibboleth, { :debug => true } end ## License (MIT License) omniauth-shibboleth is released under the MIT license. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.