Ruby on Rails 3:Devise :: LdapAdapter.get_ldap_param未定义的方法错误 [英] Ruby on Rails 3: Devise::LdapAdapter.get_ldap_param undefined method error

查看:241
本文介绍了Ruby on Rails 3:Devise :: LdapAdapter.get_ldap_param未定义的方法错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在运行:
Ruby 1.9.3p0,
Rails 3.1.1,
Devise 1.4.9,
Devise_ldap_authenticatable 0.4.10



我正在使用Devise通过ldap服务器验证我的Rails应用程序。我正在使用用户名而不是电子邮件进行身份验证,所以我的表格中的电子邮件字段当然是空白的。



要查询ldap的电子邮件,官方的方式是在用户模型中添加此代码:

  before_save:get_ldap_email 
def get_ldap_email
self.email = Devise :: LdapAdapter.get_ldap_param(self.username,mail)
end

此代码无法尝试对ldap执行任何操作,具体如下:

 未定义的方法`mail'为nil:NilClass 

它指的是方法定义中的行。日志输出没有帮助:

 在2011-11-15开始POST/ users / sign_in为10.50.1.96 11:18:16 -0800 
处理Devise :: SessionsController#create as HTML
参数:{utf8=>✓,authenticity_token=>< hidden> = ,user=> {username=>< hidden>,password=>[FILTERED],remember_me=>0},commit=> ;登录}
用户加载(0.9ms)SELECTusers。* FROMusersWHEREusers。username='< hidden>'LIMIT 1
LDAP:LDAP dn lookup:uid =< hidden>
LDAP:LDAP搜索登录名:uid =< hidden>
LDAP:授权用户< hidden>
LDAP:LDAP dn lookup:uid =< hidden>
LDAP:LDAP搜索登录:< hidden>
完成251内部服务器错误251ms

NoMethodError(未定义的方法`mail'for nil:NilClass):
app / models / user.rb:14:在`get_ldap_email'

500错误之前的所有行都是与电子邮件查询无关的正常LDAP成功身份验证。



上周我开始学习Ruby,Rails和Devise,所以我不知道什么文件是最有说服力的,但这里是我的user.rb模型和gemfile:

  class User< ActiveRecord :: Base 
#包含默认设计模块。其他可用的是:
#:token_authenticatable,:encryptable,:confirmable,:lockable,:timeoutable和:omniauthable
devise:ldap_authenticatable,:可注册,
:可恢复,可记忆, :validatable

before_save:get_ldap_email

#模型的可访问(或保护)属性
attr_accessible:email,:username,:password,:password_confirmation, remember_me

def get_ldap_email
self.email = Devise :: LdapAdapter.get_ldap_param(self.username,mail)
end
end

宝石文件:

  source'http://rubygems.org'

gem'rails','3.1.1'

#捆绑边Rails代替:
#gem' rails',:git => 'git://github.com/rails/rails.git'

gem'sqlite3'


< ... unrelated ...>

gem'therubyracer',:platforms => :ruby
gemdevise
gemdevise_ldap_authenticatable

我试过重新启动服务器,并从最后一次GemFile更新完成捆绑安装。我的配置有ldap_create_user = true,用户名是用户中正确的字段名称。那个方法有错误吗?是否有版本不兼容?我真的不知道还有什么要检查的,而且rails让我没有什么新手可以继续下去。我会喜欢一些帮助。

解决方案

我也遇到这个问题 - 我目前的临时解决方案是获取数据我使用 Net :: LDAP 而不是 ldap_authenticatable 类。当然,更永久的解决方案是修补 ldap_authenticatable ,我可能会尝试下一步。



问题(至少对我而言)是这样的:在通过 ldap_authenticatable 代码(即ldap_adapter.rb)之后,我发现 get_ldap_param 方法在尝试获取参数时不会与服务器进行身份验证,除非在 admin_user admin_password 中指定ldap.yml。因此,如果您的LDAP服务器允许匿名读取数据,那么 get_ldap_param 将按照广告的方式工作。在OpenLDAP(这是我用于本地测试的)中,匿名读取访问权限设置为slapd.conf中的访问属性:

 通过匿名auth访问* 

但是,我的公司LDAP不



需要使用auth参数创建 ldap_authenticatable 中的Net :: LDAP实例参数提取,但不是。没有给出验证参数,因此不会返回任何结果。



所以暂时的,我的User模型中有以下代码,调用 get_ldap_data as a before_save filter:

  def has_ldap_data? 
[self.email,self.first_name,self.last_name] .none? {| V | v.nil?}
end

def get_ldap_data
如果has_ldap_data返回true?还是self.password.nil?

ldap = create_ldap
ldap.search(
:base => ldap.base,
:attributes => ['cn','sn' 'givenname','mail'],
:filter => Net :: LDAP :: Filter.eq('cn',self.username),
:return_result => true)do |进入|
self.email = entry.mail.first
self.first_name = entry.givenname.first
self.last_name = entry.sn.first
end

has_ldap_data?
end

def create_ldap(password = nil)
ldap_config = ldap_config = YAML.load(ERB.new(File.read(:: Devise.ldap_config ||#{ Rails.root} /config/ldap.yml))。)result)[Rails.env]
ldap_options = {
:host => ldap_config [host],
:port => ldap_config [port],
:base => ldap_config [base],
:auth => {
:method => :简单,
:username => cn =#{self.username},#{ldap_config ['base']},
:password =>密码|| self.password
}
}

ldap_config [ssl] =:simple_tls if ldap_config [ssl] === true
ldap_options [:encryption] = ldap_config [ssl]。to_sym if ldap_config [ssl]

Net :: LDAP.new(ldap_options)
end
/ pre>

根据您的特定需求进行修改。这不是理想的,但现在直到分岔/修补 ldap_authenticatable 才能解决这个用例。


I am running: Ruby 1.9.3p0, Rails 3.1.1, Devise 1.4.9, Devise_ldap_authenticatable 0.4.10

I am using Devise to authenticate my Rails application via an ldap server. I am using username instead of email to authenticate, so naturally the email field in my table is blank.

To query the ldap for email, the official way is to add this code in the user model:

before_save :get_ldap_email
def get_ldap_email
  self.email = Devise::LdapAdapter.get_ldap_param(self.username,"mail")
end

This code fails, without attempting to do anything with the ldap, with this:

undefined method `mail' for nil:NilClass

