class Rack::Auth::Ldap

class Ldap, the main authentication component for Rack inherited from the default Rack::Auth::AbstractHandler @note please do not instantiate, this classe is reserved to Rack @example Usage

# in a config.ru
gem 'rack-auth-ldap'
require 'rack/auth/ldap'
use Rack::Auth::Ldap

Attributes

config[R]

the config read accessor @attr [Rack::Auth::Config] the read accessor to the LDAP Config object

Public Class Methods

new(app, config_options = {}) click to toggle source

initializer for the Ldap Class @note please don not instantiate without rack config.ru @see Rack::Auth::Ldap @return [Ldap] self object @param [Block,Proc,Lambda] app the rack application @param [hash<Symbol>] config_options the configurable options @option config_options [Symbol] :file the path to the YAML configuration file

Calls superclass method
# File lib/rack/auth/ldap.rb, line 92
def initialize(app, config_options = {})
  super(app)
  @config = Config.new(config_options)
end

Public Instance Methods

call(env) click to toggle source

call wrapper to provide authentication if not @param [Hash] env the rack environnment variable @return [Array] the tri-dimensional Array [status,headers,]

# File lib/rack/auth/ldap.rb, line 100
def call(env)
  auth = Ldap::Request.new(env)
  return unauthorized unless auth.provided?
  return bad_request unless auth.basic?

  if valid?(auth)
    env['REMOTE_USER'] = auth.username
    return @app.call(env)
  end
  unauthorized
end

Private Instance Methods

challenge() click to toggle source

forge a challange header for HTTP basic auth with the realm attribut @return [String] the header

# File lib/rack/auth/ldap.rb, line 116
def challenge
  'Basic realm="%s"' % realm
end
valid?(auth) click to toggle source

do the LDAP connection => search => bind with the credentials get into request headers @param [Rack::Auth::Ldap::Request] auth a LDAP authenticator object @return [TrueClass,FalseClass] Boolean true/false

# File lib/rack/auth/ldap.rb, line 123
def valid?(auth)
  # how to connect to the ldap server: ldap, ldaps, ldap + starttls
  if @config.ldaps
    enc = { method: :simple_tls }
  elsif @config.starttls
    enc = { method: :start_tls }
    enc[:tls_options] = @config.tls_options if @config.tls_options
  else
    enc = nil # just straight ldap
  end
  conn = Net::LDAP.new(host: @config.hostname, port: @config.port,
                       base: @config.basedn,
                       encryption: enc)

  $stdout.puts "Net::LDAP.new => #{conn.inspect}" if @config.debug

  if @config.auth
    $stdout.puts "doing auth for #{@config.rootdn.inspect}" if @config.debug
    conn.auth @config.rootdn, @config.passdn
    # conn.get_operation_result.message has the reson for a failure
    return false unless conn.bind
  end

  filter = Net::LDAP::Filter.eq(@config.username_ldap_attribute,
                                auth.username)

  $stdout.puts "Net::LDAP::Filter.eq => #{filter.inspect}" if @config.debug

  # find the user and rebind as them to test the password
  # return conn.bind_as(:filter => filter, :password => auth.password)
  $stdout.puts "doing bind_as password.size: #{auth.password.size}..." if @config.debug
  ret = conn.bind_as(filter: filter, password: auth.password)
  $stdout.puts "bind_as => #{ret.inspect}" if @config.debug
  ret
end