Ldap search in net-ldap Ruby Rails [closed] - ruby-on-rails

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am trying to search ldap. This is doing successful authentication, I verified using a correct and incorrect password. Ldap connection is successful. Then when I make a search query it cannot read attributes from LDAP (AD). What is wrong here? Does ldap/AD has any restrictions/permissions on who can what?
#!/usr/bin/env ruby
require "net-ldap"
$username = String.new
class ActiveDirectoryUser
SERVER = '10.10.10.10'
PORT = 389
BASE = 'DC=mydomain,DC=com'
DOMAIN = 'mydomain.com'
def self.authenticate(login, pass)
conn = Net::LDAP.new :host => SERVER,
:port => PORT,
:base => BASE,
:auth => { :username => "#{login}##{DOMAIN}",
:password => pass,
:method => :simple }
if conn.bind
conn.search(
:base => BASE, :filter => Net::LDAP::Filter.eq(
"sAMAccountName", login ),
:attributes => %w[ givenName ], :return_result => true) do
|entry|
puts "givenName: #{entry.givenName}"
$username = entry.givenName
end
return true
else
return false
end
rescue Net::LDAP::LdapError => e
return false
end
end
if ActiveDirectoryUser.authenticate('myusername', 'mypassword')
puts "Authentication Successful! The user is "+$username
#### I get this,but blank username
else
puts "Authentication FAILED!"
end
-----------
# ./ad.rb
Authentication Successful! The user is
Thanks Terry for the answer.
It was a small issue. I was missing some details in the treebase. It is working now.

LDAP-compliant directory servers must provide access control, so it is possible that the LDAP client:
cannot search for an entry
cannot read any attributes from an entry
cannot read some attributes from an entry
It is also possible the entry for which the LDAP client searches does not exist - clients cannot read attributes from entries that do not exist.
The application code should check that the entry in question exists using command-line tools if questions exist as to whether the authentication was successful or whether an entry exists. For information about the command-line ldapsearch tool, see LDAP: using ldapsearch.

Related

How to Ruby on Rails authentication with LDAP? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
I'm developing a web app and I have an authentication method using bcrypt gemIt works fine, but I wanted to change the authentication method to LDAP because I'm using an intranet environment and want my users to be able to sign in with windows credentials.
I'm looking to use net-ldap gem but I can't find any good toturials/explanations online on how to implement this into my web application.
Can you help me with this?
How can I do this?
Here's a utility class I've used in the past to do multi-server LDAP check:
require 'net/ldap'
# Ldap.authenticate('user', 'password')
# => `true` if valid
# => `false` if invalid
# => `nil` if LDAP unavailable
class Ldap
def self.config
{
domain: 'mydomain',
servers: ['server1', 'server2']
}
end
def self.authenticate(login, pass)
return false if login.empty? or pass.empty?
config['servers'].each do |server|
auth = authenticate_against_server(login, pass, server, config['domain'])
return auth unless auth.nil?
end
nil
end
private
def self.authenticate_against_server(login, pass, host, domain)
conn = Net::LDAP.new(
host: host,
port: 636,
base: "dc=#{domain}, dc=local",
encryption: :simple_tls,
auth: { username: "#{login}##{domain}.local",
password: pass,
method: :simple }
)
Timeout::timeout(15) do
return conn.bind ? true : false
end
rescue Net::LDAP::LdapError => e
notify_ldap_admin(host, 'Error', e)
return nil
rescue Timeout::Error => e
notify_ldap_admin(host, 'Timeout', e)
return nil
end
def self.notify_ldap_admin(host, error_type, error)
msg = "LDAP #{error_type} on #{host}"
RAILS_DEFAULT_LOGGER.debug(msg)
DeveloperMailer.deliver_ldap_failure_msg(msg, error)
end
end
If you're fairly new, I'd avoid homebrewing authentication. Check out either
Devise w/ LDAP: https://github.com/cschiewek/devise_ldap_authenticatable
Omniauth w/ LDAP: https://github.com/intridea/omniauth-ldap
I started with Devise, and still use it for a few projects, but Omniauth is super powerful and more versatile in my opinion. You have to do more yourself though.
Further reading should include CanCanCan for authorization within your app, unless everybody gets everything that is.

Listing all OU's in LDAP with Rails

I am trying to list all Organizational Units (OU) from my LDAP directory. I am using the "devise_ldap_authenticatable" gem to authenticate my users. The LDAP sign in works fine. I am trying to get all the OU's now.
I'm new to LDAP, please let me know if my search query is wrong here.
ldap = Net::LDAP.new
ldap.host = "192.168.0.100"
ldap.port = 389
ldap.auth "cn=admin,dc=company,dc=com", "password"
treebase = "dc=company,dc=com"
filter = Net::LDAP::Filter.eq( "objectClass=organizationalUnit","company.com" )
attrs = ["*"]
ldap.search( :base => treebase, :filter => filter, :attributes => attrs, :return_result => false ) do |entry|
puts entry
end
When I ran this, I got nothing returned. I have two OU's in my LDAP, DevOps and Development. There are 5 test users in each.
I'm not sure if this is the right way to do it, but it got me what I wanted and I'm happy with that.
I just removed the filter and retrieved the ou from the entry directly.
ldap.search( :base => treebase, :attributes => attrs, :return_result => false ) do |entry|
puts entry["ou"]
end

Using Ruby Webrick HTTPAuth with LDAP

