Active Directory (LDAP) Authentication in WordPress Multi-Site
September 9th, 2010 | Published in Mind
As many of you know, I led the team that launched the College of Education at UGA’s new website (http://www.coe.uga.edu/) which is driven by WordPress Multi-Site. The first phase is complete, and the second phase has started up. Part of their second phase is to allow a custodian from each department to edit content on their own departmental site. UGA uses Active Directory campus wide, so I thought it would be best to incorporate the WordPress authentication mechanism into UGA’s current AD implementation.
When I first researched this there weren’t many plugins for WordPress Multi-Site that handled AD/LDAP authentication. I was planning on writing one myself, but I found one yesterday by Clifton Griffin called Simple LDAP Login. I installed in on a development website, put in the necessary information and BAM it worked… but it wasn’t really designed for WordPress Multi-Site. What I needed was every site to use the Active Directory authentication, without having to set each site up individually. So I paired down the code a bit (to just what I needed) and stuck the files in the mu-plugins dir.
Clifton used the opensource PHP LDAP Class in his plugin, which works great. So, in my version, I stripped out everything I didn’t need/want like auto account creation, non-AD functionality, etc. Basically, I just needed to authenticate users via Active Directory.
So I stuck this code into a file in my mu-plugins folder. Now whenever anyone tries to authenticate it, uses Active Directory instead of WordPress’ user table:
<?php
require_once( WPMU_PLUGIN_DIR . '/simple-ldap-login/adLDAP.php' );
define( 'DOMAIN_CONTROLLERS', 'active.directory.controller.domain' );
define( 'SECURITY_MODE', 'high' );
define( 'ACCOUNT_SUFFIX', '@account.edu');
define( 'BASE_DN', 'OU=OUOU,DC=DCDC,DC=EDU' );
define( 'USE_TLS', false );
define( 'USE_SSL', true );
//Authenticate function
function sll_authenticate( $user, $username, $password ) {
if ( is_a( $user, 'WP_User' ) ) { return $user; }
//Failed, should we let it continue to lower priority authenticate methods?
if( "high" === SECURITY_MODE ) {
remove_filter('authenticate', 'wp_authenticate_username_password', 20, 3);
}
if ( empty( $username ) || empty( $password ) ) {
$error = new WP_Error();
if ( empty( $username ) )
$error->add( 'empty_username', __( 'ERROR: The username field is empty.' ) );
if ( empty($password) )
$error->add( 'empty_password', __( 'ERROR: The password field is empty.' ) );
return $error;
}
if( sll_can_authenticate( $username, $password ) ) {
$user = get_userdatabylogin( $username );
if ( !$user || ( strtolower( $user->user_login ) != strtolower( $username ) ) ) {
do_action( 'wp_login_failed', $username );
return new WP_Error( 'invalid_username', __( 'Login Error An error occurred while attempting to log in. If this continues please contact coeweb@uga.edu for support.' ) );
} else {
//we're ready to return the user
return new WP_User( $user->ID );
}
} else {
return new WP_Error( 'invalid_username', __( 'Login Error An error occurred while attempting to log in. If this continues please contact coeweb@uga.edu for support.' ) );
}
}
add_filter( 'authenticate', 'sll_authenticate', 1, 3 );
function sll_can_authenticate( $username, $password ) {
$sll_options = array(
'account_suffix' => ACCOUNT_SUFFIX,
'base_dn' => BASE_DN,
'use_tls' => USE_TLS,
'use_ssl' => USE_SSL,
'domain_controllers' => explode( ';', DOMAIN_CONTROLLERS )
);
$adldap = new adLDAP( $sll_options );
$result = false;
$result = $adldap->authenticate( $username, $password );
return $result;
}
Tags: active directory, ldap, mu-plugins, open source, plugins, wordpress, wpms

