How to Ruby on Rails Authentication with Ldap

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

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.

Rails authentication with LDAP and local database

Ruby's Net::LDAP library is pretty good.

Here's a simplified version of what I've been using for years:

# 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

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.

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.

Net/LDAP gem and basic auth in Rails 4 app

Have you looked at the Gem devise_ldap_authenticatable.I guess it better suits your requirement.Instead of using your own authentication system, you could use LDAP(Active directory) as an authentication provider.

If you are building applications for use within your organization
which require authentication and you want to use LDAP, this plugin is
for you.

Devise LDAP Authenticatable works in replacement of Database
Authenticatable. This devise plugin has not been tested with
DatabaseAuthenticatable enabled at the same time. This is meant as a
drop in replacement for DatabaseAuthenticatable allowing for a semi
single sign on approach.

SAML based single sign on is also popularly renowned way of transmitting authentication and authorization information as an XML. Service Provider(You) can leverage Identity Provider(Active directory- perhaps ADFS) for authentication purposes. Ruby-SAML by onelogin is well known gem for SAML implementation.

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"}


Related Topics



Leave a reply



Submit