We have an openldap server running. I wrote a little rails app that required authentication and that I wanted to authenticate against users in the openldap server. Here’s how I did it.
Here is the relevant part of my Gemfile. I’m using Rails 3.0.3.
gem 'authlogic' gem 'declarative_authorization' gem 'net-ldap', :require => 'net/ldap'
My user migration:
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :username
t.string :firstname
t.string :lastname
t.string :persistence_token
t.datetime :last_request_at
t.string :role
t.timestamps
end
end
Add to my user model:
acts_as_authentic do |c|
c.validate_password_field = false
c.logged_in_timeout = 2.hours
end
def valid_password?(password)
ldap_settings = YAML.load_file("#{Rails.root.to_s}/config/ldap.yml")[Rails.env]
#logger.info ldap_settings.inspect
ldap_settings[:host] = ldap_settings['host']
ldap_settings[:port] = ldap_settings['port']
ldap_settings[:encryption] = { :method => :simple_tls } if ldap_settings['ssl']
ldap_settings[:auth] =
{ :method => :simple, :username => "uid=#{self.username},#{ldap_settings['base']}", :password => password}
#logger.info ldap_settings.inspect
ldap = Net::LDAP.new(ldap_settings)
ldap.bind
end
Add to my user_session model:
logout_on_timeout true
My new user_session:
<%= form_for @user_session, :as => :user_session, :url => { :action => 'create' } do |f| -%>
<%= f.label :username %>
<%= f.text_field :username %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit 'Login' %>
<% end %>
<%= link_to 'Back', :back %>
Needed the stuff after @user_session because of a problem with authlogic and rails3.
Finally, I created a yaml file with the info for my ldap server. It's in config/ldap.yml.
development:
host: eagle.example.com
port: 636
base: ou=people,dc=group,dc=example,dc=com
ssl: true
production:
host: eagle.example.com
port: 636
base: ou=people,dc=group,dc=example,dc=com
ssl: true
That pretty much did it. You MUST use port 636 and ssl:true for this to work. Starttls over port 389 will not work. (At least, it didn't for me.)