Class: SimpleLdapAuthenticator

Inherits:
Object
  • Object
show all
Defined in:
lib/simple_ldap_authenticator.rb

Overview

Allows for easily authenticating users via LDAP (or LDAPS). If authenticating via LDAP to a server running on localhost, you should only have to configure the login_format.

Can be configured using the following accessors (with examples):

  • login_format = ‘%[email protected]’ # Active Directory, OR

  • login_format = ‘cn=%s,cn=users,o=organization,c=us’ # Other LDAP servers

  • servers = [‘dc1.domain.com’, ‘dc2.domain.com’] # names/addresses of LDAP servers to use

  • use_ssl = true # for logging in via LDAPS

  • port = 3289 # instead of 389 for LDAP or 636 for LDAPS

  • logger = RAILS_DEFAULT_LOGGER # for logging authentication successes/failures

The class is used as a global variable, you are not supposed to create an instance of it. For example:

require 'simple_ldap_authenticator'
SimpleLdapAuthenticator.servers = %w'dc1.domain.com dc2.domain.com'
SimpleLdapAuthenticator.use_ssl = true
SimpleLdapAuthenticator. = '%[email protected]'
SimpleLdapAuthenticator.logger = RAILS_DEFAULT_LOGGER
class LoginController < ApplicationController 
  def 
    return redirect_to(:action=>'try_again') unless SimpleLdapAuthenticator.valid?(params[:username], params[:password])
    session[:username] = params[:username]
  end
end

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.connectionObject

The connection to the LDAP server. A single connection is made and the connection is only changed if a server returns an error other than invalid password.



71
72
73
# File 'lib/simple_ldap_authenticator.rb', line 71

def connection
  @connection
end

.ldap_libraryObject

Returns the value of attribute ldap_library.



38
39
40
# File 'lib/simple_ldap_authenticator.rb', line 38

def ldap_library
  @ldap_library
end

.loggerObject

Returns the value of attribute logger.



38
39
40
# File 'lib/simple_ldap_authenticator.rb', line 38

def logger
  @logger
end

.login_formatObject

Returns the value of attribute login_format.



38
39
40
# File 'lib/simple_ldap_authenticator.rb', line 38

def 
  @login_format
end

.portObject

The port to use. Defaults to 389 for LDAP and 636 for LDAPS.



82
83
84
# File 'lib/simple_ldap_authenticator.rb', line 82

def port
  @port
end

.serversObject

Returns the value of attribute servers.



38
39
40
# File 'lib/simple_ldap_authenticator.rb', line 38

def servers
  @servers
end

.use_sslObject

Returns the value of attribute use_ssl.



38
39
40
# File 'lib/simple_ldap_authenticator.rb', line 38

def use_ssl
  @use_ssl
end

Class Method Details

.load_ldap_libraryObject

Load the required LDAP library, either ‘ldap’ or ‘net/ldap’



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/simple_ldap_authenticator.rb', line 41

def load_ldap_library
  return if @ldap_library_loaded
  if ldap_library
    if ldap_library == 'net/ldap'
      require 'net/ldap'
    else
      require 'ldap'
      require 'ldap/control'
    end
  else
    begin
      require 'ldap'
      require 'ldap/control'
      ldap_library = 'ldap'
    rescue LoadError
      require 'net/ldap'
      ldap_library = 'net/ldap'
    end
  end
  @ldap_library_loaded = true
end

.serverObject

The next LDAP server to which to connect



64
65
66
# File 'lib/simple_ldap_authenticator.rb', line 64

def server
  servers[0]
end

.switch_serverObject

Disconnect from current LDAP server and use a different LDAP server on the next authentication attempt



88
89
90
91
# File 'lib/simple_ldap_authenticator.rb', line 88

def switch_server
  self.connection = nil
  servers << servers.shift
end

.valid?(login, password) ⇒ Boolean

Check the validity of a login/password combination

Returns:

  • (Boolean)


94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/simple_ldap_authenticator.rb', line 94

def valid?(, password)
  if password.to_s == ''
    false
  elsif ldap_library == 'net/ldap'
    connection.authenticate( % .to_s, password.to_s)
    begin
      if connection.bind
          logger.info("Authenticated #{.to_s} by #{server}") if logger
          true
        else
          logger.info("Error attempting to authenticate #{.to_s} by #{server}: #{connection.get_operation_result.code} #{connection.get_operation_result.message}") if logger
          switch_server unless connection.get_operation_result.code == 49
          false
        end
    rescue Net::LDAP::LdapError => error
      logger.info("Error attempting to authenticate #{.to_s} by #{server}: #{error.message}") if logger
      switch_server
      false
    end
  else
    connection.unbind if connection.bound?
    begin
      connection.bind( % .to_s, password.to_s)
      connection.unbind
      logger.info("Authenticated #{.to_s} by #{server}") if logger
      true
    rescue LDAP::ResultError => error
      connection.unbind if connection.bound?
      logger.info("Error attempting to authenticate #{.to_s} by #{server}: #{error.message}") if logger
      switch_server unless error.message == 'Invalid credentials'
      false
    end
  end
end