使用多个ou =位置的devise_ldap_authenticatable

时间:2014-03-04 18:53:28

标签: ruby-on-rails ruby ruby-on-rails-3 devise ldap

我正在尝试将devise_ldap_authenticatable集成到我的应用中。我们公司拥有ldap服务器,可以为不同地点的用户提供相关信息。这些服务器中的数据不重叠。我的问题是我无法使用devise_ldap_authenticatable gem来使用我们的ldap搜索树。我只能指定一个ou =。 ldap.yml文件中丢失了任何搜索路径的意义。以下ldap文件有效,但仅适用于cityMain中的用户。

development:
  host: ldap.myCompany.com
  port: <port>
  attribute: uid
  base: ou=people,ou=cityMain,dc=myCompany,dc=com
  admin_user: uid=proxy-generic,ou=cityMain,dc=myCompany,dc=com
  admin_password: pw
  ssl: true

如果我将cityMain更改为city1,则只有city1中的用户才能登录。我需要做的是两件事之一。

1)使用我们的IT部门提供的ldap.conf文件

-OR -

2)允许多个位置,可能带有ldap过滤器语句(即:

development:
  host: ldap.myCompany.com
  port: <port>
  attribute: uid
  base: ou=people,(|(ou=city1)(ou=city2)(ou=city3)(ou=city4)(ou=cityMain)),dc=myCompany,dc=com
  admin_user: uid=proxy-generic,ou=cityMain,dc=myCompany,dc=com
  admin_password: pw
  ssl: true

截至目前,我无法使用第二个代码段中的过滤器登录。提前谢谢你看这个。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

我找到了一个解决方法。我编辑了devise_ldap_adapter以接受一系列基本配置。在ldap.yml文件中:

base: ou=people,ou=cityMain,dc=myCompany,dc=com

变为

base: ["ou=people,ou=cityMain,dc=myCompany,dc=com",
       "ou=people,ou=city1,dc=myCompany,dc=com",
       "ou=people,ou=city2,dc=myCompany,dc=com",
       "ou=people,ou=city3,dc=myCompany,dc=com",
       "ou=people,ou=city4,dc=myCompany,dc=com"]

然后编辑devise_ldap_authenticatable ldap_adapter.rb文件以迭代这些基本数组元素:

    def self.valid_credentials?(login, password_plaintext)
      ldap_config = YAML.load(ERB.new(File.read(::Devise.ldap_config || "#              {Rails.root}/config/ldap.yml")).result)[Rails.env]
  options = {:login => login,
             :password => password_plaintext,
             :ldap_auth_username_builder => ::Devise.ldap_auth_username_builder,
             :admin => ::Devise.ldap_use_admin_to_bind}
  resource = LdapConnect.new(options)
  resource.authorized?           
end

变为:

    def self.valid_credentials?(login, password_plaintext)
  ldap_config = YAML.load(ERB.new(File.read(::Devise.ldap_config || "#{Rails.root}/config/ldap.yml")).result)[Rails.env]
  bases = ldap_config["base"]
  options = {:login => login,        
             :password => password_plaintext,       
             :ldap_auth_username_builder => ::Devise.ldap_auth_username_builder,
             :admin => ::Devise.ldap_use_admin_to_bind}
  bases.each do |base|      
    # Initializer now accepts a second parameter: base
    resource = LdapConnect.new(options, base)
    if resource.authorized?
      return true
    end
  end
  false
end

编辑初始化程序以接受第二个参数“base”并将值赋给@ ldap.base

def initialize(params = {}, base)
  # def initialize(params = {})
    ldap_config = YAML.load(ERB.new(File.read(::Devise.ldap_config || "#{Rails.root}/config/ldap.yml")).result)[Rails.env]
    ldap_options = params
    ldap_config["ssl"] = :simple_tls if ldap_config["ssl"] === true
    ldap_options[:encryption] = ldap_config["ssl"].to_sym if ldap_config["ssl"]

    @ldap = Net::LDAP.new(ldap_options)
    @ldap.host = ldap_config["host"]
    @ldap.port = ldap_config["port"]
    # Use base parameter here
    @ldap.base = base
    # @ldap.base = ldap_config["base"]
    @attribute = ldap_config["attribute"]
    @ldap_auth_username_builder = params[:ldap_auth_username_builder]

    @group_base = ldap_config["group_base"]
    @required_groups = ldap_config["required_groups"]        
    @required_attributes = ldap_config["require_attribute"]

    @ldap.auth ldap_config["admin_user"], ldap_config["admin_password"] if params[:admin] 
    @login = params[:login]
    @password = params[:password]
    @new_password = params[:new_password]

  end
鲍勃是你的叔叔。