4

我正在尝试编写一种设计身份验证策略来针对现有的旧 API 进行身份验证。我没有数据库,所以我无法从某些现有来源迁移用户。我想做类似的事情:

http://4trabes.com/2012/10/31/remote-authentication-with-devise/

但是,按照这些说明操作后,Devise 拒绝调用我的身份验证策略。我已经通过尝试将 puts 调用插入到我的 RemoteAuthenticatable 模块中来对此进行测试...

彼得。

根据要求编辑添加代码。

应用程序/模型/User.rb:

class User
  attr_accessor :id

  include ActiveModel::Validations #required because some before_validations are defined in devise
  extend ActiveModel::Callbacks #required to define callbacks
  extend Devise::Models

  define_model_callbacks :validation #required by Devise

  devise :remote_authenticatable
end

lib/remote_authenticatable.rb (注意我插入的puts以获得一些穷人的追踪)。

module Devise
  module Models
    module RemoteAuthenticatable
      extend ActiveSupport::Concern

      #
      # Here you do the request to the external webservice
      #
      # If the authentication is successful you should return
      # a resource instance
      #
      # If the authentication fails you should return false
      #
      def remote_authentication(authentication_hash)
        puts "In Devise::Models::RemoteAuthenticatable.remote_authentication()"
        # Your logic to authenticate with the external webservice
      end

      module ClassMethods
        ####################################
        # Overriden methods from Devise::Models::Authenticatable
        ####################################

        #
        # This method is called from:
        # Warden::SessionSerializer in devise
        #
        # It takes as many params as elements had the array
        # returned in serialize_into_session
        #
        # Recreates a resource from session data
        #
        def serialize_from_session(id)
          resource = self.new
          resource.id = id
          resource
        end

        #
        # Here you have to return and array with the data of your resource
        # that you want to serialize into the session
        #
        # You might want to include some authentication data
        #
        def serialize_into_session(record)
          [record.id]
        end

      end
    end
  end

  module Strategies
    class RemoteAuthenticatable < Authenticatable
      def valid?
        puts "In Devise::Strategies::RemoteAuthenticatable.valid?()"
        true
      end

      #
      # For an example check : https://github.com/plataformatec/devise/blob/master/lib/devise/strategies/database_authenticatable.rb
      #
      # Method called by warden to authenticate a resource.
      #
      def authenticate!
        puts "In Devise::Strategies::RemoteAuthenticatable.authenticate!()"
        #
        # authentication_hash doesn't include the password
        #
        auth_params = authentication_hash
        auth_params[:password] = password

        #
        # mapping.to is a wrapper over the resource model
        #
        resource = mapping.to.new

        return fail! unless resource

        # remote_authentication method is defined in Devise::Models::RemoteAuthenticatable
        #
        # validate is a method defined in Devise::Strategies::Authenticatable. It takes
        #a block which must return a boolean value.
        #
        # If the block returns true the resource will be loged in
        # If the block returns false the authentication will fail!
        #
        if validate(resource){ resource.remote_authentication(auth_params) }
          success!(resource)
        end
      end
    end
  end
end

以及我添加到 config/initializers/devise.rb 的代码

  require 'remote_authenticatable'  

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

  Devise.add_module :remote_authenticatable, :controller => :sessions,  :route => { :session => :routes }
4

4 回答 4

0

您可以尝试删除对

manager.strategies.add

而是在您的策略文件末尾添加此调用

Warden::Strategies.add(:rememberable, Devise::Strategies::RemoteAuthenticatable)
于 2013-05-08T21:20:47.193 回答
0

我将 remote_authenticable.rb (model) 添加到 app > models >关注> devise > models,并插入了一个调试器语句来检查它是否被正确调用

def remote_authentication(authentication_hash)
  debugger
  false 
  # Your logic to authenticate with the external webservice
end

将 remote_authenticable.rb (strategy) 放入 lib > devise > strategy

并将warden块添加到devise.rb(初始化程序)

require "devise/strategies/remote_authenticable.rb"

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

它运行...

于 2013-08-20T17:11:42.267 回答
0

在 config/initializers/devise.rb 你写了这个

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

现在在同一目录中创建另一个文件,即“remote.rb”并添加类似这样的内容

Warden::Strategies.add(:remote) do 
 def valid? 
 true
end 

def authenticate! 

  if params[:user]
    user = User.find_by_login_name(params[:user][:login_name])

    if user && user.account_status != "active" # add your own checks here for authentication 
      fail
      halt! #after this succes no other authentication will process
    end
  else
    fail
  end 
 end
end
于 2013-10-30T07:42:25.737 回答
0

按照相同的教程,这对我有用:

将 remote_authenticatable 代码分解为:/lib/devise/models/remote_authenticatable.rb 和 /lib/devise/strategies/remote_authenticatable.rb

在 config/initializers/devise.rb 我添加了

require 'devise/orm/active_record'
require "devise/strategies/remote_authenticatable"
require "devise/models/remote_authenticatable"

Devise.add_module :remote_authenticatable, :controller => :sessions, :route => { :session => :routes }

在 Devise.setup 下:

config.warden do |manager|
 manager.strategies.add(:remote, Devise::Strategies::RemoteAuthenticatable)
 manager.default_strategies(:scope => :user).unshift :remote
end
于 2014-03-24T15:14:46.750 回答