Devise ldap authenticable does not lookup correctly - ruby-on-rails

I am trying to get user properties from ldap on rails + devise_ldap_authenticatable
(devise_ldap_authenticatable 0.8.1, rails 3.2.14)
Blow is my configuration
devise.rb
config.ldap_logger = true
config.ldap_create_user = true
config.ldap_config = "#{Rails.root}/config/ldap.yml"
ldap.yml (./config/ldap.yml)
authorizations: &AUTHORIZATIONS
group_base: OU=Employee,OU=Person,DC=TEST,DC=AD
required_groups:
- CN=users,OU=Employee,OU=Person,DC=TEST,DC=AD
require_attribute:
objectClass: inetOrgPerson
authorizationRole: postsAdmin
development:
host: 192.168.1.10
port: 389
attribute: CN
base: OU=Employee,OU=Person,DC=TEST,DC=AD
ssl: false
user.rb
devise :ldap_authenticatable, :registerable, revoerable,
:rememberable, :trackable, :validatable
before_save :get_ldap_email
def get_ldap_email
self.email = Devise::LDAP::Adapter.get_ldap_param(self.username, "mail")
end
and my LDAP(AD) status is
CN=12345678,OU=Employee,OU=Person,DC=TEST,DC=AD is exist
and it has mail attribute => "12345678#test.com"
The Login process was good
But It didn't get any properties
log is ...
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`username` = '12345678' ORDER BY created_at DESC LIMIT 1
LDAP: LDAP dn lookup: CN=12345678
LDAP: LDAP search for login: CN=12345678
LDAP: LDAP search yielded 0 matches
LDAP: Authorizing user 12345678#test.ad
LDAP: LDAP dn lookup: CN=12345678
LDAP: LDAP search for login: CN=12345678
LDAP: LDAP search yielded 0 matches
and
Devise::LDAP::Adapter.get_ldap_param(self.username, "mail")
#It returns nil
Maybe the lookup address is wrong...
(maybe CN=12345678,OU=Employee,OU=Person,DC=TEST,DC=AD is correct)
How can i fix it?
How can i get user properties? (ex: mail ...)

Try this:
def get_ldap_email
self.email = Devise::LDAP::Adapter.get_ldap_param(self.username,"mail").first
end
before_save :get_ldap_email
admin_user: your correct root dn
admin_password: you correct pw
In devise.rb
config.ldap_use_admin_to_bind = true

Related

Devise LDAP can't find user, but logs in fine

So when I authorize a user with the devise_ldap_authenticatable gem, I get the following logged information:
LDAP: LDAP dn lookup: sAMAccountName=john.smith
LDAP: LDAP search for login: sAMAccountName=john.smith
LDAP: LDAP search yielded 0 matches
LDAP: Authorizing user lt\john.smith
As I understand it, the search fails to return a user, which I would like to find so I could set other attributes based off of LDAP fields (mainly department).
I've checked that this search should work with the following rake task:
desc "LDAP Test"
task ldap: :environment do
ldap = Net::LDAP.new :host => ENV['LDAP_IP'],
:port => ENV['LDAP_PORT'],
:encryption => :simple_tls,
:base => ENV['LDAP_BASE'],
:auth => {
:method => :simple,
:username => ENV['LDAP_LOGIN'],
:password => ENV['LDAP_PASSWORD']
}
if ldap.bind
ldap.search(:base => ENV['LDAP_BASE'], :filter => Net::LDAP::Filter.eq("sAMAccountName", "john.smith"), :attributes => ["sAMAccountName", "department"], :return_result => false) do |entry|
entry.each do |attr, values|
puts "#{attr}: #{values.first}"
end
end
else
puts "Connection failed! Code: #{ldap.get_operation_result.code}, message: #{ldap.get_operation_result.message}"
end
end
Which returns:
dn: CN=John Smith,OU=Temporary Staff,OU=Users,DC=lt,DC=local
department: Bioinformatics
samaccountname: Johh.Smith
Does anyone know why the login search could be failing? My config files are as follows:
devise.rb:
# ==> LDAP Configuration
config.ldap_logger = true
config.ldap_create_user = true
config.ldap_update_password = false
# config.ldap_config = "#{Rails.root}/config/ldap.yml"
config.ldap_auth_username_builder = Proc.new() {|attribute, login, ldap| "lt\\#{login}"}
# config.ldap_check_group_membership = false
# config.ldap_check_attributes = false
config.ldap_use_admin_to_bind = true
ldap.yml:
development:
host: <%= ENV['LDAP_IP'] %>
port: <%= ENV['LDAP_PORT'] %>
attribute: sAMAccountName
base: <%= ENV['LDAP_BASE'] %>
admin_user: <%= ENV['LDAP_LOGIN'] %>
admin_password: <%= ENV['LDAP_PASSWORD'] %>
ssl: true
# <<: *AUTHORIZATIONS
I would use a packet sniffer like Wireshark to see the difference between the LDAP requests in the rake task vs. devise. The UnboundID LDAP SDK for Java also ships with a tool called LDAPDebugger that you can use as a proxy between your app and Active Directory to decode the traffic.
I hope this helps.

