mirror of
https://github.com/omniauth/omniauth.git
synced 2022-11-09 12:31:49 -05:00
added user search and user info retrieve for LDAP strategy. updated the
reamde as well.
This commit is contained in:
parent
bfc4eb9c86
commit
cd4af04646
3 changed files with 67 additions and 52 deletions
|
@ -12,9 +12,9 @@ For the full auth suite:
|
|||
|
||||
gem install omniauth
|
||||
|
||||
CAS strategy
|
||||
== Stand-Alone Example
|
||||
|
||||
CAS strategy
|
||||
Use the strategy as a middleware in your application:
|
||||
|
||||
require 'omniauth/enterprise'
|
||||
|
@ -42,13 +42,16 @@ If CAS is one of several authentication strategies, use the OmniAuth Builder:
|
|||
|
||||
LDAP strategy
|
||||
|
||||
use OmniAuth::Strategies::LDAP, :host => '10.101.10.1', :port => 389, :method => :plain, :try_sasl => true, :sasl_mechanisms => "GSS-SPNEGO"
|
||||
use OmniAuth::Strategies::LDAP, :host => '10.101.10.1', :port => 389, :method => :plain, :base => 'dc=intridea, dc=com', :uid => 'sAMAccountName', :try_sasl => true, :sasl_mechanisms => "GSS-SPNEGO"
|
||||
or
|
||||
use OmniAuth::Builder do
|
||||
provider :LDAP, :host => '10.101.10.1', :port => 389, :method => :plain, :try_sasl => true, :sasl_mechanisms => "GSS-SPNEGO"
|
||||
provider :LDAP, :host => '10.101.10.1', :port => 389, :method => :plain, :base => 'dc=intridea, dc=com', :uid => 'sAMAccountName', :try_sasl => true, :sasl_mechanisms => "GSS-SPNEGO"
|
||||
end
|
||||
|
||||
LDAP server's :host and :port are required, :method is also a required field, and allowed values are :plain, :ssl, and :tls.
|
||||
:base is required, it is the distinguish name (DN) for your organization, all users should be searchable under this base.
|
||||
:uid is required, it is the LDAP attribute name for the user name in the login form. typically AD would be 'sAMAccountName' or 'UniquePersonalIdentifier', while
|
||||
OpenLDAP is 'uid'. You can also use 'dn', if your user choose the put in the dn in the login form (but usually is too long for user to remember or know).
|
||||
:try_sasl and :sasl_mechanisms are optional, use it to initial SASL connection to server. mechanism supported are DIGEST-MD5 and GSS-SPNEGO.
|
||||
|
||||
Then simply direct users to '/auth/ldap' to have them authenticated via your company's LDAP server.
|
||||
|
|
|
@ -33,14 +33,17 @@ module OmniAuth
|
|||
def perform
|
||||
begin
|
||||
@adaptor.bind(:bind_dn => request.POST['username'], :password => request.POST['password'])
|
||||
rescue
|
||||
fail!(:invalid_credentials)
|
||||
end
|
||||
@user_info = @adaptor.search(:filter => Net::LDAP::Filter.eq(@adaptor.uid, request.POST['username']),:limit => 1)
|
||||
puts @user_info
|
||||
request.POST['auth'] = auth_hash
|
||||
@env['REQUEST_METHOD'] = 'GET'
|
||||
@env['PATH_INFO'] = "#{OmniAuth.config.path_prefix}/#{name}/callback"
|
||||
|
||||
@app.call(@env)
|
||||
rescue Exception => e
|
||||
puts e.message
|
||||
fail!(:invalid_credentials)
|
||||
end
|
||||
end
|
||||
|
||||
def callback_phase
|
||||
|
@ -49,7 +52,8 @@ module OmniAuth
|
|||
|
||||
def auth_hash
|
||||
OmniAuth::Utils.deep_merge(super, {
|
||||
'uid' => request.POST['username']
|
||||
'uid' => @user_info["dn"],
|
||||
'user_info' => @user_info
|
||||
})
|
||||
end
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#this code boughts pieces from activeldap and net-ldap
|
||||
require 'rack'
|
||||
require 'net/ldap'
|
||||
require 'net/ntlm'
|
||||
|
@ -11,15 +12,15 @@ module OmniAuth
|
|||
class AuthenticationError < StandardError; end
|
||||
class ConnectionError < StandardError; end
|
||||
VALID_ADAPTER_CONFIGURATION_KEYS = [:host, :port, :method, :bind_dn, :password,
|
||||
:try_sasl, :sasl_mechanisms, :sasl_quiet]
|
||||
MUST_HAVE_KEYS = [:host, :port, :method]
|
||||
:try_sasl, :sasl_mechanisms, :uid, :base]
|
||||
MUST_HAVE_KEYS = [:host, :port, :method, :uid, :base]
|
||||
METHOD = {
|
||||
:ssl => :simple_tls,
|
||||
:tls => :start_tls,
|
||||
:plain => nil
|
||||
}
|
||||
attr_reader :bind_dn
|
||||
|
||||
attr_accessor :bind_dn, :password
|
||||
attr_reader :connection, :uid, :base
|
||||
def initialize(configuration={})
|
||||
@connection = nil
|
||||
@disconnected = false
|
||||
|
@ -75,7 +76,6 @@ module OmniAuth
|
|||
# Rough bind loop:
|
||||
# Attempt 1: SASL if available
|
||||
# Attempt 2: SIMPLE with credentials if password block
|
||||
# Attempt 3: SIMPLE ANONYMOUS if 1 and 2 fail (or pwblock returns '')
|
||||
if try_sasl and sasl_bind(bind_dn, options)
|
||||
puts "bind with sasl"
|
||||
elsif simple_bind(bind_dn, options)
|
||||
|
@ -111,7 +111,26 @@ module OmniAuth
|
|||
connecting? and @bound
|
||||
end
|
||||
|
||||
def search(options={}, &block)
|
||||
base = options[:base]
|
||||
filter = options[:filter]
|
||||
limit = options[:limit]
|
||||
|
||||
args = {
|
||||
:base => @base,
|
||||
:filter => filter,
|
||||
:size => limit
|
||||
}
|
||||
puts args.inspect
|
||||
attributes = {}
|
||||
execute(:search, args) do |entry|
|
||||
puts entry.inspect
|
||||
entry.attribute_names.each do |name|
|
||||
attributes[name] = entry[name]
|
||||
end
|
||||
end
|
||||
attributes
|
||||
end
|
||||
private
|
||||
def execute(method, *args, &block)
|
||||
result = @connection.send(method, *args, &block)
|
||||
|
@ -137,11 +156,6 @@ module OmniAuth
|
|||
def prepare_connection(options)
|
||||
end
|
||||
|
||||
|
||||
def need_credential_sasl_mechanism?(mechanism)
|
||||
not %(GSSAPI EXTERNAL ANONYMOUS).include?(mechanism)
|
||||
end
|
||||
|
||||
def ensure_method(method)
|
||||
method ||= "plain"
|
||||
normalized_method = method.to_s.downcase.to_sym
|
||||
|
@ -153,15 +167,9 @@ module OmniAuth
|
|||
end
|
||||
|
||||
def sasl_bind(bind_dn, options={})
|
||||
if options.has_key?(:sasl_quiet)
|
||||
sasl_quiet = options[:sasl_quiet]
|
||||
else
|
||||
sasl_quiet = @sasl_quiet
|
||||
end
|
||||
|
||||
sasl_mechanisms = options[:sasl_mechanisms] || @sasl_mechanisms
|
||||
begin
|
||||
sasl_mechanisms.each do |mechanism|
|
||||
begin
|
||||
normalized_mechanism = mechanism.downcase.gsub(/-/, '_')
|
||||
sasl_bind_setup = "sasl_bind_setup_#{normalized_mechanism}"
|
||||
next unless respond_to?(sasl_bind_setup, true)
|
||||
|
@ -177,11 +185,11 @@ module OmniAuth
|
|||
:name => "bind: SASL", :dn => bind_dn, :mechanism => mechanism,
|
||||
}
|
||||
puts info.inspect
|
||||
return true if execute(:bind, args)
|
||||
end
|
||||
execute(:bind, args)
|
||||
return true
|
||||
rescue Exception => e
|
||||
puts e.message
|
||||
false
|
||||
end
|
||||
end
|
||||
false
|
||||
end
|
||||
|
@ -228,7 +236,7 @@ module OmniAuth
|
|||
:maxbuf => "65536",
|
||||
"digest-uri" => uri.inspect,
|
||||
}
|
||||
a1 = "#{bind_dn}:#{realm}:#{@password}"
|
||||
a1 = "#{bind_dn}:#{realm}:#{options[:password]||@password}"
|
||||
a1 = "#{Digest::MD5.digest(a1)}:#{nonce}:#{cnonce}"
|
||||
ha1 = Digest::MD5.hexdigest(a1)
|
||||
a2 = "AUTHENTICATE:#{uri}"
|
||||
|
@ -244,7 +252,7 @@ module OmniAuth
|
|||
end
|
||||
def sasl_bind_setup_gss_spnego(bind_dn, options)
|
||||
puts options.inspect
|
||||
user,psw = [bind_dn, @password]
|
||||
user,psw = [bind_dn, options[:password]||@password]
|
||||
raise LdapError.new( "invalid binding information" ) unless (user && psw)
|
||||
|
||||
nego = proc {|challenge|
|
||||
|
@ -261,7 +269,7 @@ module OmniAuth
|
|||
args = {
|
||||
:method => :simple,
|
||||
:username => bind_dn,
|
||||
:password => @password,
|
||||
:password => options[:password]||@password,
|
||||
}
|
||||
execute(:bind, args)
|
||||
true
|
||||
|
|
Loading…
Reference in a new issue