Hi,

Is there any documentation for this module? I need to authenticate our Drupal users against an external system that provides Oauth 2.0 (yes I know its meant for authorisation purposes), but I can't seem to find any documentation for this module.

Is there anything that can help me get started? Is the module fit for this use case?

Thanks!

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

kyuubi created an issue. See original summary.

colan’s picture

Title: How to use? » Add missing developer documentation
Version: 8.x-1.0-alpha4 » 8.x-1.x-dev
Category: Support request » Task
Priority: Normal » Major

This needs to get done, but until that happens a workaround is looking at how other modules are making use of it. Here are some depending modules:

#2773363: Example provider would be nice too.

colan’s picture

After figuring this out for Certificate Login, I discovered that the API basically consists of these two interface definitions:

The former deals with the user mapping while the latter deals with user operations.

They're both implemented as services that can be injected into your (controller) classes from the service container. Take a look at the Certificate Login code for my example.

All of this needs to be put into a README.

kevinquillen’s picture

I looked at CertificateLogin, but don't see where you are leveraging ExternalAuth module code.

colan’s picture

kevinquillen’s picture

Ahhh, I see. So you can just inject the basic implementation that module provides.

I will give this a shot later. It should be simple to swap out parts of the SSO I just did and use those two classes.

kevinquillen’s picture

Well, I know a little more now. I did not use External Auth when implementing SSO on a project, but I suppose I could now. The refactor effort would be too great at this point for something I have working and covered with tests.

It would still be great to include an example or two in the module or README as a starting point.

Jody Lynn’s picture

Here's a pretty simple approach to starting to integrate with the Drupal login form.


use Drupal\Core\Form\FormStateInterface;

function example_auth_form_user_login_form_alter(&$form, FormStateInterface $form_state) {
  // Add external user login validation in user_login_form
  // after ::validateAuthentication
  // and before ::validateFinal.
  if (@in_array('::validateFinal', $form['#validate'])) {
    $key = array_search('::validateFinal', $form['#validate']);
    $form['#validate'][$key] = 'example_auth_authenticate';
    $form['#validate'][] = '::validateFinal';
  }
}

function example_auth_authenticate(array &$form, FormStateInterface $form_state) {
  if (!$form_state->get('uid')) { // Default Drupal authentication failed, so try alternative means.
    $name = $form_state->getValue('name');
    $password = trim($form_state->getValue('pass'));

    if ($account_data = example_auth_get_account_data_if_valid($name, $password)) {
      $authmap = \Drupal::service('externalauth.authmap');
      $externalauth = \Drupal::service('externalauth.externalauth');
      $provider = 'example_auth';

      // loginRegister will only make a new account if one does not exist.
      $account = $externalauth->loginRegister($name, $provider, $account_data);

      $form_state->set('uid', $account->id());
    }
    else {
      // TODO: extra message for testing only.
      $form_state->setErrorByName('name', t('External auth failed'));
    }
  }
}

function example_auth_get_account_data_if_valid($name, $password) {
  if (some_call_to_your_authentication($name, $password)) {
    $account_data = [
      'foo' => 'bar',
    ];
    return $account_data;
  }
  return FALSE;
}
sidik.permana’s picture

Sorry, I'm newbie in drupal, is there any documentation for using this module on Drupal 8?
I was installed it, but I don't know what must I do after it

Thank you

tepelena’s picture

Yeah, it will be nice to have some documentation or example on how to implement this module. Not everyone using Drupal is a programmer.

Jody Lynn’s picture

@tepelena This module is for programmers.

Ted Milker’s picture

@jody-lynn Thanks for the example, it really helped. Is there a way to assign roles with account_data?

chenx319’s picture

@Jody Lynn , I try your code , but I get the error at running the code as follow:
$externalauth = \Drupal::service('externalauth.externalauth');

