Créer un type de compte personnalisé

Jusqu'à présent, nous avons parlé de l'accès aux API Google, qui utilisent des comptes et des utilisateurs définis par Google. Si vous avez votre propre service en ligne, il n'aura pas de comptes ni d'utilisateurs Google. Que faites-vous ? Il s'avère relativement simple d'installer de nouveaux types de comptes sur l'appareil d'un utilisateur. Cette leçon explique comment créer un type de compte personnalisé qui fonctionne de la même manière que les comptes intégrés.

Implémenter votre code de compte personnalisé

Vous aurez d'abord besoin d'un moyen d'obtenir les identifiants de l'utilisateur. Il peut s'agir d'une simple boîte de dialogue vous demandant un nom et un mot de passe. Il peut aussi s'agir d'une procédure plus exotique, telle qu'un mot de passe à usage unique ou un scan biométrique. Dans tous les cas, il est de votre responsabilité d'implémenter le code qui:

  1. Collecte les identifiants de l'utilisateur
  2. Authentifie les identifiants auprès du serveur
  3. Stocke les identifiants sur l'appareil

En général, ces trois exigences peuvent être gérées par une seule activité. Nous l'appellerons l'activité de l'authentificateur.

Étant donné qu'elles doivent interagir avec le système AccountManager, les activités d'authentification présentent certaines exigences que les activités normales n'ont pas à respecter. Pour faciliter les choses, le framework Android fournit une classe de base, AccountAuthenticatorActivity, que vous pouvez étendre pour créer votre propre authentificateur personnalisé.

C'est à vous de décider comment répondre aux deux premières exigences d'une activité d'authentification, à savoir la collecte des identifiants et l'authentification. S'il n'y avait qu'une seule façon de procéder, il ne serait pas nécessaire d'avoir un type de compte "personnalisé" après tout. La troisième exigence a une implémentation canonique, plutôt simple:

Kotlin

Account(username, your_account_type).also { account ->
    accountManager.addAccountExplicitly(account, password, null)
}

Java

final Account account = new Account(username, your_account_type);
accountManager.addAccountExplicitly(account, password, null);

Faites attention à la sécurité !

Il est important de comprendre que AccountManager n'est pas un service de chiffrement ni un trousseau. Il stocke les identifiants du compte exactement comme vous les transmettez, en texte brut. Sur la plupart des appareils, ce n'est pas un problème particulier, car cela les stocke dans une base de données accessible uniquement en mode root. Toutefois, sur un appareil en mode root, les identifiants seraient lisibles par toute personne disposant d'un accès adb à l'appareil.

En gardant cela à l'esprit, vous ne devez pas transmettre le mot de passe réel de l'utilisateur à AccountManager.addAccountExplicitly(). À la place, vous devez stocker un jeton sécurisé de manière cryptographique dont l'utilisation serait limitée pour un pirate informatique. Si vos identifiants utilisateur protègent quelque chose de précieux, vous devez soigneusement envisager d'effectuer une action similaire.

N'oubliez pas : en ce qui concerne le code de sécurité, respectez la règle "Hausse des mythes". N'essayez pas ceci chez vous ! Consultez un professionnel de la sécurité avant d'implémenter un code de compte personnalisé.

Maintenant que les clauses de non-responsabilité de sécurité sont supprimées, il est temps de reprendre le travail. Vous avez déjà implémenté l'élément élémentaire de votre code de compte personnalisé. Il ne vous reste plus qu'à mettre en œuvre la plomberie.

Étendre AbstractAccountAuthenticator

Pour que AccountManager fonctionne avec votre code de compte personnalisé, vous avez besoin d'une classe qui implémente les interfaces attendues par AccountManager. Il s'agit de la classe authenticator.

Le moyen le plus simple de créer une classe d'authentificateur consiste à étendre AbstractAccountAuthenticator et à implémenter ses méthodes abstraites. Si vous avez suivi les leçons précédentes, les méthodes abstraites de AbstractAccountAuthenticator devraient vous sembler familières: il s'agit du côté opposé des méthodes que vous avez appelées dans la leçon précédente pour obtenir des informations sur le compte et des jetons d'autorisation.

L'implémentation correcte d'une classe d'authentification nécessite un certain nombre d'éléments de code distincts. Tout d'abord, AbstractAccountAuthenticator comporte sept méthodes abstraites que vous devez remplacer. Ensuite, vous devez ajouter un filtre d'intent pour "android.accounts.AccountAuthenticator" au fichier manifeste de votre application (comme indiqué dans la section suivante). Enfin, vous devez fournir deux ressources XML qui définissent, entre autres, le nom de votre type de compte personnalisé et l'icône que le système affichera à côté des comptes de ce type.

Vous trouverez un guide par étapes pour implémenter une classe d'authentificateur réussie et les fichiers XML dans la documentation AbstractAccountAuthenticator.

Si votre activité d'authentification nécessite des paramètres d'initialisation spéciaux, vous pouvez les associer à l'intent à l'aide de Intent.putExtra().

Créer un service d'authentification

Maintenant que vous disposez d'une classe Authenticator, il vous faut un lieu de résidence. Les authentificateurs de compte doivent être disponibles pour plusieurs applications et fonctionner en arrière-plan. Ils doivent donc naturellement s'exécuter dans un Service. Nous l'appellerons le service d'authentification.

Votre service d'authentification peut être très simple. Il suffit de créer une instance de votre classe d'authentification dans onCreate() et d'appeler getIBinder() dans onBind().

N'oubliez pas d'ajouter une balise <service> à votre fichier manifeste, d'ajouter un filtre d'intent pour l'intent AccountAuthenticator et de déclarer l'authentificateur de compte:

<service ...>
   <intent-filter>
      <action android:name="android.accounts.AccountAuthenticator" />
   </intent-filter>
   <meta-data android:name="android.accounts.AccountAuthenticator"
             android:resource="@xml/authenticator" />
</service>

Distribuer votre service

Vous avez terminé ! Le système reconnaît désormais votre type de compte, juste à côté de tous les types de comptes connus tels que "Google" et "Entreprise". Vous pouvez utiliser la page des paramètres Comptes et synchronisation pour ajouter un compte. Les applications qui demandent des comptes de votre type personnalisé pourront énumérer et s'authentifier comme avec n'importe quel autre type de compte.

Bien entendu, tout cela suppose que le service de votre compte est bien installé sur l'appareil. Si une seule application accède au service, ce n'est pas un problème. Il vous suffit de regrouper le service dans l'application. Toutefois, si vous voulez que le service de votre compte soit utilisé par plusieurs applications, les choses se compliquent. Vous ne souhaitez pas regrouper le service avec toutes vos applications et que plusieurs copies de celui-ci occupent de l'espace sur l'appareil de l'utilisateur.

Une solution consiste à placer le service dans un petit fichier APK spécifique à l'usage. Lorsqu'une application souhaite utiliser votre type de compte personnalisé, elle peut vérifier l'appareil pour voir si votre service de compte personnalisé est disponible. Sinon, il peut rediriger l'utilisateur vers Google Play pour télécharger le service. Cela peut sembler problématique au début, mais plutôt que de saisir à nouveau les identifiants pour chaque application qui utilise votre compte personnalisé, il est facile d'actualiser la page.