Search code examples
ruby-on-railsdevisewarden

Rails app local and remote authentication with Devise ( 2 strategies )


I am trying to setup 2 authentification strategies using Devise the standard one ( :database_authenticable ) and if this one fails another try is performed against another remote server :remote ( as described http://4trabes.com/2012/10/31/remote-authentication-with-devise/ )

if I add in my devise.rb initializer the config.warden block

config.warden do |manager|
  manager.strategies.add(:remote, Devise::Strategies::RemoteAuthenticatable)
  manager.default_strategies(:scope => :user).unshift :remote
end

then :remote becomes the default strategy, but this not what I am looking for .. I would like to have first Devise::Strategies::DatabaseAuthenticatable then if it fails Devise::Strategies::RemoteAuthenticatable

I know it's possible as warden accepts cascading strategies.... as described at https://github.com/hassox/warden/wiki/Strategies Using strategies..

but I don't see how to implement it ...


Solution

  • the warden block in devise initializer defines an array of strategies in warden config,

    require 'devise/strategies/remote_authenticable'
    
    config.warden do |manager|
     manager.strategies.add(:remote, Devise::Strategies::RemoteAuthenticatable)
     manager.default_strategies(:scope => :user).unshift :remote
    end
    

    however the :remote strategy is listed as first...

        # warden.config[:default_strategies][:user] =>  [:remote, :rememberable, :database_authenticatable]
    

    so I modified the #createaction in my users/sessions_controller, to move :remote to the end of the list

    # POST /resource/sign_in
    def create
        warden.config[:default_strategies][:user].push(warden.config[:default_strategies][:user].shift)
        self.resource = warden.authenticate!(auth_options)
    

    now, user authentication starts wit Devise ( :rememberable, :database_authenticable) and if it fails , then authentication on the remote server is tried with :remote_authenticable