in phpstorm debug Console:
PHP Fatal error: Trait 'Drupal\Core\DependencyInjection\DeprecatedServicePropertyTrait' not found in /xxxxxxxxxxx/drupal8site/web/modules/contrib/externalauth/src/ExternalAuth.php on line 23

can you give me any suggestion how to fix it ? Thanks a lot ?

My drupal version is 8.6.13
and the External Authentication is 8.x-1.2

the line 23 of ExternalAuth.php is: use DeprecatedServicePropertyTrait;

---------------------------------------------------------------------------------------------------------------------------------------

class ExternalAuth implements ExternalAuthInterface {

  use DeprecatedServicePropertyTrait;

  /**
   * {@inheritdoc}

it seems duplicate with https://www.drupal.org/project/externalauth/issues/3084602

chenx319’s picture

hello Everyone ,
can you kindly give me some explanation how the $account_data is used or stored ?

I used the code Ms. @Jody Lynn provide ,
but I can not find the where $account_data stored or used ?

$account_data = [
      'foo' => 'bar',
    ];

I assumed that stored in authmap table , I unserialize the column of "data", I just get "N"

I make a breakpoint in Authmap.save() , the $data is null

if i create a "foo" field in account setting , nothing happened.

data is null

.

svendecabooter’s picture

The $account_data variable gets used to pass in extra properties / field data to the Drupal user entity that will get created upon registration.
For example the user entity has a property 'timezone', so if your external authentication service would know which timezone applies to the user you are registering, you would add it to $account_data as follows:

$username = 'my_external_username';
$account_data = ['timezone' => 'Europe/Brussels'];
$account = \Drupal::service('externalauth.externalauth')->loginRegister($username, 'my_module', $account_data);
bwoods’s picture

I just wanted to say that @Jody Lynn's sample code was very helpful in getting started with external auth. The part that confused me with the example was that authmap isn't automatically populated, which makes sense, but with the code above alone, that will not allow external auth to work.

To test, I added a record in authmap for my test account, and the user was logged in. I am also using the simplesaml module for another login option, and there's a code snippet in the .module file that shows how to add the authmap entry.

Ted Milker’s picture

#16 @bwoods It does function if you're not attempting to map to existing Drupal accounts but just rely on externalauth to create new accounts when they don't exist yet in Drupal. If they are created by externalauth, they do properly map up the next time the user logs in. I never noticed the authmap is never used by that example, I guess I can get rid of it in my code since I only use externalauth-based logins.

Webbeh’s picture

Status: Active » Needs review

Per #11, this string would be awesome to place on the project page: https://www.drupal.org/docs/contributed-modules/external-authentication

For now, I've added that string to community documentation, and then added this threads' details into a Community Documentation page: https://www.drupal.org/docs/contributed-modules/external-authentication/...

Does this suffice for 'developer' documentation for folks to get started?

roderik’s picture

Agreed that this would be good for the project page. Now that the Community Docs page exists, did a little edit for "why (and partly, how) would you use this".

There are multiple ways to use this module; I myself have never used a form as in the example, but needed to redirect to an external authentication service and expose a Drupal route which the service can redirect the authenticated user back to. (That's how SAML works.)

IMHO the biggest blocker currently for me to extend the documentation more, is... the ExternalAuth service itself doesn't implement some things. Once it supports updating user data during login (as proposed by #2972782: Update account data on user login / #3179148: Redo authmap_alter / register events.), writing a generic example / help docs becomes easier. For now, I've seen basically every module which needs this, implement code by itself.

svendecabooter’s picture

svendecabooter’s picture

Status: Needs review » Fixed

Thanks for creating the documentation guide, based on the info in this issue.
I have added a link to the documentation guide on the project page, as well as an extra info block on the project page called "Target audience".

Thanks everyone who provided valuable documentation in this issue. I think I have credited all of you.
I will mark this issue as done, and have created a followup issue, since the documentation can still use improvements.
#3220336: Improve module documentation

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.