[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 |