The app I am writing has the ability to have a login popup appear and it authenticates against a hard coded username/password constant pair. I would like to authenticate against our central LDAP server. the we dont have a base however we do have a bind_dn string of "cn=USERFOO,ou=it,o=corporate". The variables user/pass are passed in through the basic login box.
I am trying to do this through ActiveLdap however I dont mind using any other library as long as I can validate the credentials through a single sign on against our LDAP server using the HTTPAuth since is written completely in Webrick Ruby. Below is a sample of the function I am calling.
Does anyone have any idea how to do this?
Thanks in advance.
def authenticate_ldap(req,res)
authlabel = "LDAP Authentication"
HTTPAuth.basic_auth(req, res, authlabel) { |user, pass|
ActiveLdap::Base.setup_connection(
:host => 'ldap.internalserver.com',
:port => 389,
:bind_dn => "cn=#{user},ou=it,o=corporate",
:password_block => Proc.new { pass },
)
}
return
end
I figured out a solution. The person who manages our LDAP server provided the incorrect ldap connection string, but even with that it still didn't work.
The solution I discovered that did indeed make a connection with very basic validation is something to this effect for anyone else interested in a very simple ldap authentication popup in pure Ruby.
def authenticate(req,res)
authlabel = 'LDAP Authentication'
HTTPAuth.basic_auth(req, res, authlabel) { |user, pass|
if pass.to_s != ''
ldap = Net::LDAP.new
ldap.host = "ldap.serverfoo.com"
ldap.port = 389
result = ldap.bind_as(
:base => "t=basetreefoo",
:filter => "uid=#{user}",
:password => pass
)
if result
ldap = Net::LDAP.new :host => "ldap.serverfoo.com",
:port => "389",
:auth => {
:method => :simple,
:username => "",
:password => ""
}
group_name = Net::LDAP::Filter.eq("cn", "#{user}")
group_type = Net::LDAP::Filter.eq("groupmembership", "cn=infra,ou=IT,o=Corporate")
filter = group_name & group_type
treebase = "t=basetreefoo"
ldap.search(:base => treebase, :filter => filter) do |entry|
if entry.dn.to_s != ""
puts 'success'
return
end
end
end
end
puts 'fail'
}
end

Twitter User Hash for Sorcery Authentication

I'm using the Sorcery gem and their external module to authenticate with Twitter. I've got the authentication working, but I want to store the user's Twitter profile image URL in my database after a successful log in. Sorcery seems to have a configuration option that's meant to do exactly what I want:
config.twitter.user_info_mapping = {:nickname => "screen_name"}
Maybe I've missed something in the Sorcery documentation, but I can't find any information about what "keys" are available. I tried this to no avail:
config.twitter.user_info_mapping = {:nickname => "screen_name", :avatar_url => "profile_image_url"}
Has anyone found documentation about this?
That is just what you get from twitter in json format.
Here is a twitter documentation about it https://dev.twitter.com/docs/api/1/get/account/verify_credentials
config.twitter.user_info_mapping = {:username => "screen_name",
:realname => "name",
:location => "place",
:web => "url",
:bio => "description"}

Troubleshooting Active Merchant returning "Failed with 500 Internal Server Error"

The following code
purchase = #order.authorize_payment(#credit_card, options)
is_success = purchase.success?
if is_success
...
else
flash[:notice] = "!! " + purchase.message + "" +
purchase.params['missingField'].to_s
redirect_to :action => :payment, :id => #order.id
end
results in "!! Failed with 500 Internal Server Error" in my flash[:notice]. There is no stacktrace, no webserver error, all that I know is that purchase.message is populated and purchase.success? is false.
I am really at a loss to figure out how to troubleshoot this. I think it might be an ssl requirement, but I can't either see the soap request, or test basic connectivity with cybersource (my payment gateway).
I establish my gateway with this code (after config.after_initialize do):
ActiveMerchant::Billing::Base.mode = :production # :test
ActiveMerchant::Billing::CreditCard.require_verification_value = false
ActiveMerchant::Billing::CyberSourceGateway.wiredump_device = File.new(File.join([Rails.root, "log", "cybersource.log"]), "a") # doesn't work (!)
# we need to open an external file to get the password
mypassphrase = File.open('/var/www/foo/shared/passphrase.txt').read
OrderTransaction.gateway = ActiveMerchant::Billing::CyberSourceGateway.new(:login => 'vxxxxxxx',
:password => mypassphrase.to_s,
:test => false,
:vat_reg_number => 'your VAT registration number',
# sets the states/provinces where you have a physical presense for tax purposes
:nexus => "GA OH",
# don‘t want to use AVS so continue processing even if AVS would have failed
:ignore_avs => true,
# don‘t want to use CVV so continue processing even if CVV would have failed
:ignore_cvv => true,
:money_format => :dollars
)
Can I see the soap request? Are there ways to test part of this? Any help greatly appreciated.
Best,
Tim
ActiveMerchant::Billing::CyberSourceGateway.logger = your_logger
So, late response but...
I've done a good amount of work with the Cybersource gateway, and the only way to see the SOAP request/response of the cybersource gateway currently is to open up the gem and edit it.
If you modify the commit method of lib/active_merchant/billing/gateways/cybersource.rb, you can do something like this:
def commit(request, options)
puts "*** POSTING TO: #{test? ? TEST_URL : LIVE_URL}"
request = build_request(request, options)
puts "*** POSTING:"
puts request
begin
post_response = ssl_post(test? ? TEST_URL : LIVE_URL, request)
rescue ActiveMerchant::ResponseError => e
puts "ERROR!"
puts e.response
end
puts post_response
It would be nice if there was a way to get that response without going through that hassle, I'll see if there's a way to pass that information up through the response object that's returned and add it to my fork.

Resources