This page needs wiki gardening.
It needs more than gardening; 98 percent of information here is outdated and invalid now.
Using the ActiveLDAP library, it’s relatively easy to set up your Rails app to authenticate via LDAP. Of course, you’ll need to have ActiveLDAP installed on your system, which you can get via RubyGems:
gem install ruby-activeldap
ActiveLDAP requires the Ruby-LDAP extension library which can be downloaded here.
It also requires the ‘log4r’ rubygem which you will be prompted to install as a dependency.
I was having issues with log4r not loading so I had to alter the require line in lib/activeldap/base.rb to use the log4r rubygem per the log4r documentation.
So instead of
require 'log4r'
You have
require 'rubygems' require_gem 'log4r'
In order to get this working, I actually had to unpack the gem once it was installed and move the contents of its “lib” folder inside my app’s “lib”. I don’t know if that’s the easiest way to do it, but it worked for me.
Example: You could do something like the following, from your application root:
cd lib gem unpack ruby-activeldap cp -a ruby-activeldap-<version>/lib/* . rm -rf ruby-activeldap-<version> </pre>Once you have ActiveLDAP installed on your system, the next step is to add it to the environment in your app. Add the following line somewhere in your config/environment.rb or config/root.rb (depending on your version of Rails):
require 'active_ldap'Now, create a model (File app/models/ldap_user.rb) for your LDAP-user, and define a method for authenticating against the LDAP server:
class LdapUser < ActiveLdap:Base ldap_mapping :prefix => "cn=users" def self.login(username, password) ActiveLdap::Base.connect \ :host => "ldap.yourserver.com", :port => 389, :base => "dc=your,dc=base", :bind_format => "uid=#{username},cn=users,dc=your,dc=ldap,dc=binding,dc=config,dc=com", :password_block => Proc.new { password }, :allow_anonymous => false return true rescue ActiveLdap::AuthenticationError return false ensure ActiveLdap::Base.close end endIn this case, the method takes the user’s login name and password as parameters, and uses them to attempt to connect to the LDAP server. If the login succeeds, it closes the connection and returns true. If it fails, it catches the error and returns false.
Now you have an LDAP-based login method that you can build into your controllers. Most of the rest of my code was based on the HowtoAuthenticate page, which gives a good overview of how to protect your controllers.
The only other difference with my code is that I used cookies rather than session variables so my users could stay logged in longer. :). Do not use cookies, this makes your site vulnerable to attack.For what it’s worth, here’s how my controllers look.
Application:
# The filters added to this controller will be run for all controllers in the application.
# Likewise will all the methods added be available for all controllers.
class ApplicationController < ActionController::Base protected def authenticate #changed from cookie to session unless session[:login] @session[:return_to] = @request.request_uri redirect_to :controller => “login” return false end end endConcern: I’m not an expert, but isn’t using the presence of the plaintext username in a cookie as the indicator of authenticated state vulnerable to dishonest cookies? Seems like storing it in the session hash would be secure. Fixed
Login Controller:
class LoginController < ApplicationController
def index
render :action => “login”
end def login # the actual login form if @params[:login] @values = @params[:login] if LdapUser.login(@values[:un], @values[:pw]) cookies[:login] = {:value => @values[:un], :expires => Time.now+31536000} else flash[:notice] = “Incorrect!” end else flash[:notice] = “no params?” end redirect_to @session[:return_to] end endOnce you have all that in place, all you need to do is add a call to
before_filterto the top of each controller you want to password protect, like so:class ProtectedController < ApplicationController before_filter :authenticate endThat’s it!
note: There is now a pure ruby LDAP library that is much more simple to use than activeldap. See HowtoAuthenticateWithRubyNetLdap.
Great!
Q: So, what does your login.rhtml look like?A: Here’s a basic example that works for me (LeahCunningham):
<div class='portlet'> <table border='0' cellspacing='0' cellpadding='5'> <tr> <caption> Authentication <%= form_tag :action => “login” %>User <%= text_field(:login, :un) %> Password <%= password_field(:login, :pw) %> <%= end_form_tag %>
begin 2006-04-08 DelayedGreen
I have some problems with this authentication method:
Forunately, ruby/ldap can maintain multiple connections, and to mutiple servers. No need to use ActiveLDAP for this simple task.
end 2006-04-08 DelayedGreen
BEGIN 8/30/06 paul@nelkin.net
I used the following for my LDAP Authentication (less than 10 Lines of Code!!)
require 'ldap'
ldap_host = ‘mail.host.com’
ldap_port = 389
begin
ldap_conn = LDAP::Conn.new(“mail.host.com”, 389)
ldap_conn.set_option( LDAP::LDAP_OPT_PROTOCOL_VERSION, 3 )
pass=“yourpassword”
ldap_conn.bind( “uid=youruserid,cn=users,dc=yourbase,dc=com”, pass )
end
Of course for uid and pass you would specify either a specific username and password, or define a variable.
**END 8/30/06
Questions
Answer:
No Answer Yet.
Answer:
It doesn’t. It uses only Ruby’s built in ldap support. If all you wish to do is authenticate login
using LDAP, active_ldap is overkill, as all you really
need to do is some variation of the above.
Not sure what you mean by an easier way. If you are familiar with RoR this shouldn’t be too difficult. Just use paul@nelkin.net code, it worked for me!
eric-at-erichayes-dot-net note:
With ActiveLDAP 0.8.3.1 I had to require with an underscore:
require ‘active_ldap’
This page needs wiki gardening.
It needs more than gardening; 98 percent of information here is outdated and invalid now.
Using the ActiveLDAP library, it’s relatively easy to set up your Rails app to authenticate via LDAP. Of course, you’ll need to have ActiveLDAP installed on your system, which you can get via RubyGems:
gem install ruby-activeldap
ActiveLDAP requires the Ruby-LDAP extension library which can be downloaded here.
It also requires the ‘log4r’ rubygem which you will be prompted to install as a dependency.
I was having issues with log4r not loading so I had to alter the require line in lib/activeldap/base.rb to use the log4r rubygem per the log4r documentation.
So instead of
require 'log4r'
You have
require 'rubygems' require_gem 'log4r'
In order to get this working, I actually had to unpack the gem once it was installed and move the contents of its “lib” folder inside my app’s “lib”. I don’t know if that’s the easiest way to do it, but it worked for me.
Example: You could do something like the following, from your application root:
cd lib gem unpack ruby-activeldap cp -a ruby-activeldap-<version>/lib/* . rm -rf ruby-activeldap-<version> </pre>Once you have ActiveLDAP installed on your system, the next step is to add it to the environment in your app. Add the following line somewhere in your config/environment.rb or config/root.rb (depending on your version of Rails):
require 'active_ldap'Now, create a model (File app/models/ldap_user.rb) for your LDAP-user, and define a method for authenticating against the LDAP server:
class LdapUser < ActiveLdap:Base ldap_mapping :prefix => "cn=users" def self.login(username, password) ActiveLdap::Base.connect \ :host => "ldap.yourserver.com", :port => 389, :base => "dc=your,dc=base", :bind_format => "uid=#{username},cn=users,dc=your,dc=ldap,dc=binding,dc=config,dc=com", :password_block => Proc.new { password }, :allow_anonymous => false return true rescue ActiveLdap::AuthenticationError return false ensure ActiveLdap::Base.close end endIn this case, the method takes the user’s login name and password as parameters, and uses them to attempt to connect to the LDAP server. If the login succeeds, it closes the connection and returns true. If it fails, it catches the error and returns false.
Now you have an LDAP-based login method that you can build into your controllers. Most of the rest of my code was based on the HowtoAuthenticate page, which gives a good overview of how to protect your controllers.
The only other difference with my code is that I used cookies rather than session variables so my users could stay logged in longer. :). Do not use cookies, this makes your site vulnerable to attack.For what it’s worth, here’s how my controllers look.
Application:
# The filters added to this controller will be run for all controllers in the application.
# Likewise will all the methods added be available for all controllers.
class ApplicationController < ActionController::Base protected def authenticate #changed from cookie to session unless session[:login] @session[:return_to] = @request.request_uri redirect_to :controller => “login” return false end end endConcern: I’m not an expert, but isn’t using the presence of the plaintext username in a cookie as the indicator of authenticated state vulnerable to dishonest cookies? Seems like storing it in the session hash would be secure. Fixed
Login Controller:
class LoginController < ApplicationController
def index
render :action => “login”
end def login # the actual login form if @params[:login] @values = @params[:login] if LdapUser.login(@values[:un], @values[:pw]) cookies[:login] = {:value => @values[:un], :expires => Time.now+31536000} else flash[:notice] = “Incorrect!” end else flash[:notice] = “no params?” end redirect_to @session[:return_to] end endOnce you have all that in place, all you need to do is add a call to
before_filterto the top of each controller you want to password protect, like so:class ProtectedController < ApplicationController before_filter :authenticate endThat’s it!
note: There is now a pure ruby LDAP library that is much more simple to use than activeldap. See HowtoAuthenticateWithRubyNetLdap.
Great!
Q: So, what does your login.rhtml look like?A: Here’s a basic example that works for me (LeahCunningham):
<div class='portlet'> <table border='0' cellspacing='0' cellpadding='5'> <tr> <caption> Authentication <%= form_tag :action => “login” %>User <%= text_field(:login, :un) %> Password <%= password_field(:login, :pw) %> <%= end_form_tag %>
begin 2006-04-08 DelayedGreen
I have some problems with this authentication method:
Forunately, ruby/ldap can maintain multiple connections, and to mutiple servers. No need to use ActiveLDAP for this simple task.
end 2006-04-08 DelayedGreen
BEGIN 8/30/06 paul@nelkin.net
I used the following for my LDAP Authentication (less than 10 Lines of Code!!)
require 'ldap'
ldap_host = ‘mail.host.com’
ldap_port = 389
begin
ldap_conn = LDAP::Conn.new(“mail.host.com”, 389)
ldap_conn.set_option( LDAP::LDAP_OPT_PROTOCOL_VERSION, 3 )
pass=“yourpassword”
ldap_conn.bind( “uid=youruserid,cn=users,dc=yourbase,dc=com”, pass )
end
Of course for uid and pass you would specify either a specific username and password, or define a variable.
**END 8/30/06
Questions
Answer:
No Answer Yet.
Answer:
It doesn’t. It uses only Ruby’s built in ldap support. If all you wish to do is authenticate login
using LDAP, active_ldap is overkill, as all you really
need to do is some variation of the above.
Not sure what you mean by an easier way. If you are familiar with RoR this shouldn’t be too difficult. Just use paul@nelkin.net code, it worked for me!
eric-at-erichayes-dot-net note:
With ActiveLDAP 0.8.3.1 I had to require with an underscore:
require ‘active_ldap’