Skip to content
Native Ruby Access to Microsoft Active Directory
Pull request Compare This branch is 5 commits ahead, 4 commits behind richardun:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


**Coming Soon:**  
I'm reworking this gem to allow simulatneous and multiple connections. 
Also, I'll be adding RSpec test units for all the methods.  Stay tuned!


Active Directory

Ruby Integration with Microsoft's Active Directory system based on original code by Justin Mecham and James Hunt at

See documentation on ActiveDirectory::Base for more information.


Queries for membership and group membership are based on the distinguished name of objects. Doing a lot of queries, especially for a Rails app, is a sizable slowdown. To alleviate the problem, I've implemented a very basic cache for queries which search by :distinguishedname. This is diabled by default. All other queries are unaffected.

Install (with Bundler for instance)

In Gemfile:

gem 'active_directory', :git => 'git://'

Run bundle install:

$ bundle install

Base setup

You can do this next part however you like, but I put the settings global variable in ../config/initializers/ad.rb...

# Uses the same settings as net/ldap
  :host => 'domain-controller.example.local',
  :base => 'dc=example,dc=local',
  :port => 636,
  :encryption => :simple_tls,
  :auth => {
    :method => :simple,
    :username => "username",
    :password => "password"

Simple finds using attributes

Then I put the base initialization in ../app/controllers/application_controller.rb...


Then in my model, or anywhere really, I can look for AD users, etc.

ActiveDirectory::User.find(:first, :userprincipalname => "")


# Caching is disabled by default, to enable:

ActiveRecord example

You can also limit the fields that get returned, just like with ActiveRecord.

In ActiveRecord, you use :select => ['select this', 'or', 'that'] - you can do this or use the net/ldap syntax of :attributes => # ... You should use one or the other, but not both.

ad_user = ActiveDirectory::User.find(:all, :attributes => ['givenname', 'sn'])

# if you don't give it an array and just one item, that's ok too...
ad_user = ActiveDirectory::User.find(:all, :attributes => 'givenname')

puts ad_user.givenname #=> Richard
puts #=> Navarrete
puts #=> Richard Navarrete

# But looking for a field you didn't return will raise an ArgumentError.
puts ad_user.mail #=> ArgumentError: no id given


You can pass any filter you can make in Net::LDAP::Filter along in the find.
In this example, I have a couple of groups that a given user can be a member of.
If they are a member of either of the groups (memberOf) then a user will be returned.

groups = ['CN=admins,OU=Security,OU=Groups,DC=Example,DC=Local', 'CN=HR,OU=Security,OU=Groups,DC=Example,DC=Local']

# Don't miss this important step -> be sure to put double quotes in the value, no matter if it's a
# single variable string that you're interpolating... it must be there or Net::LDAP::Filter will
# treat it like an Array and won't find gsub and error out!
filter = Net::LDAP::Filter.eq('distinguishedName', "#{session[:current_user][:dn]}")

# Same thing here with the memberOf equals... must have double quotes!
# Notice the |= under else, this will make the groups all OR conditions.
# Obviously replace this with &= if you require that the give user be 
# a member of ALL the given groups. 
right_filter = nil
groups.each do |group|
  if right_filter.nil?
    right_filter = Net::LDAP::Filter.eq('memberOf', "#{group}")
    right_filter |= Net::LDAP::Filter.eq('memberOf', "#{group}")

filter = filter & (right_filter)

# Assuming you already setup the Base, but just in case...

ad_user = ActiveDirectory::User.find(:all, filter)

Updating thumbnailPhoto attribute in AD!

First, why would you want to do this? I did it so that users could upload a photo in one place, and it would update other applications with user avatars where it was more convenient instead of making those applications point to a URL. Basically, if you update thumbnailPhoto with an image, the user pic will show up for users in MS Outlook, MS Lync, etc. Here is something I included in a user model (with email as an attribute), to update the coorsponding AD account with a thumbnailPhoto. Use AD gem's update_attribute.

def update_ad_profile_pic
    ad_user = ActiveDirectory::User.find(:first, :mail =>
    if ad_user.present?
      picture_data = image_to_bytes
      ad_user.update_attribute(:thumbnailPhoto, picture_data)
  rescue Exception => e
    logger.error("** Failed updating AD photo for: #{} \n#{e.message}")


# convert this user's "image_tiny" byte-by-byte and return
# using Dragonfly here for the image, but you can use anything... it's just an image
def image_to_bytes
  picture_data = ""
  file ="#{Rails.root}/public/#{self.image_tiny.remote_url}",'rb') do |byte|
    picture_data << byte
Something went wrong with that request. Please try again.