Using ldap to connect to ad with devise ruby on rails

Question I am having issues connecting to my Microsoft Active Directory using the devise_ldap_authentication. For some reason I keep getting LDAP search yielded 0 matches when using it with devise and I am 100% certain I am using the correct credentials, so I wrote a test class using 'net/ldap' to see if I could yeild a correct match and presto it works with my test class but, I still can't authenticate with devise_ldap_auth. Any help would be greatly appreciated or help with setting up my config/ldap.yml to match my test class.
Here is my config/ldap.yml
#Environment
development:
host: myldap.mydomain.com
port: 389
attribute: sAMAccountname
base: dc=mydomain, dc=com
admin_user: cn=admin,dc=mydomain,dc=com
admin_password: password
#ssl: false
Here is my devise.rb
Devise.setup do |config|
# ==> LDAP Configuration
config.ldap_logger = true
# config.ldap_create_user = false
# config.ldap_update_password = true
config.ldap_config = "#{Rails.root}/config/ldap.yml"
# config.ldap_check_group_membership = false
# config.ldap_check_group_membership_without_admin = false
config.ldap_check_attributes = true
#config.ldap_use_admin_to_bind = true
# config.ldap_ad_group_check = false
this is what I get back when using ldap with devise.
D, [2016-06-24T07:01:30.558440 #42760] DEBUG -- : LDAP: LDAP dn lookup: sAMAccountName=snow
D, [2016-06-24T07:01:30.558507 #42760] DEBUG -- : LDAP: LDAP dn lookup: sAMAccountName=snow
D, [2016-06-24T07:01:30.558549 #42760] DEBUG -- : LDAP: LDAP search for login: sAMAccountName=snow
D, [2016-06-24T07:01:30.558579 #42760] DEBUG -- : LDAP: LDAP search for login: sAMAccountName=snow
D, [2016-06-24T07:01:30.594029 #42760] DEBUG -- : LDAP: LDAP search yielded 0 matches
D, [2016-06-24T07:01:30.594099 #42760] DEBUG -- : LDAP: LDAP search yielded 0 matches
D, [2016-06-24T07:01:30.594146 #42760] DEBUG -- : LDAP: Authorizing user sAMAccountName=snow,dc=mydomain, dc=com
D, [2016-06-24T07:01:30.594180 #42760] DEBUG -- : LDAP: Authorizing user sAMAccountName=snow,dc=mydomain, dc=com
D, [2016-06-24T07:01:30.611308 #42760] DEBUG -- : LDAP: Not authorized because not authenticated.
D, [2016-06-24T07:01:30.611377 #42760] DEBUG -- : LDAP: Not authorized because not authenticated.
Here is my test class that works to authenticate with ldap on my microsoft AD
require 'net/ldap' # gem install ruby-net-ldap
module Test
class PutAd
SERVER = 'myldap.mydomain.com'
PORT = 389
BASE = 'DC=mydomain,DC=com'
DOMAIN = 'mydomain.com'
ATTR_SV = {
:login => :samaccountname,
:first_name => :givenname,
:last_name => :sn,
:email => :mail
}
def self.authenticate(login, pass)
return nil if login.empty? or pass.empty?
conn = Net::LDAP.new :host => SERVER,
:port => PORT,
:base => BASE,
:auth => { :username => "#{login}##{DOMAIN}",
:password => pass,
:method => :simple }
if conn.bind and user = conn.search(:filter => "sAMAccountName=#{login}").first
return self.new(user)
else
return nil
end
rescue Net::LDAP::LdapError => e
return nil
end
end
end
^This will return my account information if it matches if not it will return nil.
Turns out my company has a different way of authorizing a user. I added the advanced flag to my devise ldap install, and set this accordingly and presto it worked.
==> Advanced LDAP Configuration
config.ldap_auth_username_builder = Proc.new() {|attribute, login, ldap| "#{login}#mydomain.com"}

Multiple groups in ldap device authenticatable

I am trying to allow users to login who are present in group1 or group2
but during LDAP authorization it is checking in both groups.
If user is present in either group1 or group2 i need to allow them to login.
Can anybody assist on this?
In devise.rb
config.ldap_check_group_membership = true
In ldap.yml
authorizations: &AUTHORIZATIONS
group_base: ou=groups,dc=test,dc=com
required_groups:
cn=admins,ou=groups,dc=test,dc=com -----group1
cn=users,ou=groups,dc=test,dc=com ----- group2
require_attribute:
# objectClass: inetOrgPerson
# authorizationRole: postsAdmin
development:
host: # ip address is to be filled in here..
port: # port number goes here..
attribute: cn
base: # my tree base details go in here..
admin_user: cn=admin_name,dc=test,dc=com
admin_password: # password goes in here..
ssl: true
<<: *AUTHORIZATIONS
/devise_ldap_authenticatable-0.8.3/lib/devise_ldap_authenticatable/ldap/connection.rb
def in_required_groups?
return true unless #check_group_membership
## FIXME set errors here, the ldap.yml isn't set properly.
return false if #required_groups.nil?
arr_res = []
for group in #required_groups
if group.is_a?(Array)
res = in_group?(group[1],group[0])
arr_res << res
# return false unless in_group?(group[1], group[0])
else
return false unless in_group?(group)
end
end
DeviseLdapAuthenticatable::Logger.send(arr_res)
return true if arr_res.include? true
# return true
end
Only 4 months late but for anyone still facing this, you can monkey patch a single method in the gem
module Devise
module LDAP
class Connection
def in_required_groups?
found = false
return true unless #check_group_membership
return false if #required_groups.nil?
for group in #required_groups
if group.is_a?(Array)
found = true if in_group?(group[1], group[0])
# return false unless in_group?(group[1], group[0])
else
found = true if in_group?(group)
# found = true if in_group?(group[1], group[0])
end
end
return found
end
end
end
end

Rails devise customization

In devise's user table i'm trying to save email and password through a different controller , but in server log i'm getting this error ,
WARNING: Can't mass-assign protected attributes for User: encrypted_password
------------------------------------------------------------------------------
(0.1ms) BEGIN
User Exists (0.4ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'mail#mail.com' LIMIT 1
(0.2ms) ROLLBACK
Added encrypted_password attribute to the model.
So i'm not able to insert it to users table.
And ,How to encrypt password? as devise gem has built in.
Controller :
#user = User.new(:email => params[:supplier][:username],:username => params[:supplier][:username],:encrypted_password => '$2a$10$/Hh7UegsWm2ndRXbDEfjvOKBUiI1fa/z1GIbE5OYFpyqW6P97llsG')
#user.save
puts #user.errors
Model :
attr_accessible :encrypted_password
I would simply use
user = User.new(email: "...", password: "password", password_confirmation: "password")
user.skip_confirmation!
user.save!
This way, devise will do the work for you, and you don't have to bother about confirmation emails. If you want confirmation emails still to be send out, remove the second line

How do I allow uppercase usernames in Refinery CMS?

I believe Refinery uses Devise, and I found this guide to allow uppercase usernames in Devise
https://github.com/plataformatec/devise/wiki/How-To%3a-Allow-users-to-sign-in-using-their-username-or-email-address
However, even with
config.authentication_keys = [ :login ]
config.case_insensitive_keys = [:email]
it still forced the username to lowercase.
> u = User.create username: "UsErNaMe", password: "secret", email: "email#com.com"
=> #<Refinery::User id: 60, username: "username", email: "email#com.com",
I saw this question, but it did not help
Devise: Allow users to register as "UsErNaMe" but login with "username"
Refinery 2.1.1, Devise 2.2.8, Rails 3.2.14
It is in the Refinery::User model. There's a before_validation filter that downcases usernames:
...
before_validation :downcase_username, :strip_username
...
private
def downcase_username
self.username = self.username.downcase if self.username?
end
You could decorate the Refinery::User model:
Refinery::User.class_eval do
private
def downcase_username
self.username if self.username?
end
end
Found it
intended_username = user_params[:username] # save the username because Refinery converts it to lowercase! https://github.com/refinery/refinerycms/blob/master/authentication/app/models/refinery/user.rb#L28
intended_username.strip! # trim spaces
if current_refinery_user.update_without_password(user_params)
current_refinery_user.username = intended_username # restore the username as the user intended with mixed case
current_refinery_user.save(validate: false) # skip validations

Resources