It refers to the line inside the method definition. The log output is no more helpful:

Started POST "/users/sign_in" for 10.50.1.96 at 2011-11-15 11:18:16 -0800
Processing by Devise::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"<hidden>=", "user"=>{"username"=>"<hidden>", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Sign in"}
User Load (0.9ms)  SELECT "users".* FROM "users" WHERE "users"."username" = '<hidden>' LIMIT 1
  LDAP: LDAP dn lookup: uid=<hidden>
  LDAP: LDAP search for login: uid=<hidden>
  LDAP: Authorizing user <hidden>
  LDAP: LDAP dn lookup: uid=<hidden>
  LDAP: LDAP search for login: <hidden>
Completed 500 Internal Server Error in 251ms

NoMethodError (undefined method `mail' for nil:NilClass):
  app/models/user.rb:14:in `get_ldap_email'

All lines previous to the 500 error are normal LDAP successful authentication that are unrelated to the the email query.

I started learning Ruby, Rails, and Devise just last week, so I'm not sure what files would be the most telling, but here is my user.rb model and gemfile:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
  devise :ldap_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  before_save :get_ldap_email

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :username, :password, :password_confirmation, :remember_me

  def get_ldap_email
    self.email = Devise::LdapAdapter.get_ldap_param(self.username,"mail")
  end
end

And the gemfile:

source 'http://rubygems.org'

gem 'rails', '3.1.1'

# Bundle edge Rails instead:
# gem 'rails',     :git => 'git://github.com/rails/rails.git'

gem 'sqlite3'


<... unrelated ...>

gem 'therubyracer', :platforms => :ruby
gem "devise"
gem "devise_ldap_authenticatable"

I have tried restarting the server, and have done a bundle install since the last GemFile update. My configuration has ldap_create_user = true and username is the correct field name in users. Is there an error in that method? Could there be a version incompatibility? I'm not really sure what else to check, and rails is giving me nothing beginner-friendly to go on. I would love some help with this.

解决方案

I'm also having this problem - my current temporary solution is to fetch the data myself using Net::LDAP instead of the ldap_authenticatable classes. The more permanent solution would, of course, be to patch ldap_authenticatable, which I may try to do next.

The issue (at least for me) was this: After poring through the ldap_authenticatable code (namely ldap_adapter.rb) I discovered that the get_ldap_param method is not authenticating with the server when trying to fetch the params unless admin_user and admin_password are specified in ldap.yml. So, if your LDAP server allows anonymous reading of data, then get_ldap_param will work as advertised. On OpenLDAP (which is what I use for local testing), anonymous read access is set with the "access to" property in slapd.conf:

access to *
  by anonymous auth

But, my corporate LDAP does not allow that.

The Net::LDAP instance in ldap_authenticatable needs to be created with auth parameters when being used for parameter fetching, but it's not. No auth parameters are given, so no results are returned.

So, temporarily, I have the following code in my User model, calling get_ldap_data as a before_save filter:

def has_ldap_data?
  [self.email, self.first_name, self.last_name].none? {|v| v.nil?}
end

def get_ldap_data
  return true if has_ldap_data? or self.password.nil?

  ldap = create_ldap
  ldap.search(
    :base => ldap.base,
    :attributes => ['cn', 'sn', 'givenname', 'mail'],
    :filter => Net::LDAP::Filter.eq('cn', self.username),
    :return_result => true) do |entry|
      self.email = entry.mail.first
      self.first_name = entry.givenname.first
      self.last_name = entry.sn.first
  end

  has_ldap_data?
end

def create_ldap(password = nil)
  ldap_config = ldap_config = YAML.load(ERB.new(File.read(::Devise.ldap_config || "#{Rails.root}/config/ldap.yml")).result)[Rails.env]
  ldap_options = {
    :host => ldap_config["host"],
    :port => ldap_config["port"],
    :base => ldap_config["base"],
    :auth => {
      :method => :simple,
      :username => "cn=#{self.username},#{ldap_config['base']}",
      :password => password || self.password
    }
  }

  ldap_config["ssl"] = :simple_tls if ldap_config["ssl"] === true
  ldap_options[:encryption] = ldap_config["ssl"].to_sym if ldap_config["ssl"]

  Net::LDAP.new(ldap_options)
end

Modify per your particular needs. It's not ideal, but works for now until forking/patching ldap_authenticatable to account for this use case.

这篇关于Ruby on Rails 3:Devise :: LdapAdapter.get_ldap_param未定义的方法错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