[PATCH] LDAP Auth source with BindDN support. ยป ldap_auth_binddn.patch
app/models/auth_source_ldap.rb | ||
---|---|---|
33 | 33 |
|
34 | 34 |
def authenticate(login, password) |
35 | 35 |
return nil if login.blank? || password.blank? |
36 |
attrs = get_user_dn(login) |
|
36 |
attrs = get_user_dn(login, password)
|
|
37 | 37 |
|
38 |
if attrs && attrs[:dn] && authenticate_dn(attrs[:dn], password)
|
|
38 |
if attrs && attrs[:dn] |
|
39 | 39 |
logger.debug "Authentication successful for '#{login}'" if logger && logger.debug? |
40 | 40 |
return attrs.except(:dn) |
41 | 41 |
end |
... | ... | |
92 | 92 |
end |
93 | 93 |
end |
94 | 94 |
|
95 |
# Check if a DN (user record) authenticates with the password |
|
96 |
def authenticate_dn(dn, password) |
|
97 |
if dn.present? && password.present? |
|
98 |
initialize_ldap_con(dn, password).bind |
|
99 |
end |
|
100 |
end |
|
101 |
|
|
102 | 95 |
# Get the user's dn and any attributes for them, given their login |
103 |
def get_user_dn(login) |
|
104 |
ldap_con = initialize_ldap_con(self.account, self.account_password) |
|
105 |
login_filter = Net::LDAP::Filter.eq( self.attr_login, login ) |
|
106 |
object_filter = Net::LDAP::Filter.eq( "objectClass", "*" ) |
|
96 |
def get_user_dn(login, password) |
|
97 |
ldap = Net::LDAP.new |
|
98 |
ldap.host = self.host |
|
99 |
ldap.port = self.port |
|
100 |
ldap.auth self.account, self.account_password |
|
101 |
|
|
102 |
result = ldap.bind_as( |
|
103 |
:base => "o=neusoft.com", |
|
104 |
:filter => '(uid='+login+')', |
|
105 |
:password => password |
|
106 |
) |
|
107 |
|
|
107 | 108 |
attrs = {} |
109 |
if result |
|
110 |
login_filter = Net::LDAP::Filter.eq( self.attr_login, login ) |
|
111 |
object_filter = Net::LDAP::Filter.eq( "objectClass", "*" ) |
|
108 | 112 |
|
109 |
ldap_con.search( :base => self.base_dn,
|
|
113 |
ldap.search( :base => self.base_dn,
|
|
110 | 114 |
:filter => object_filter & login_filter, |
111 | 115 |
:attributes=> search_attributes) do |entry| |
112 |
|
|
113 |
if onthefly_register? |
|
114 |
attrs = get_user_attributes_from_ldap_entry(entry) |
|
115 |
else |
|
116 |
attrs = {:dn => entry.dn} |
|
116 |
if onthefly_register? |
|
117 |
attrs = get_user_attributes_from_ldap_entry(entry) |
|
118 |
else |
|
119 |
attrs = {:dn => entry.dn} |
|
120 |
end |
|
121 |
|
|
122 |
logger.debug "DN found for #{login}: #{attrs[:dn]}" if logger && logger.debug? |
|
117 | 123 |
end |
118 |
|
|
119 |
logger.debug "DN found for #{login}: #{attrs[:dn]}" if logger && logger.debug? |
|
120 | 124 |
end |
121 |
|
|
122 | 125 |
attrs |
123 | 126 |
end |
124 | 127 |
|
app/models/user.rb | ||
---|---|---|
112 | 112 |
# Make sure no one can sign in with an empty password |
113 | 113 |
return nil if password.to_s.empty? |
114 | 114 |
user = find_by_login(login) |
115 |
attrs = AuthSource.authenticate(login, password) |
|
115 | 116 |
if user |
116 | 117 |
# user is already in local database |
117 | 118 |
return nil if !user.active? |
118 |
if user.auth_source
|
|
119 |
# user has an external authentication method
|
|
120 |
return nil unless user.auth_source.authenticate(login, password)
|
|
119 |
if attrs
|
|
120 |
user.reload
|
|
121 |
logger.info("User '#{user.login}' created from external auth source: #{user.auth_source.type} - #{user.auth_source.name}") if logger && user.auth_source
|
|
121 | 122 |
else |
122 |
# authentication with local password |
|
123 |
return nil unless User.hash_password(password) == user.hashed_password |
|
124 |
end |
|
123 |
if user.auth_source |
|
124 |
# user has an external authentication method |
|
125 |
return nil unless user.auth_source.authenticate(login, password) |
|
126 |
else |
|
127 |
# authentication with local password |
|
128 |
return nil unless User.hash_password(password) == user.hashed_password |
|
129 |
end |
|
130 |
end |
|
125 | 131 |
else |
126 | 132 |
# user is not yet registered, try to authenticate with available sources |
127 |
attrs = AuthSource.authenticate(login, password) |
|
128 | 133 |
if attrs |
129 | 134 |
user = new(attrs) |
130 | 135 |
user.login = login |