Last updated 15 March 2011. Created on 3 July 2007.
Edited by sinkingfish, matt2000, cscsteve. Log in to edit this page.

You may have Drupal setup as your web root and also have other subdirectories that contain non-Drupal content or applications. If you want to provide authentication via basic http authentication to protect those areas, it is easy to set it up to authenticate against your Drupal users.

If you want to provide basic http authentication to protect your Drupal site, you'll need to use a module like Secure Site. Using Secure Site in conjuction with basic authentication on other site areas provides a seamless authentication between Drupal and the rest of your site. Since your users have already authenticated for the Drupal area and browsers cache basic http authentication, your users won't have to see the authentication box again.

To protect the other areas you need to setup Apache to authenticate against Drupal's users table. It is possible to use basic auth vs a mysql db table. In this case, we'd want to put basic auth over the entire site, with the data lookup on the Drupal users table. You must uses the mod_auth_mysql module for Apache. Basically (for Apache 2.x, 1.x is similar):

Ubuntu Server

Note: Some versions of Ubuntu have a bug in this package, so you may still need to compile yourself as below, or install using dpkg and the latest .deb here: https://launchpad.net/ubuntu/+source/mod-auth-mysql (You may even be able to install a version for a Release newer than yours, but YMMV.)

  1. Install mod_auth_mysql:
    sudo apt-get install libapache2-mod-auth-mysql
    
  2. Enable mode_auth_mysql
    cd /etc/apache2/mods-enabled
    sudo ln -s ../mods-available/auth_mysql.load
    
  3. Create an .htaccess file as follows:
    AuthName "site name"
    AuthType Basic
    
    Auth_MySQL On
    Auth_MySQL_Authoritative on
    
    Auth_MySQL_Host <db_host>
    Auth_MySQL_Username <db_user>
    Auth_MySQL_Password <db_password>
    Auth_MySQL_DB <db_name>
    Auth_MySQL_Password_Table users
    Auth_MySQL_Username_Field name
    Auth_MySQL_Password_Field pass
    Auth_MySQL_Encryption_Types PHP_MD5
    Auth_MySQL_Password_Clause " AND status=1"
    Auth_MySQL_Empty_Passwords Off
    
    AuthBasicAuthoritative Off
    AuthUserFile /dev/null
    
    require valid-user
    

Other Platforms

  1. Download mod_auth_sql via (substitute your sourceforge mirror of choice if you like):
    wget http://superb-east.dl.sourceforge.net/sourceforge/modauthmysql/mod_auth_mysql-3.0.0.tar.gz
  2. compile mod_auth_sql:
    [root@server1 mod_auth_mysql-3.0.0]# /usr/sbin/apxs -c -L/usr/lib/mysql -I/usr/include/mysql -lmysqlclient -lm -lz mod_auth_mysql.c
  3. Install mod_auth_sql:
    /usr/sbin/apxs -i mod_auth_mysql.la
  4. Configure Apache to use it by adding the following line to httpd.conf:
    LoadModule mysql_auth_module modules/mod_auth_mysql.so
  5. Configure authentication. You can do this in .htaccess files, but after getting it working, it's best to do it in the httpd.conf sites section:
    AuthName "SiteName"
    AuthType Basic
    AuthMySQLHost localhost
    AuthMySQLUser drupaluser
    AuthMySQLPassword *******
    AuthMySQLDB drupal
    AuthMySQLUserTable users
    AuthMySQLNameField name
    AuthMySQLPasswordField pass
    AuthMySQLPwEncryption md5
    AuthMySQLEnable On
    AuthMySQLUserCondition "status=1"
    require valid-user
    

    Obviously, replace AuthMySQLUser, AuthMySQLPassword, AuthMySQLDB with the correct settings.

    The AuthMySQLUserCondition directive causes only active drupal users to access the protected directories. This way, if you block a user in the admin area, that user will no longer have access. This directive adds sections to the "WHERE" clause of the SQL lookup statement, so if you want to restrict based on roles you can do that also.

Note that Drupal uses md5 hashes for the password field.

That's all there is to it. Site-wide basic authentication should work if you add this to every directory subpart of the site. Note that this won't replace application html login pages, sessions, or any integration beyond basic authentication, but it will protect the portions of the site you need to protect. Further integration will require more work.

Note that this does not provide encryption for the login, remember to configure SSL if you want to encrypt the authentication.

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

seanr’s picture

Here's a version of this set to require users with a role higher than 2 (authenticated), so users who just sign up still can't see the files until an admin promotes them:


AuthName "YourSite"
AuthType Basic

# Database settings:
AuthMySQLHost localhost
AuthMySQLUser dbuser
AuthMySQLPassword dbpass
AuthMySQLDB dbname

# User table
AuthMySQLUserTable users
AuthMySQLNameField users.name
AuthMySQLPasswordField users.pass

# User Roles tables
AuthMySQLGroupTable "users, users_roles"
AuthMySQLGroupField users_role.rid

