Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Multi authentication: Difference between revisions

From MoodleDocs
(Initial version)
 
 
(15 intermediate revisions by 6 users not shown)
Line 1: Line 1:
Before starting to code anything about Multi Authentication support in Moodle, I would like to share what I have in mind, so others can see the flaws and everybody can spot the problems with this approach.
== Proposal ==
{{Moodle 2.4}}
To implement an oauth2 authentication plugin, Moodle needs to log the user in even though the user auth method is set to "manual". I think Moodle should support multiple auth methods for one Moodle account.
 
=== new 'mdl_user_auth_methods' ===
 
{| class="wikitable"
! id !! component !!  class="unsortable" |userid !!  class="unsortable" | provideruserid
|-
|  1 || auth_manual || 2 || null
|-
|  1 || auth_oauth2google || 2 || 85134984
|}
 
Note: we still keep the auth field in 'mdl_user' table as primary auth method.
 
=== Use case: login with a second auth method during login ===
* Case 1: Moodle finds that the second auth method can be linked to the account (example with Google oauth2: the user email address sent by Google matches a Moodle account. This email address is marked as verified.).
* Case 2: Moodle doesn't find a linkable account. Moodle suggest the user to create a new user.
 
=== Use case: link a second auth method from the edit profile page ===
The user is logged in. In the edit profile page, the user connects with the second auth method and is redirect to the same edit profile page. No attempt to re-log the user in. Moodle just adds a record to mdl_user_auth_methods.
 
=== Administration ===
* add checkbox to allow to remove an authentication method. If the plugin is set to true, then if the authentication method is not the primary auth method, the user can remove it from the edit profile.
 
== Old proposal: Some random notes about multi-auth in Moodle ==
{{Moodle 1.8}}Before starting to code anything about Multi Authentication support in Moodle, I would like to share what I have in mind, so others can see the flaws and everybody can spot the problems with this approach.


There are some big questions (see below) I don't know the answer for, so if others with more knowledge of Moodle internals (specially authentication internals) than me could answer them, that would be great.
There are some big questions (see below) I don't know the answer for, so if others with more knowledge of Moodle internals (specially authentication internals) than me could answer them, that would be great.


== Some random notes about multi-auth in Moodle ==
=== NOTE ===
Following text does not describe current auth implementation in 1.8!
[[User:Skodak|Skodak]]


=== Goals ===
=== Goals ===


* Multiple simultaneous sources for authentication
* Multiple simultaneous sources for authentication
* Multiples sources of the same type (LDAP, database, etc)
* Multiples authentication instances (instances for short) of the same source type (LDAP, database, etc)
* Each source has its own configuration
* Each instance has its own configuration
* The order in which we try the sources is configurable
* The order in which we try the instances is configurable


=== How it works ===
=== How it works ===


