17.9.7 Créer son propre Provider
Un Provider doit hériter de, et implémenter les méthodes définies dans, la
classe WHAT/Class.Provider.php
.
Les méthodes à implémenter obligatoirement sont :
- abstract function validateCredential($username, $password)
Les méthodes optionnelles sont :
- public function validateAuthorization($opt)
- public function __construct($authProviderName, $parms)
- public function initializeUser($username)
17.9.7.1 Méthodes
17.9.7.1.1 validateCredential()
Cette méthode prend en entrée deux arguments qui sont :
-
$username
: le login entré par l'utilisateur ; -
$password
: le mot de passe entré par l'utilisateur.
La méthode doit retourner :
-
true
si le couple login/mot de passe est correct ; -
false
si le couple login/mot de passe est incorrect.
17.9.7.1.2 validateAuthorization()
Une fois le couple login/password validé, cette méthode permet de contrôler si l'utilisateur est autorisé à se connecter.
Cette méthode est optionnelle, et peut ne pas être fournit par le Provider s'il n'a pas de contrôles d'autorisation supplémentaires à faire.
Cette méthode prend entrée un argument :
-
$opt
: une structure contenant le nom de l'utilisateur.$opt = array( 'username' => $username, 'dcp_account' => $Account );
'username'
: le login de l'utilisateur authentifié.-
'dcp_account
' : l'objet Account de l'utilisateur authentifié.
La méthode retourne :
-
true
si l'utilisateur est autorisé à se connecter ; -
false
dans le cas contraire.
17.9.7.1.3 __construct()
C'est le constructeur du Provider que l'on peut étendre si celui-ci nécessite une initialisation particulière.
Cette méthode prend en entrée deux arguments qui sont :
-
$authProviderName
: le nom du provider ; -
$parms
: un array contenant les paramètres du provider.
17.9.7.1.4 initializeUser()
Si le compte de l'utilisateur n'existe pas dans dynacase, cette méthode est utilisée pour créer le compte de l'utilisateur dans dynacase.
Cette méthode prend en entrée le login de l'utilisateur :
-
$username
: le login de l'utilisateur.
La méthode retourne :
-
""
: une chaîne vide s'il n'y a pas eu d'erreur à la création du compte. -
"Error message …"
: une chaîne non vide contenant le message d'erreur rencontré.
Cette méthode spécifique implémente la recherche des informations de l'utilisateur à partir du login sur le système d'authentification utilisé, et la création du compte utilisateur dynacase avec les informations obtenus.
17.9.7.2 Exemple
Dans l'exemple ci-dessous, nous allons écrire un Provider pour valider les mots
de passe des utilisateurs auprès d'un service PAM à l'aide de
la commande checkpassword-pam
Ce module ne supportera pas la création d'utilisateurs à la volée.
17.9.7.2.1 Fichier config/local-dbaccess.php
On va déclarer dans le fichier config/local-dbaccess.php
que l'on utilise en
premier notre Provider pam
, et ensuite le Provider freedom
si l'utilisateur
n'est pas reconnu par le Provider pam
.
Notre Provider pam
aura un paramètre nommé service
qui contiendra le nom du
service PAM auprès duquel seront validés les logins et mots de passe (c'est le
nom du fichier situé dans /etc/pam.d
).
<?php $freedom_authprovider = 'pam,freedom'; $freedom_providers['pam'] = array( 'service' => 'dynacasepam' );
17.9.7.2.2 Fichier WHAT/providers/Class.pamProvider.php
Notre Provider est donc décrit dans le fichier Class.pamProvider.php
situé
dans le sous-répertoire WHAT/providers
de l'installation dynacase.
Celui-ci fournit une classe pamProvider
qui étend la classe Provider
, et
nous allons décrire nos méthodes spécifiques validateCredential()
et
validateAuthorization()
.
Dans validateCredential()
nous allons récupérer le paramètre service
de
notre provider, et utiliser la commande checkpassword-pam
pour valider le
username et le password reçu.
Pour simplifier l'exemple, la méthode validateAuthorization()
retournera
true
systématiquement (elle pourrait aussi ne pas être implémentée, ce qui
donnerait le même résultat).
<?php include_once('WHAT/Class.Provider.php'); Class pamProvider extends Provider { public function validateCredential($username, $password) { $service = 'freedom'; if( array_key_exists('service', $this->parms) ) { $service = $this->parms['service']; } return $this->checkpassword_pam($username, $password, $service); } public function validateAuthorization($opt) { $username = $opt['username']; return true; } public function checkpassword_pam($username, $password, $service) { $cmd = sprintf("checkpassword-pam --service %s --no-chdir-home --noenv", escapeshellarg($service)); $proc = proc_open($cmd, array(3=>array('pipe', 'r')), $pipes); if( ! is_resource($proc) ) { error_log(__CLASS__."::".__FUNCTION__." ".sprintf("Error running checkpassword-pam")); return false; } fwrite($pipes[3], sprintf("%s\0%s\0timestamp\0", $username, $password )); fclose($pipes[3]); $ret = proc_close($proc); if( $ret === 0 ) { return true; } error_log(__CLASS__."::".__FUNCTION__." ". sprintf("Authentication failed for user '%s' and service '%s'.", $username, $service ) ); return false; } }
17.9.7.2.3 Fichier /etc/pam.d/dynacase
Pour finir, le fichier associé au paramètre service
de notre Provider. Celui-
ci contiendra les règles que l'on souhaite voir appliqué pour la validation des
comptes. Dans cet exemple, on utilisera une authentification des comptes sur la
base locale des utilisateurs Unix du serveur.
auth sufficient pam_unix.so auth required pam_deny.so account required pam_permit.so session required pam_permit.so