# Where clauses
AuthMySQLUserCondition "users.status = 1 and users.access <> 0"
AuthMySQLGroupCondition "users.uid = users_roles.uid AND users_roles.rid > 2"

# Do it to it!
AuthMySQLPwEncryption md5
AuthMySQLEnable On
require valid-user

Sean Robertson
webolutionary@webolutionary.com

lowriep’s picture

Here's an .htaccess example which allows access by any
authorised user who is also a member of a Specific Role.

AuthName                 "MY Site"
AuthType                 Basic

#MySQL DB
AuthMySQLHost           mysql_server_name
AuthMySQLuser            mysql_user_name
AuthMySQLPassword     ****************
AuthMySQLDB              mysql_db_name

# User Table
AuthMySQLUserTable       users
AuthMySQLNameField       users.name
AuthMySQLPasswordField   users.pass
AuthMySQLPwEncryption    md5

# Group Tables
AuthMySQLGroupTable      "users, role, users_roles"
AuthMySQLGroupField      "role.name"

#The SQL for user/role goes like this:
#
#  SELECT users.name AS name, role.name AS role
#    FROM role,users,users_roles
#    WHERE users_roles.uid = users.uid
#    AND users_roles.rid=role.rid
#    AND role.name = 'some_specific_role';

# WHERE Clauses
AuthMySQLUserCondition  "users.status=1 and users.access <> 0"
AuthMySQLGroupCondition "users_roles.uid=users.uid AND users_roles.rid=role.rid"

AuthMySQLEnable          On
require group            some_specific_role
Skyr’s picture

In my case, Apache still tried to access a password file containing username/hash pairs; of course, the AuthUserFile was no longer set - which resulted in a

Internal error: pcfg_openfile() called with NULL filename

error. The solution that worked for me: Add the

AuthBasicAuthoritative Off

directive to your .htaccess file.

ge’s picture

After setting Basic authentication on a staff-internal Drupal site, I found the Drupal status report started saying cron had not run in some time, although I was still able to click "run cron manually" with no trouble.

The system cron was not able to run Drupal's cron.php script because it did not have login credentials. The crontab entry was:

45 * * * * curl --silent --compressed http://www.example.com/cron.php

To correct this problem, I added the login and password to the crontab entry:

45 * * * * curl --silent --compressed --user username:password http://www.example.com/cron.php

This works fine with regular Basic authentication using Apache's password file. If the Basic authentication is going to run against the Drupal users table, you might want to set one permanent user whose password never changes, in order to avoid making repeated manual updates to crontab.

cpho’s picture

I want to check the path of URL with data in Database.

%h DNS name of the remote host
%a IP address of the remote host
%f The filename being requested
%V Hostname of the Apache server
%v Virtual hostname
%H Protocol sent with the request (i.e. HTTP/0.9)
%m Request method (i.e. GET, HEAD, POST, etc.)
%q Arguments following the ? in the request
%r Request line
%U Path portion of the URI

I think i could set : AuthMySQLUserCondition "PATH= '%U'"
with in mysql database I set PATH like : "myweb" (Full path is : http://xxx.xxx.xxx.xxx/myweb)

In this case using %U is OK ??? Or another parameter.

Please tell me.

Thanks.

sinkingfish’s picture

I was having the problem :-

Invalid command 'Auth_MySQL_User'

Changing the property to Auth_MySQL_Username solved it.

Anonymous’s picture

I've tried it, and it seems D7 now stores passwords with sha512 encryption, and it seems mod_auth_mysql does'nt yet support it?

apop’s picture

Anyone know of an alternative to mod_auth_mysql that supports sha-512? Looks like mod_auth_mysql hasn't been updated since 2005.

drzraf’s picture

[rant]
working around Drupal (phpass) pitfall :
https://github.com/machtfuernacht/mod_authnz_mysql/tree/raphael

As the same applies to pam : https://github.com/NigelCunningham/pam-MySQL

Prepare to wait some years until it is packaged, until then let's use that git/development code on our -prod boxes (that's the cost for "enhanced" (= non standard) crypto choices.
[/rant]

Ali1365’s picture

Hi,

Sorry for bringing up an old topic. I'm facing the same issue and decided to give mod_dbd a shot. Class crypt is capable of sha512 with salt.
-----------------------------------------------------------------------------------------------------------------

DBDriver mysql
DBDParams "host=localhost port=3306 dbname=***** user=***** pass=*****"


AuthType Basic
AuthName "Protected. Please login !!!"

# To cache credentials, put socache ahead of dbd here
AuthBasicProvider dbd
# mod_authz_core configuration
Require valid-user
# mod_authn_dbd SQL query to authenticate a user
AuthDBDUserPWQuery "SELECT crypt(pass,"\$6\$D\$") FROM users WHERE name = %s and status = 1"


-----------------------------------------------------------------------------------------------------------------
I also found this article which might help:
http://morknet.de/smork/entry/apache-basic-authentication-mit-mysql/

I just can't figure out the statement to make it work. Something like:
crypt("password","\$6\$saltsalt\$")
crypt.crypt('password', '\$6\$saltsalt\$')

Any idea?