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.)