I think having a drupal authentication base class (for "drupal" authentication") that could be extended by external authentication modules would save a lot of code and make implementing ldap, cas, etc. easier. If done right the user interface for admins could be more consistent and the login sequence more predictable.

Hooks could be used throughout the authentication process so non authentication modules could react to the process; but authentication modules would be expected to implement certain properties and methods. Simpletests would become easier to share for external auth modules also.

It might end up we need two base classes; one for drupal form based authentication and one for tools such as openid, cert based, and cas where you enter your credentials elsewhere.

something like:

Authentication Class Properties:

An instance of this class represents an authentication means such as an ldap server, cas, or drupal.

  • boolean enabled
  • string moduleName
  • string instanceID (instance identifier. for ldap it might be server id. needed for cases where a single module provides more than one authentication means)
  • boolean provisionDrupalAccounts signifies if successful authentication can lead to drupal user account creation.
  • boolean allowPasswordResetinDrupal signifies if password stored in external structure (ldap, shib, etc.) can be reset via drupal reset pwd interface.
  • string passwordResetURL
  • string accountHelpURL

Authentication Class Methods:

  • __construct($username)
  • authenticationDerivedUserAttributes($username, $uid = NULL); returns array of attributes such as mail, first name, last name, etc. that could be mapped to drupal profile, account, etc.
  • drupalAccountExists()
  • userCredentialTest($pwd)

Then instead of every external author module figuring out how to fit itself into the the authentication process, user_login_authenticate_validate() could look something like:

function user_login_authenticate_validate($form, &$form_state) {
  $name = $form_state['values']['name'];
  $password = trim($form_state['values']['pass']);
  $drupal_accnt = drupal_account_from_name($name);
  check flood issues given name

  $authn_providers = module_invoke_all('authentication_providers');
  $results = array();
  if ($drupal_acct->uid == 1) {
    // for user 1, only allow authentication on user module.
    $authn_providers = array('user__drupal' => $authn_providers['user__drupal']);
  }
  foreach ($authn_providers  as $instance_id => $instance_data {
    require_once($instance_data['class_path']);
    $authn = new {$instance_data['classname']}($instance_data, $name);
    $results[$instance_id]['authn_object'] = $authn;
    $result = $authn->userCredentialTest($password);
    if (!$result) {
      $results[$instance_id]['result'] = USER_AUTHN_CREDENTIAL_FAILED;
      continue;
    }

    if (!$drupal_accnt) {
      if (!$authn->provisionDrupalAccounts) {
        $results[$instance_id]]['result'] = USER_AUTHN_ACCT_MISSING;
        continue;
      }
      list($result, $user_data) = $authn->provisionAccount($name);
      if (!$result) {
        $results[$instance_id]['result'] = USER_AUTHN_FAILED_TO_CREATE_ACCT;
        continue;
      }
      else {
        user_external_login_register($name, $user_data, $authn);
      }
    }
    
    $results[$instance_id]['result'] = USER_AUTHN_SUCCESS;
    $user->authnObject = $authn;
    exit;
  }
if ($results[$instance_id]['result'] == USER_AUTHN_SUCCESS)) {
    user_login_finalize();
    user_module_invoke('login', $user_data, $user);
  }
  else {  // no authentications succeeded.  
    if (count($authn_providers) == 1) { // if only one authentication provider, allow it to generate error msg
       list($field, $message) = $authn->loginFormSetError();
       form_set_error($field, $message);
    }
    else {
      form_set_error('name', t('Sorry, unrecognized username or password. <a href="@password">Have you forgotten your password?</a>', array('@password' => url('user/password'))));
      watchdog('user', 'Login attempt failed for %user.', array('%user' => $form_state['values']['name']));
    }
  }
}

Comments

corvus_ch’s picture

Drupal 8 now ships with a pluggable authentication system that is also capable of dealing with non session based means of authentication. See #1890878: Add modular authentication system, including Http Basic; deprecate global $user.

I am not sure if this feature request is still valid and should remain open or if it can be closed as a duplicate.

colan’s picture

I'm running into this myself in D7 trying to get LDAP and my OAuth2 Authentication module working together.

It seems like the new modular authentication system should do the trick in D8. Modules like ours would need to implement AuthenticationProviderInterface.

@johnbarclay: Do you think that would work? If so, we can mark this as a duplicate.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

bradjones1’s picture

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

prudloff’s picture

It seems like the new modular authentication system should do the trick in D8.

So is this issue still needed?

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.