我正在尝试重写使用 PHP/MySQL 创建的旧应用程序。使用的身份验证系统在数据库中有一个用户表,其中存储用户名、电子邮件等......但不存储密码。
每当用户登录时,它首先检查数据库以查看用户是否存在,如果不存在则返回登录错误。如果用户存在于本地数据库中,则它会尝试使用用户输入的用户名/密码组合绑定到活动目录,如果成功则创建会话。
使用 Rails 完成此任务的最佳方法是什么?
我正在尝试重写使用 PHP/MySQL 创建的旧应用程序。使用的身份验证系统在数据库中有一个用户表,其中存储用户名、电子邮件等......但不存储密码。
每当用户登录时,它首先检查数据库以查看用户是否存在,如果不存在则返回登录错误。如果用户存在于本地数据库中,则它会尝试使用用户输入的用户名/密码组合绑定到活动目录,如果成功则创建会话。
使用 Rails 完成此任务的最佳方法是什么?
Ruby 的 Net::LDAP 库非常好。
这是我多年来一直使用的简化版本:
# sessions_controller.rb
def create
user = User.find_by_login(params[:login])
if user && Ldap.authenticate(params[:login], params[:password])
self.current_user = user
Rails.logger.info "Logged in #{user.name}"
flash[:notice] = "Successfully Logged In!"
redirect_back_or_default root_url
else
flash[:alert] = "Invalid User credentials"
render :new
end
end
# lib/ldap.rb
# Ldap.authenticate('user','password')
# Returns true if validated
# Returns false if invalidated
# Returns nil if LDAP unavailable
require 'net/ldap'
class Ldap
def self.config
# this is actually loaded from a yaml config file
{
:domain => 'YOURDOMAIN',
:host => '10.10.10.100'
}
end
def self.authenticate(login, password)
conn = Net::LDAP.new(
:host => config[:host],
:port => 636,
:base => "dc=#{config[:domain]}, dc=local",
:encryption => :simple_tls,
:auth => {
:username => "#{login}@#{config[:domain]}.local",
:password => password,
:method => :simple
}
)
Timeout::timeout(15) do
return conn.bind ? true : false
end
rescue Net::LDAP::LdapError => e
notify_ldap_admin(config[:host],'Error',e)
nil
rescue Timeout::Error => e
notify_ldap_admin(config[:host],'Timeout',e)
nil
end
def self.notify_ldap_admin(host,error_type,error)
msg = "LDAP #{error_type} on #{host}"
RAILS_DEFAULT_LOGGER.debug(msg)
DeveloperMailer.deliver_ldap_failure_msg(msg,error)
end
end