* Each source has at least the auth_user_login function (like now).
* Each source (and thus each instance) has at least the auth_user_login function, like now. (this may change to class function user_login() once Jonathan Harker and Martin Langhoff work in multi-authentication is merged).
* This function can return one of the following values:
* This function can return one of the following values:
** AUTH_OK: the user and the password are valid
** AUTH_OK: the user and the password are valid
Line 20: Line 49:
** AUTH_DENIED: This user cannot login, even if the username and password are valid
** AUTH_DENIED: This user cannot login, even if the username and password are valid
** AUTH_ERROR: The source found and error during user and password validation and can't say wether they are valid or not.
** AUTH_ERROR: The source found and error during user and password validation and can't say wether they are valid or not.
* We try each source in the configured order.
* We try each instance in the configured order.
* For each order, we call auth_user_login with the user credentials and test the result.  
* For each instance, we call auth_user_login() (or user_login()) with the user credentials, and test the result.  
** if the result is AUTH_DENIED, we break out of the loop and deny the user login.
** if the result is AUTH_DENIED, we break out of the loop and deny the user login.
** if the result is AUTH_OK, we break out of the loop and allow the user login.
** if the result is AUTH_OK, we break out of the loop and allow the user login.
** in any other case, we continue the loop.
** in any other case, we continue the loop.
* If we finish the loop, we deny the user login (all the sources returned either AUTH_DECLINED or AUTH_ERROR, so we can't let the user log in).
* If we finish the loop, we deny the user login (all the instances returned either AUTH_DECLINED or AUTH_ERROR, so we can't let the user log in).


=== The (proposed) database tables ===
=== The (proposed) database tables ===


(MySQL syntax, Postgresql gurus please adjust definition ;-)
(MySQL syntax, Postgresql syntax omitted for shortness)


==== auth_type ====  
==== auth_type ====  
Line 36: Line 65:
       `id` integer(10) NOT NULL auto_increment,
       `id` integer(10) NOT NULL auto_increment,
       `name` varchar(20) NOT NULL default '',  
       `name` varchar(20) NOT NULL default '',  
       `multiple` tinyint(1) NOT NULL default '0',
       `isinternal` tinyint(1) NOT NULL default '0',
       `interactive` tinyint(1) NOT NULL default '0',
       `multiple` tinyint(1) NOT NULL default '1',
       `candisable` tinyint(1) NOT NULL default '0',
       `candisable` tinyint(1) NOT NULL default '0',
       `removable` tinyint(1) NOT NULL default '0',
       `removable` tinyint(1) NOT NULL default '0',
Line 45: Line 74:
</pre>
</pre>


This table stores the different authentication types present in this
This table stores the different authentication types (sources) present in this
Moodle installation: internal, none, ldap, db, cas, etc.
Moodle installation: internal, none, ldap, db, cas, etc.


Line 52: Line 81:


* 'id': the primary key of the record.
* 'id': the primary key of the record.
* 'name': The name of the autentication type: 'internal', 'none', 'ldap', 'db', etc. There can't be duplicated values in this field.
* 'name': The name of the autentication type: 'manual', 'none', 'ldap', 'db', etc. There can't be duplicated values in this field.
* 'isinternal' if this auth type is internal to Moodle (1) or not(0), i.e., if it doesn't depend on any external entity to provide authentication. Tipically this is for 'manual', 'email' and 'none'.
* 'multiple': if this auth type supports multiple instances (1) or not (0).
* 'multiple': if this auth type supports multiple instances (1) or not (0).
* 'interactive': if this auth type is interactive (1) or not (0).
* 'candisable': if this auth type can be temporarily disabled (1) or not (0)
* 'candisable': if this auth type can be temporarily disabled (1) or not (0)
* 'removable': if this auth type can be removed from the system (1) or not (0).
* 'removable': if this auth type can be removed from the system (1) or not (0).


If we decide that 'internal', 'none' and/or 'email' are special
If we decide that 'manual', 'none' and/or 'email' are special
authentication types and are handled separately form the rest, then
authentication types and are handled separately form the rest, then
this last field can be removed.
this last field can be removed.


'''BIG QUESTION HERE''': Can 'internal' be disabled? I'm not sure
'''BIG QUESTION HERE''': Can 'manual' be disabled? I'm not sure
about this, as all the admin users can be locked out of Moodle if we
about this, as all the admin users can be locked out of Moodle if we
mistakenly disable all the auth types needed for admin users.
mistakenly disable all the auth types needed for admin users.


'''BIG QUESTION HERE''': Should 'internal' auth type be handled
'''BIG QUESTION HERE''': Should 'manual' auth type be handled
separately from all this multi-auth mess? I guess there are some
separately from all this multi-auth mess? I guess there are some
benefits to it, but I'm not sure about it. For one, it would make the
benefits to it, but I'm not sure about it. For one, it would make the
Line 78: Line 107:
       `name` varchar(20) NOT NULL default '',  
       `name` varchar(20) NOT NULL default '',  
       `description` varchar(50) NOT NULL default '',  
       `description` varchar(50) NOT NULL default '',  
       `sortorder` integer(10) NOT NULL default '0'
       `sortorder` integer(10) NOT NULL default '0',
      `enabled` tinyint(1) NOT NULL default '1',
       PRIMARY_KEY(`id`),
       PRIMARY_KEY(`id`),
       UNIQUE KEY(`name`)       
       UNIQUE KEY(`name`)       
Line 87: Line 117:
type. It's managed from the authentication setup page, using
type. It's managed from the authentication setup page, using
the add/modify/delete functionality available there. We can also
the add/modify/delete functionality available there. We can also
specify the order in which we want to user each auth-instance when
specify the order in which we want to use each auth-instance when
authenticating users.
authenticating users.


Line 97: Line 127:
* 'description': a short description text for this instance (e.g., 'UK Students LDAP server').
* 'description': a short description text for this instance (e.g., 'UK Students LDAP server').
* 'sortorder': the order in which we use each auth instance when trying to authenticate users.
* 'sortorder': the order in which we use each auth instance when trying to authenticate users.
* 'enabled': if this instance is enabled (1) or not (0).


'''BIG QUESTION HERE''': If we use 'id' to fill in the 'auth' field in
'''BIG QUESTION HERE''': If we use 'id' to fill in the 'auth' field in
Line 106: Line 137:
LDAP server, but now "is" in our US staff database server). Is this
LDAP server, but now "is" in our US staff database server). Is this
good or bad?
good or bad?
'''ANSWER TO BIG QUESTION''': After talking with Martin Langhoff at MoodleMoot Spain '06, this is clearly a Bad(tm) thing. If we allow users to "float" between authentication instances, things like auth_ldap_sync_users.php could break havoc, deleting users it doesn't know about in this auth_instance (but perfectly valid in other auth_instance's). So storing the auth_instance 'id' in prefix_user and using it accordingly is The Right Thing(tm).


==== auth_instance_settings ====
==== auth_instance_settings ====
Line 133: Line 166:


# If we store the 'prefix_auth_intance.id' value in the 'prefix_user.auth' field as suggested above, what should we do when we '''remove''' that auth instance from our system? Should we allow removal if any users are using that instance? Should we move those users to the default auth instance (internal)? Should we choose a new auth instance for those users as part of the removal? Or should we just ignore the 'prefix_user.auth' field during login and just proceed through the whole loop and try to find which new auth instance allows the user to login (if any)?
# If we store the 'prefix_auth_intance.id' value in the 'prefix_user.auth' field as suggested above, what should we do when we '''remove''' that auth instance from our system? Should we allow removal if any users are using that instance? Should we move those users to the default auth instance (internal)? Should we choose a new auth instance for those users as part of the removal? Or should we just ignore the 'prefix_user.auth' field during login and just proceed through the whole loop and try to find which new auth instance allows the user to login (if any)?
# Multiple instances login: If we use multiple Moodle instances, from my point it means that a user can have access to several instances. So  it will be a good idea to think about a kind of Moodle portal that shows all the instances a user can access.
#:: I hadn't thought about this when posting the original questions, because I was thinking about one Moodle site and multiple authentication sources (our problem at the moment), but with [[Community_hub|Moodle Network]] around the corner, this is a real issue. Well thought out Hélène :-) -- [[User:Iñaki Arenaza|Iñaki Arenaza]] 07:56, 22 November 2006 (CST)
# Others?
# Others?

Latest revision as of 06:20, 10 August 2012

Proposal

Moodle 2.4

To implement an oauth2 authentication plugin, Moodle needs to log the user in even though the user auth method is set to "manual". I think Moodle should support multiple auth methods for one Moodle account.

new 'mdl_user_auth_methods'

id component userid provideruserid
1 auth_manual 2 null
1 auth_oauth2google 2 85134984

Note: we still keep the auth field in 'mdl_user' table as primary auth method.

Use case: login with a second auth method during login

  • Case 1: Moodle finds that the second auth method can be linked to the account (example with Google oauth2: the user email address sent by Google matches a Moodle account. This email address is marked as verified.).
  • Case 2: Moodle doesn't find a linkable account. Moodle suggest the user to create a new user.

Use case: link a second auth method from the edit profile page

The user is logged in. In the edit profile page, the user connects with the second auth method and is redirect to the same edit profile page. No attempt to re-log the user in. Moodle just adds a record to mdl_user_auth_methods.

Administration

  • add checkbox to allow to remove an authentication method. If the plugin is set to true, then if the authentication method is not the primary auth method, the user can remove it from the edit profile.

Old proposal: Some random notes about multi-auth in Moodle

Moodle1.8 Before starting to code anything about Multi Authentication support in Moodle, I would like to share what I have in mind, so others can see the flaws and everybody can spot the problems with this approach.

There are some big questions (see below) I don't know the answer for, so if others with more knowledge of Moodle internals (specially authentication internals) than me could answer them, that would be great.

NOTE

Following text does not describe current auth implementation in 1.8! Petr Škoda (škoďák)

Goals

  • Multiple simultaneous sources for authentication
  • Multiples authentication instances (instances for short) of the same source type (LDAP, database, etc)
  • Each instance has its own configuration
  • The order in which we try the instances is configurable

How it works

  • Each source (and thus each instance) has at least the auth_user_login function, like now. (this may change to class function user_login() once Jonathan Harker and Martin Langhoff work in multi-authentication is merged).
  • This function can return one of the following values:
    • AUTH_OK: the user and the password are valid
    • AUTH_DECLINED: The user or the password are not correct or unknown to this source
    • AUTH_DENIED: This user cannot login, even if the username and password are valid
    • AUTH_ERROR: The source found and error during user and password validation and can't say wether they are valid or not.
  • We try each instance in the configured order.
  • For each instance, we call auth_user_login() (or user_login()) with the user credentials, and test the result.
    • if the result is AUTH_DENIED, we break out of the loop and deny the user login.
    • if the result is AUTH_OK, we break out of the loop and allow the user login.
    • in any other case, we continue the loop.
  • If we finish the loop, we deny the user login (all the instances returned either AUTH_DECLINED or AUTH_ERROR, so we can't let the user log in).

The (proposed) database tables

(MySQL syntax, Postgresql syntax omitted for shortness)

auth_type

  CREATE TABLE `prefix_auth_type` (
       `id` integer(10) NOT NULL auto_increment,
       `name` varchar(20) NOT NULL default '', 
       `isinternal` tinyint(1) NOT NULL default '0',
       `multiple` tinyint(1) NOT NULL default '1',
       `candisable` tinyint(1) NOT NULL default '0',
       `removable` tinyint(1) NOT NULL default '0',
       PRIMARY_KEY(`id`),
       UNIQUE KEY(`name`)
  )

This table stores the different authentication types (sources) present in this Moodle installation: internal, none, ldap, db, cas, etc.

Each auth type has to autoregister in this table when it's installed, specifying:

  • 'id': the primary key of the record.
  • 'name': The name of the autentication type: 'manual', 'none', 'ldap', 'db', etc. There can't be duplicated values in this field.
  • 'isinternal' if this auth type is internal to Moodle (1) or not(0), i.e., if it doesn't depend on any external entity to provide authentication. Tipically this is for 'manual', 'email' and 'none'.
  • 'multiple': if this auth type supports multiple instances (1) or not (0).
  • 'candisable': if this auth type can be temporarily disabled (1) or not (0)
  • 'removable': if this auth type can be removed from the system (1) or not (0).

If we decide that 'manual', 'none' and/or 'email' are special authentication types and are handled separately form the rest, then this last field can be removed.

BIG QUESTION HERE: Can 'manual' be disabled? I'm not sure about this, as all the admin users can be locked out of Moodle if we mistakenly disable all the auth types needed for admin users.

BIG QUESTION HERE: Should 'manual' auth type be handled separately from all this multi-auth mess? I guess there are some benefits to it, but I'm not sure about it. For one, it would make the above question irrelevant.

auth_instance

  CREATE TABLE `prefix_auth_instance` (
       `id` integer(10) NOT NULL auto_increment,
       `typeid` integer(10) NOT NULL default '0', 
       `name` varchar(20) NOT NULL default '', 
       `description` varchar(50) NOT NULL default '', 
       `sortorder` integer(10) NOT NULL default '0',
       `enabled` tinyint(1) NOT NULL default '1',
       PRIMARY_KEY(`id`),
       UNIQUE KEY(`name`)       
  )

This table stores the different auth instances available for each auth type. It's managed from the authentication setup page, using the add/modify/delete functionality available there. We can also specify the order in which we want to use each auth-instance when authenticating users.

The meaning of the fields are:

  • 'id': the primary key of the record. We will put this value into the 'auth' field in prefix_user table when we correctly authenticate a user using this auth instance (to later track where to update values from, where to check for password expiration, etc.)
  • 'typeid': the auth type id of this instance. It's a foreign key into the 'type' field of auth_type table. We need this to check if there is already an instance of a given auth type, in case that auth type doesn't allow for multiple instances.
  • 'name': the name of this instance. It's the text shown in the authentication setup page to refer to this instance.
  • 'description': a short description text for this instance (e.g., 'UK Students LDAP server').
  • 'sortorder': the order in which we use each auth instance when trying to authenticate users.
  • 'enabled': if this instance is enabled (1) or not (0).

BIG QUESTION HERE: If we use 'id' to fill in the 'auth' field in prefix_user, then we should only use 'sortorder' when the user has that field empty (i.e., we don't know where to authenticate this user so far). Otherwise we could directly authenticate with the known auth-instance. But this prevents users from "moving" between authentication instances (i.e, this user "was" in our UK student's LDAP server, but now "is" in our US staff database server). Is this good or bad?

ANSWER TO BIG QUESTION: After talking with Martin Langhoff at MoodleMoot Spain '06, this is clearly a Bad(tm) thing. If we allow users to "float" between authentication instances, things like auth_ldap_sync_users.php could break havoc, deleting users it doesn't know about in this auth_instance (but perfectly valid in other auth_instance's). So storing the auth_instance 'id' in prefix_user and using it accordingly is The Right Thing(tm).

auth_instance_settings

  CREATE TABLE `prefix_auth_instance_settings` (
       `id` integer(10) NOT NULL auto_increment,
       `instanceid` integer(10) NOT NULL default '0', 
       `name` varchar(255) NOT NULL default '', 
       `value` text NOT NULL
       PRIMARY_KEY(`id`),
       UNIQUE KEY `instancesetting` (`instanceid`,`name`)
  )

This table stores each auth instance configuration settings.

  • 'id': the primary key for the record.
  • 'instanceid': foreign key into the 'id' field of auth_instance table.
  • 'name': name of the setting.
  • 'value': value for that setting.

There can't be two (or more) identical 'name' values for the same 'instanceid'.

The questions

Some additional questions before starting to code all this mess

  1. If we store the 'prefix_auth_intance.id' value in the 'prefix_user.auth' field as suggested above, what should we do when we remove that auth instance from our system? Should we allow removal if any users are using that instance? Should we move those users to the default auth instance (internal)? Should we choose a new auth instance for those users as part of the removal? Or should we just ignore the 'prefix_user.auth' field during login and just proceed through the whole loop and try to find which new auth instance allows the user to login (if any)?
  2. Multiple instances login: If we use multiple Moodle instances, from my point it means that a user can have access to several instances. So it will be a good idea to think about a kind of Moodle portal that shows all the instances a user can access.
    I hadn't thought about this when posting the original questions, because I was thinking about one Moodle site and multiple authentication sources (our problem at the moment), but with Moodle Network around the corner, this is a real issue. Well thought out Hélène :-) -- Iñaki Arenaza 07:56, 22 November 2006 (CST)
  3. Others?