Ldap Through Ruby or Rails

LDAP through Ruby or Rails

Here is sample code I use with the net-ldap gem to verify user logins from the ActiveDirectory server at my work:

require 'net/ldap' # gem install net-ldap

def name_for_login( email, password )
email = email[/\A\w+/].downcase # Throw out the domain, if it was there
email << "@mycompany.com" # I only check people in my company
ldap = Net::LDAP.new(
host: 'ldap.mycompany.com', # Thankfully this is a standard name
auth: { method: :simple, email: email, password:password }
)
if ldap.bind
# Yay, the login credentials were valid!
# Get the user's full name and return it
ldap.search(
base: "OU=Users,OU=Accounts,DC=mycompany,DC=com",
filter: Net::LDAP::Filter.eq( "mail", email ),
attributes: %w[ displayName ],
return_result:true
).first.displayName.first
end
end

The first.displayName.first code at the end looks a little goofy, and so might benefit from some explanation:

  • Net::LDAP#search always returns an array of results, even if you end up matching only one entry. The first call to first finds the first (and presumably only) entry that matched the email address.

  • The Net::LDAP::Entry returned by the search conveniently lets you access attributes via method name, so some_entry.displayName is the same as some_entry['displayName'].

  • Every attribute in a Net::LDAP::Entry is always an array of values, even when only one value is present. Although it might be silly to have a user with multiple "displayName" values, LDAP's generic nature means that it's possible. The final first invocation turns the array-of-one-string into just the string for the user's full name.

How to Ruby on Rails authentication with LDAP?

Here's a utility class I've used in the past to do multi-server LDAP check:

require 'net/ldap'

# Ldap.authenticate('user', 'password')
# => `true` if valid
# => `false` if invalid
# => `nil` if LDAP unavailable

class Ldap
def self.config
{
domain: 'mydomain',
servers: ['server1', 'server2']
}
end

def self.authenticate(login, pass)
return false if login.empty? or pass.empty?
config['servers'].each do |server|
auth = authenticate_against_server(login, pass, server, config['domain'])
return auth unless auth.nil?
end
nil
end

private

def self.authenticate_against_server(login, pass, host, domain)
conn = Net::LDAP.new(
host: host,
port: 636,
base: "dc=#{domain}, dc=local",
encryption: :simple_tls,
auth: { username: "#{login}@#{domain}.local",
password: pass,
method: :simple }
)
Timeout::timeout(15) do
return conn.bind ? true : false
end
rescue Net::LDAP::LdapError => e
notify_ldap_admin(host, 'Error', e)
return nil
rescue Timeout::Error => e
notify_ldap_admin(host, 'Timeout', e)
return 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

Using ldap to connect to ad with devise ruby on rails

Turns out my company has a different way of authorizing a user. I added the advanced flag to my devise ldap install, and set this accordingly and presto it worked.

==> Advanced LDAP Configuration

config.ldap_auth_username_builder = Proc.new() {|attribute, login, ldap| "#{login}@mydomain.com"}

I have an ldap connection on my RoR app but now how do I check users on login?

You could create a service that handles that process:

app/services/authenticate_user.rb

class AuthenticateUser
def initialize(user, password)
@user = user
@password = password
end

def call
user_is_valid?
end

private
def user_is_valid?
ldap = Net::LDAP.new
ldap.host = your_server_ip_address
ldap.port = 389
ldap.auth(@user, @password)
ldap.bind
end
end

Then use it in your controller:

class SessionsController < ApplicationController
def new
end

def create
username = params[:NumeroEmpregado]
password = params[:password]
name = "Some Name" # Change "Some Name" to set the correct name

if AuthenticateUser.new(username, password).call
user = User.create_with(nome: name).find_or_create_by(NumeroEmpregado: username)
session[:user_id] = user.id
redirect_to '/'
else
flash[:error] = "Erro! \nNúmero de Empregado e/ou password incorrecto(a)"
redirect_to '/login'
end
end

def destroy
session[:user_id] = nil
redirect_to '/index/new'
end
end

AuthenticateUser.new(user, password).call will return true when valid user and password are provided, and will return false otherwise.

This is a basic example covering only the LDAP authentication, you will need to adapt it for your specific needs, including exception handling.

Ruby on Rails: LDAP user operations


read the documentation of the
gem(https://github.com/cschiewek/devise_ldap_authenticatable)

add in initializer config/initializers/devise.rb

ldap_create_user (default: false)

If set to true, all valid LDAP users will be allowed to login 
and an appropriate user record will be created. If set to false, you will

have to create the user record before they will be allowed to login.

Ruby on Rails - LDAP based authentication

Check out .bind_as: According to the docs
http://www.rubydoc.info/gems/ruby-net-ldap/Net/LDAP#bind_as-instance_method
it is for testing authentication credentials.

Ruby with LDAP or AD

ActiveDirectory is an implementation of the LDAP. You can use the RubyLDAP gem to integrate with AD. I am currently using this gem to connect from a RHEL server to a Windows Domain Controller.

gem install ruby-ldap


Related Topics



Leave a reply



Submit