HOWO: Use Drupal For HTTP Authentication

Profile picture

Very often, a Drupal website is just one of many tools being deployed on a complex project. For instance, on Chapter Three's development servers, we keep our own SVN repositories to track custom modules and theme development.

Also often, miscellanious web services like this will want to use the standard HTTP Authentication system. Most simply this is the familiar pair a .haccess and .htpasswd file protecting a directory. Easy to set up, but it requires an admin to keep yet another list of usernames and passwords somewhere on the system which over time becomes quite a pain.

Today, while noodling with some authentication scripts for the Drupal Dojo, I decided to see if Drupal's own user table could be used as an authentication source for these tasks. Turns out it can, and it's pretty useful too.

Drupal User Authentication
First off, this requires mod_auth_mysql to be set up in your Apache server. There are packages for most systems, as this is a common and widely used Apache module. Once this is done, use the following code in a .htaccess file or Apache <Directory> or <Location> directive:

AuthName "Use Your Drupal Login"
AuthType Basic
AuthMySQLEnable On
AuthMySQLHost <hostname>
AuthMySQLDB <database>
AuthMySQLUser <user>
AuthMySQLPassword <password>
AuthMySQLUserTable users
AuthMySQLNameField name
AuthMySQLPasswordField pass
AuthMySQLPwEncryption md5
require valid-user

Replace the hostname, database, user and pass values just as you would when configuring your drupal installation's setting.php file. This will let Apache access the same users table from Drupal and authenticate against it!

Limiting Access By Drupal User Role
For extra credit, you can restrict valid logins to a particular user role by replacing the AuthMySQLUserTable directive above with these two lines:

AuthMySQLUserTable "users, users_roles"
AuthMySQLUserCondition "users.uid = users_roles.uid AND users_roles.rid = 3"

The above assumes that your "admin" role has role id (rid) 3. Your mileage may vary here, and savvy SQL query writers will immediately see how you can use these two directives to limit access in all sorts of ways.

For admins with a lot of experience with mod-auth-mysql, this is all pretty obvious, but I hadn't seen documentation specific to Drupal anywhere on the web. Hopefully this will simplify your life as much as it's already simplifying mine!

Comments

If you want to make the Drupal site itself use HTTP Auth as well, then you can add the secure site module. All the site(s) are now authenticating via the Drupal database, AND using HTTP Auth.

Securesite was my inspiration here, but the intention with this knowledge is not to use HTTP Auth for Drupal, but rather to use Drupal as the system of record for other systems (e.g. SVN) which support HTTP Auth as an authentication method.

The upside here is all about integration.

Check out the securesite module. It might be easier to use.

This might not be a good solution when you have both Drupal and non-Drupal pages on the same domain that you want to restrict access to. Because, presumably, if the user logs into Drupal and then visits a non-Drupal page where authentication is handled by mod_auth_mysql, the user will have to log in again via the HTTP prompt. Correct? Making users log in twice is no good.

You are right, but at the same time it might be exactly what you want: if you need to access Drupal with different credentials. In my case I wanted a single log-in, as you describe, but then I realised I could not switch to a different user in Drupal (for ex. for testing) without also changing my HTTP Auth session. I now prefer to have same password but different log-in sessions. Of course it all depends on the way web services are used: it work great in our settings but it's a specific case.

I was struggling to get it working on ubuntu hardy with apache2, mysql 5 and php 5, here is a working configuration that I got after a couple of hours:

AuthName "Use Your Drupal Login"
AuthBasicAuthoritative Off
AuthType Basic
AuthMySQL On
AuthMySQL_Authoritative on
AuthMySQL_Host localhost
AuthMySQL_DB dbaname
AuthMySQL_User dbuser
AuthMySQL_Password dbpwd
AuthMySQL_Password_Table "users, users_roles"
Auth_MySQL_Password_Clause " AND users.uid = users_roles.uid AND users_roles.rid = 3"
AuthMySQL_Username_Field name
AuthMySQL_Password_Field pass
AuthMySQL_Empty_Passwords off
AuthMySQL_Encrypted_Passwords on
AuthMySQL_Encryption_Types PHP_MD5
require valid-user

Hope this save a few hours of other fellas

Cheers
Mehrdad

I came across this rather nasty little bug when trying to do this:

https://bugs.launchpad.net/ubuntu/+bug/150649

I think DBD is now the preferred method of authenticating against a database by the sound of it... might see if I can do a similar thing using DBD.

http://httpd.apache.org/docs/2.2/mod/mod_authn_dbd.html

Steve

That sounds very useful as a mean of providing a nice web interface to SVN users to request new SVN accounts or change their passwords.

Any ideas on how one would proceed to import an already existing SVN auth file (passwords generated using htpasswd) into a new Drupal installation?

The reason I'm asking this is that I already have a working SVN setup with several users, and I do not wish to ask my SVN users to create an account in Drupal. It would be simpler if I could simply re-use their existing SVN username and password.

Unfortunately, this isn't possible. Drupal uses PHP's MD5 hashing method for storing one-way encrypted passwords. This is different from the htpasswd encryption method (which is either an apache-specific md5() or crypt()).

On the upside, if you migrate things into Drupal, people can use a "forgot password" url to get a one-time login link and reset their credentials.

This is a nify trick. Note, however, that Drupal 7 no longer uses MD5 to hash passwords, so this technique might not work well moving forward.

Regarding cleanly integrating with http authentication, I have successfully used mod_auth_cookie to share authentication information between Drupal and Apache. If you log in through Drupal first, then you won't get the http basic auth dialog when you go to an http-auth-protected page. At the moment I am using export_users_dbm to integrate, which is similarly dependant on the fact that Drupal 6 and earlier use MD5 password hashes, so I'm looking around for other options to achieve SSO.

Add comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <br> <br/> <br /> <p> <img> <blockquote> <i> <b> <u>
  • Lines and paragraphs break automatically.
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options

By submitting this form, you accept the Mollom privacy policy.

Client Testimonial

We have found Chapter Three to be a valuable resource in both training and development of custom Drupal functionality. In addition, getting Chapter Three’s help with scaling Drupal has been a real asset.

Jim Nisbet, CTO Highwire Press

Drupalcon SF 2010