Authentification externe

Dotclear 2 stocke par défaut les utilisateurs et leurs mots de passe dans sa propre base de données. Le processus d'authentification passe donc tout naturellement par là. Ceci dit, il peut être utile d'accéder à une autre source de données pour procéder à l'authentification. Nous allons voir que Dotclear 2 le permet assez facilement.

Préambule

Dotclear 2 permet de spécifier dans sa configuration une constante définissant le nom de la classe qui sera utilisée pour le processus d'authentification.

Il suffit de définir la constante DC_AUTH_CLASS et lui donner le nom d'une classe que vous aurez créée.

Une nouvelle classe d'authentification

Au même niveau que notre fichier de configuration, nous allons créer un fichier nommé class.auth.php qui contiendra tout simplement le code suivant :

class myDcAuth extends dcAuth
{
}

Enfin, dans le fichier de configuration de Dotclear, nous ajoutons ces lignes à la fin :

$__autoload['myDcAuth'] = dirname(__FILE__).'/class.auth.php';
define('DC_AUTH_CLASS','myDcAuth');

À ce stade, notre installation de Dotclear doit continuer à fonctionner. Pour l'instant nous avons simplement changé la classe d'authentification et comme notre nouvelle classe ne fait rien, rien n'a changé.

Important :

La classe d'authentification doit impérativement hériter de dcAuth pour être utilisée.

Scénario

Dans le cadre de ces explications, nous allons partir du principe que nous disposons d'un service web XML-RPC qui permet de vérifier la validité d'un identifiant et de son mot de passe et d'obtenir des informations sur l'utilisateur.

Voici les spécifications de notre service Web d'authentification fictif.

L'URL du service est http://example.com/auth et il possède une seule méthode auth.login.

Cette méthode prend deux paramètres : une chaîne login pour l'identifiant de l'utilisateur et une chaîne password pour le mot de passe. Elle renvoie un tableau contenant les informations sur l'utilisateur ou provoque une erreur XML-RPC en cas d'erreur d'identifiant et/ou de mot de passe.

Enfin, nous allons partir du principe que notre installation ne contient qu'un seul blog dont l'identifiant est default.

Application

Dans le cadre de notre service d'authentification, nous devons nous intéresser à la méthode checkUser de dcAuth puisque c'est là que tout se passe. Cette méthode est appelée de différente manière par Dotclear.

Elle peut être appelée avec uniquement l'identifiant de l'utilisateur. Ceci permet d'initialiser les informations dans la classe.

Elle peut être appelée avec l'identifiant et un mot de passe. Ceci permet de vérifier le mot de passe en plus d'initialiser l'utilisateur.

Enfin, elle peut être appelée avec un identifiant, un mot de passe de valeur null et une clé de vérification. Ceci permet de valider la session de l'utilisateur et de l'initialiser à l'aide d'une clé.

Voici comment nous allons procéder :

  • Si la méthode checkUser est appelée sans mot de passe, nous passons la main à la méthode parente.
  • Si la méthode checkUser est appelée avec un mot de passe, nous vérifions la validité de celui-ci puis créons ou mettons à jour l'utilisateur dans la base de données et enfin, passons la main à la méthode parent sans mot de passe.

On notera que l'utilisateur doit exister dans la base de données pour des raisons d'intégrité référentielle. En effet, il est nécessaire de pouvoir associer des billets (entre autre) à tel ou tel utilisateur.

Il est également nécessaire de stocker le mot de passe de l'utilisateur dans la base de données de Dotclear car certaines opérations en ont besoin. Ceci étant, il est possible d'interdire le changement de mot de passe par l'utilisateur.

Voici donc maintenant le code commenté de notre nouvelle classe d'authentification :

class myDcAuth extends dcAuth
{
	# L'utilisateur n'a pas le droit de changer son mot de passe
	protected $allow_pass_change = false;
 
	# La méthode de vérification du mot de passe
	public function checkUser($user_id, $pwd=null, $user_key=null)
	{
		# Pas de mot de passe, on appelle la méthode parente.
		if ($pwd == '') {
			return parent::checkUser($user_id,null,$user_key);
		}
 
		# Si un mot de passe a été donné, nous allons le vérifier avec la
		# méthode auth.login XML-RPC.
		try
		{
			# On démarre une transaction et on ouvre un curseur sur la
			# table utilisateur de Dotclear pour créer ou modifier
			# l'utilisateur.
			$this->con->begin();
			$cur = $this->con->openCursor($this->user_table);
 
			# On appelle la méthode de vérification du mot de passe.
			# En cas d'erreur le processus s'arrête là et provoque
			# une exception.
			$client = new xmlrpcClient('http://example.com/auth');
			$info = $client->query('auth.login',$user_id,$pwd);
 
			# On définit le mot de passe, il est inséré dans tous les cas.
			$cur->user_pwd = $pwd;
 
			# Si l'utilisateur existe, nous allons uniquement mettre à jour
			# son mot de passe dans la table utilisateur de Dotclear.
			if ($this->core->userExists($user_id))
			{
				$this->sudo(array($this->core,'updUser'),$user_id,$cur);
				$this->con->commit();
			}
 
			# Si l'utilisateur n'existe pas, nous allons le créer.
			# Afin qu'il puisse se connecter, il est nécessaire de lui donner
			# au moins une permission "usage" sur le blog "default".
			else
			{
				$cur->user_id = $info['login'];
				$cur->user_email = $info['email'];
				$cur->user_name = $info['name'];
				$cur->user_firstname = $info['firstname'];
				$cur->user_lang = $info['lang'] ? $info['lang'] : 'en';
				$cur->user_tz = 'Europe/Paris';
				$cur->user_default_blog = 'default';
 
				$this->sudo(array($this->core,'addUser'),$cur);
				$this->sudo(array($this->core,'setUserBlogPermissions'),
					$user_id,'default',array('usage'=>true));
				$this->con->commit();
			}
 
			# Les opérations précédentes se sont déroulées sans erreur, nous
			# pouvons maintenant appeler la méthode parente afin d'initialiser
			# l'utilisateur dans l'object $core->auth
			return parent::checkUser($user_id,$pwd);
		}
		catch (Exception $e)
		{
			# En cas d'erreur on annule la transaction et on renvoie "false"
			$this->con->rollback();
			return false;
		}
	}
}

Note :

On notera l'utilisation de la propriété allow_pass_change qui permet d'interdire le changement de mot de passe par l'utilisateur.

Comme on peut le voir, le processus est assez simple à mettre en place. Quelques remarques maintenant.

  • Il est indispensable de stocker le mot de passe de l'utilisateur dans la table utilisateur de Dotclear car celui-ci peut en avoir besoin pour certaines opérations
  • Il est bien sûr possible de donner des paramètres à ce code, comme par exemple, le blog et les permissions qui seront assignés à l'utilisateur s'il n'existe pas encore.
  • Vous pouvez créer des méthodes afterAddUser, afterUpdUser et afterDelUser dans votre classe d'authentification. Ces méthodes sont appelées respectivement après la création, la mise à jour ou la suppression d'un utilisateur.

Cet exemple simple d'authentification montre ce qu'il est possible de faire. Vous pouvez ainsi authentifier un utilisateur depuis n'importe quelle source telle qu'un serveur LDAP, la table utilisateur d'un forum, ou n'importe quoi acceptant un identifiant et un mot de passe.

Enfin, la class dcAuth permet de réaliser une véritable authentification unique de type SSO par ces fonctions de vérification de session et de changement du formulaire d'authentification.

Wiki powered by Dokuwiki.