Adding Secondary Validation to Drupal’s User Login

Want to add another layer of authentication to the default Drupal login? Say, by calling a company’s internal web service? Here’s a clean approach I’ve taken. Notice that we are inserting our secondary authentication into the validators, rather than overriding anything. Also notice that if we authenticate against our local Drupal DB, there’s no reason to look at the secondary web service or DB, but rather we only look if our default local authentication failed. Then, if we authenticate against our secondary source, we create a user to be used later on.

One additional note, you should do some checking when a user’s local authentication fails, but they exist in your secondary web service or DB, in case their password has changed there.
/*
* See user_login_default_validators in user.module
*/
function MYMODULE_validators() {
return array(‘user_login_name_validate’, ‘user_login_authenticate_validate’, MYMODULE_authenticate_validate’, ‘user_login_final_validate’, ‘MYMODULE_final_validate’);
}
 
function MYMODULE_final_validate($form, &$form_state){
// DO SOME FINAL VALIDATION OR OVERRIDE DEFAULT LOGIN ERRORS
}
 
function MYMODULE_authenticate_validate($form, &$form_state){
// has the user failed local authentication?
if (empty($form_state['uid'])) {
$username = $form_state['values']['name'];
$password = trim($form_state['values']['pass']);
$user=user_load_by_name($username);
 
// DO SOME USER AUTHENTICATION AGAINST ANOTHER WEB SERVICE OR DB
 
 
 
$newUser= array(
‘name’ => $username,
‘pass’ => $password,
‘mail’ => $email, // get email from service or db
‘status’ => 1,
‘roles’ => $roles, // get roles according to rules against service or db
);
user_save(null, $newUser);
$form_state['uid'] = user_authenticate($username,$password);
}
 
}