The problem with rack-saml <https://github.com/toyokazu/rack-saml> and similar is that they don't support encrypted responses. I ran into this issue while trying to work with an IdP and encryption enabled (the encryption was a requirement).
My stack was nginx (1 server frontend) + passengers (multiple servers). I tried lots of solutions but I ended up with shibd and Apache web server. So, shibd + Apache and a little shib.php file that would grab whatever shibd environment there is after successful authentication, put it in a memcache and redirect the browser to my original rails app. Here's how my shib.php looks like: <?php $REDIRECT_URL = 'https://rails.app.example.org/_shib'; $MEMCACHE_HOST = 'memcache.host'; $MEMCACHE_PORT = 11211; # connect to memcache server $memcache = new Memcache; $memcache->connect($MEMCACHE_HOST, $MEMCACHE_PORT) or die ("Could not connect"); # create a temp saml session object from shibd environment variables $saml = new stdClass; $saml->provider = $_SERVER['Shib-Identity-Provider']; $saml->common_name = $_SERVER['CommonName']; $saml->given_name = $_SERVER['givenName']; $saml->surname = $_SERVER['surname']; $saml->edu_person_scoped_affiliation = $_SERVER['eduPersonScopedAffiliation']; $saml->uid = $_SERVER['uid']; $saml->email = $_SERVER['mail']; $saml->principal_name = $_SERVER['principalName']; $shib_session_id = $_SERVER['Shib-Session-ID']; # store this object in the memcache with 60 sec expiration $cache_key = 'samlsess:' . $shib_session_id; $memcache->set($cache_key, json_encode($saml), 0, 60) or die ("Failed to store data in memcache"); # send redirect to the rails app that will fetch the above object from the memcache header('Location: ' . $REDIRECT_URL . '?s=' . $shib_session_id); ?> So, the browser gets redirected to a URL handled by my rails app, a custom Devise strategy specifically: # lib/devise/strategies/shibboleth_authenticatable.rb require 'json' module Devise module Strategies class ShibAuthError < RuntimeError; end class ShibbolethAuthenticatable < Devise::Strategies::Base # check public/samlsession/index.php for full set of attributes SAML_ATTRIBUTES = %w(provider given_name surname uid email idada) # The request should go something like http://HOST/login?s=_23418cd2aadf # where s parameter is a key of the auth (usually memcached) data coming from shibd def valid? params[:s].present? end # Method that actually decides whether we'll let the user in def authenticate! # fetch raw data from the cache shib_session = Rails.cache.read(params[:s], :raw => true).to_s auth_hash = JSON.parse shib_session # sometimes IdP wasn't returning all the attributes # so just to make sure we have them all validate_saml_attributes! auth_hash # find existing user or create a new one since we always trust # our IdP resource = mapping.to.find_or_initialize_by_ada_id(auth_hash['idada']) if resource.new_record? # set SAML_ATTRIBUTES in the newly built user resource.update_from_saml auth_hash # store the new user or raise an exception raise(ShibAuthError, 'An error occured during new user creation') unless resource.save end # successfully authenticated success! resource rescue JSON::ParserError, ShibAuthError Rails.logger.error("[ShibbolethAuthenticatable] ERROR during _shib authentication: #{$!}") fail(:invalid) unless halted? end private # Checks the presence of all the attributes, # otherwise raises an exception def validate_saml_attributes!(auth_hash) raise(ShibAuthError, "No SAML attributes provided") unless auth_hash SAML_ATTRIBUTES.each { |a| raise(ShibAuthError, "#{a} SAML attribute is missing") if auth_hash[a].blank? } end end end end I can wrap this in a sample rails app and opensource it if enough people are interested. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/rU2y9_fq8ZEJ. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.

