Rails Authentication: Devise with LDAP with multiple configs and database authenticatable
Update two years later: In the two years since this was made (and this post written)
there have been no issues related to the login. Both the database and the LDAP logins still
work perfectly. Given that I still remember the pain of making this, feel free to get in touch
if you need any help.
Getting LDAP integration to work with Devise is quite trivial. The LDAP Authenticatable
gem works very well out of
the box and getting it up and running requires only minimal effort. You do have to take note
that in order for bind to work the admin_user setting has to be fully qualified name
of the admin user. That means that it has to include the entire directory structure from
the username downwards.
In a recent project however, I had to integrate with a client’s ActiveDirectory that had
servers segmented by role. The server that the user was authenticated with also needed to
be used to determine what roles the user should have in the application. In addition, the
client required the database authentication to remain in tact so that they would be able
to use accounts local to the application.
A quick Google session would find the solution for having multiple configurations for
LDAP servers – however not for entirely separate servers that are to be sequentially tried
till the user is authenticated.
Another quick Google session would help you find a way to preserve database authentication
while still having the LDAP auth in tact.
Integrating the two however took a little bit of work so it shall be documented here for
future reference and in hopes that it will help someone else.
Firstly, we will modify devise.rb to cater for LDAP and database simultaneously.
Following is how we define the strategy to be used. It’s very similar to the
original Devise strategy except it checks whether the user trying to log in is
actually from AD – once a user is authenticated via LDAP it will be copied to
the database and can then authenticate locally and we don’t want that.
Next, we move on to changing the way ldap_authenticatable works with mulitple configs.
We start by changing the structure of ldap.yml file – the config file that devise_ldap_authenticatable
Given that the configuration is no longer what the gem expects we need to change
the relevant methods. The most significant here is the Connection class. It’s been
altered to actually accept a config and not try to load one itself.
Following that we need to add the looping mechanism that will progressively try
the different configurations in the authentication function and we need to change
other functions that are commonly used to accept a config directly and not open one