Le AccountManager d'Android semble récupérer le même jeton d'authentification mis en cache pour les applications avec différents UID - est-ce sécurisé? Il ne semble pas compatible avec OAuth2, car les jetons d'accès ne sont pas censés être partagés entre différents clients.
Je crée une application Android qui utilise OAuth2 pour l'authentification/l'autorisation de REST requêtes API à mon serveur, qui est un fournisseur OAuth2. Puisque l'application est la application "officielle" (par opposition à une application tierce), elle est considérée comme un client OAuth2 de confiance, donc j'utilise le flux de mots de passe du propriétaire de la ressource pour obtenir un jeton OAuth2: l'utilisateur (le propriétaire de la ressource) entre son nom d'utilisateur/mot de passe dans l'application, qui envoie ensuite son ID client et son secret client ainsi que les informations d'identification de l'utilisateur au point de terminaison du jeton OAuth2 de mon serveur en échange d'un jeton d'accès qui peut être utilisé pour effectuer des appels API, ainsi qu'un jeton de rafraîchissement de longue durée utilisé pour obtenir de nouveaux jetons d'accès à leur expiration. La raison en est qu'il est plus sûr de stocker le jeton d'actualisation sur l'appareil que le mot de passe de l'utilisateur.
J'utilise AccountManager pour gérer le compte et le jeton d'accès associé sur l'appareil. Puisque je fournis mon propre fournisseur OAuth2, j'ai créé mon propre type de compte personnalisé en étendant AbstractAccountAuthenticator et d'autres composants requis, comme expliqué dans ce Android Guide de développement et illustré dans l'exemple de projet SampleSyncAdapter. Je suis en mesure d'ajouter avec succès des comptes de mon type personnalisé à partir de mon application et de les gérer à partir de "Comptes et synchronisation" Android .
Cependant, je suis préoccupé par la façon dont le AccountManager met en cache et émet des jetons d'authentification - en particulier, que le même jeton d'authentification pour un type de compte et un type de jeton donnés semble être accessible par toute application à laquelle le l'utilisateur a accordé l'accès.
Pour obtenir un jeton d'authentification via le AccountManager, il faut invoquer AccountManager.getAuthToken () , en passant, entre autres, l'instance Account pour laquelle obtenir le jeton d'authentification et le authTokenType
souhaité. Si un jeton d'authentification existe pour le compte et l'authTokenType spécifiés, et si l'utilisateur accorde l'accès (via l'écran "Demande d'accès" ) à l'application qui a fait la demande de jeton d'authentification (dans les cas où l'UID de l'application demandeuse ne correspond pas à l'UID de l'authentificateur), puis le jeton est retourné. Au cas où mon explication manquerait, cette entrée de blog utile l'explique très clairement. Sur la base de ce message, et après avoir examiné la source de AccountManager et AccountManagerService (une classe interne qui fait le gros du travail pour AccountManager) pour moi-même, il semble que seulement 1 jeton d'authentification est stocké par combo authTokenType/compte.
Ainsi, il semble possible que si une application malveillante connaissait le type de compte et le ou les authTokenType utilisés par mon authentificateur, elle pourrait invoquer AccountManager.getAuthToken () pour obtenir l'accès au jeton OAuth2 stocké de mon application, en supposant que l'utilisateur accorde l'accès à l'application malveillante.
Pour moi, le problème est que l'implémentation de la mise en cache par défaut de AccountManager est basée sur un paradigme sur lequel, si nous superposions un contexte d'authentification/autorisation OAuth2, il considérerait le téléphone/périphérique comme un client OAuth2 unique pour un fournisseur de services/ressources. . Alors que le paradigme qui me semble logique est que chaque application/UID doit être considérée comme son propre client OAuth2. Lorsque mon fournisseur OAuth2 émet un jeton d'accès , il émet un jeton d'accès pour cette application particulière qui a envoyé l'ID client et le secret client correct, pas toutes les applications sur l'appareil. Par exemple, l'utilisateur peut avoir installé à la fois mon application officielle (appelez-la application client A) et une application tierce "sous licence" qui utilise mon API (appelez-la application client B). Pour le client officiel A, mon fournisseur OAuth2 peut émettre un jeton de type/portée "super" qui autorise l'accès aux éléments publics et privés de mon API, tandis que pour le client tiers B, mon fournisseur peut émettre un type "restreint"/portée jeton qui accorde uniquement l'accès aux appels d'API publics. Il ne devrait pas être possible pour le client d'application B d'obtenir le jeton d'accès du client d'application A, ce que l'implémentation actuelle de AccountManager/AccountManagerService semble autoriser. Pour, même si l'utilisateur accorde une autorisation au client B pour le super jeton du client A, le fait demeure que mon fournisseur OAuth2 avait uniquement l'intention d'accorder ce jeton au client A.
Suis-je en train d'oublier quelque chose ici? Est-ce que je pense que les jetons d'authentification doivent être émis sur une base par application/UID (chaque application étant un client distinct) rationnel/pratique, ou sont des jetons d'authentification par appareil (chaque appareil étant un client) le standard/accepté entraine toi?
Ou y a-t-il une faille dans ma compréhension du code/des restrictions de sécurité autour de AccountManager
/AccountManagerService
, de sorte que cette vulnérabilité n'existe pas réellement? J'ai testé le scénario Client A/Client B ci-dessus avec le AccountManager
et mon authentificateur personnalisé, et mon application cliente de test B, qui a une étendue de package et un UID différents, a pu obtenir le jeton d'authentification que mon que le serveur avait émis pour mon application cliente de test A en transmettant le même authTokenType
(au cours duquel j'ai été invité à accéder à l'écran d'autorisation "Demande d'accès", que j'ai approuvé car je suis un utilisateur et donc sans aucune idée). .
a. AuthTokenType "secret"
Pour obtenir le jeton d'authentification, le authTokenType
doit être connu; le authTokenType
doit-il être traité comme un type de secret client, de sorte qu'un jeton émis pour un type de jeton secret donné ne peut être obtenu que par les applications clientes "autorisées" qui connaissent le type de jeton secret? Cela ne semble pas très sûr; sur un périphérique enraciné, il serait possible d'examiner la colonne auth_token_type
de la table authtokens
dans la base de données accounts
du système et d'examiner les valeurs authTokenType qui sont stockées avec mes jetons. Ainsi, les types de jetons d'authentification "secrets" utilisés dans toutes les installations de mon application (et toutes les applications tierces autorisées utilisées sur l'appareil) auront été exposés dans un emplacement central. Au moins avec les identifiants/secrets des clients OAuth2, même s'ils doivent être fournis avec l'application, ils sont répartis entre différentes applications clientes, et une tentative peut être faite pour les obscurcir (ce qui est mieux que rien) pour aider à décourager ceux qui décompresser/décompiler l'application.
b. Jetons d'authentification personnalisés
Selon les documents pour AccountManager.KEY_CALLER_UID et AuthenticatorDescription.customTokens et le code source AccountManagerService
auquel j'ai fait référence précédemment, je devrais pouvoir pour spécifier que mon type de compte personnalisé utilise des "jetons personnalisés" et faire tourner ma propre implémentation de mise en cache/stockage de jetons dans mon authentificateur personnalisé, dans lequel je peux obtenir l'UID de l'application appelante afin de stocker/récupérer les jetons d'authentification par UID. En gros, j'aurais une table authtokens
comme l'implémentation par défaut, sauf qu'il y aurait une colonne uid
ajoutée afin que les jetons soient uniquement indexés sur U̲I̲D̲, a̲c̲c̲o̲u̲n̲t̲ et A̲u̲t̲h̲ ̲T̲o̲k̲e̲n̲ ̲T̲y̲p̲ juste a̲c̲c̲o̲u̲n̲t̲ et A̲u̲t̲h̲ ̲T̲o̲k̲e̲n̲ ̲T̲y̲p̲e̲). Cela semble être une solution plus sécurisée que l'utilisation d'authTokenTypes "secrets", car cela impliquerait d'utiliser le même authTokenTypes
dans toutes les installations de mon application/authentificateur, tandis que les UID varient d'un système à l'autre et ne peuvent pas être facilement usurpé. Mis à part le surcoût joyeux de pouvoir écrire et gérer mon propre mécanisme de mise en cache de jetons, quels sont les inconvénients de cette approche en termes de sécurité? Est-ce exagéré? Suis-je vraiment en train de protéger quoi que ce soit, ou manque-t-il quelque chose de telle que même avec une telle implémentation en place, il serait toujours assez facile pour un client d'application malveillant d'obtenir le jeton d'authentification d'un autre client d'application en utilisant les AccountManager
et authTokenType
(s) qui ne sont pas garantis comme secrets (en supposant que ladite application malveillante ne connaît pas le secret du client OAuth2 et ne peut donc pas obtenir directement un nouveau jeton, mais ne peut qu'espérer en obtenir un qui a déjà été mis en cache dans le AccountManager
au nom du client d'application autorisé)?
c. Envoyer l'ID client/secret avec le jeton OAuth2
Je pourrais m'en tenir à l'implémentation de stockage de jetons par défaut de AccountManagerService
et accepter la possibilité d'un accès non autorisé au jeton d'authentification de mon application, mais je pourrais forcer les demandes d'API à toujours inclure l'ID et le client OAuth2 secret, en plus du jeton d'accès, et vérifiez côté serveur que l'application est le client autorisé pour lequel le jeton a été émis en premier lieu. Cependant, je voudrais éviter cela car A) AFAIK, la spécification OAuth2 ne nécessite pas d'authentification client pour les demandes de ressources protégées - seul le jeton d'accès est requis , et B) Je voudrais éviter les frais supplémentaires liés à l'authentification du client à chaque demande.
Ce n'est pas possible dans le cas général (tout ce que le serveur reçoit est une série de messages dans un protocole - le code qui a généré ces messages ne peut pas être déterminé). -- Michael
Mais la même chose pourrait être dite de l'authentification initiale du client dans le flux OAuth2 au cours de laquelle le client reçoit pour la première fois le jeton d'accès. La seule différence est qu'au lieu de s'authentifier uniquement sur la demande de jeton, les demandes de ressources protégées seraient également authentifiées de la même manière. (Notez que l'application cliente pourrait transmettre ses c̲l̲i̲e̲n̲t̲ ̲i̲d̲ et c̲l̲i̲e̲n̲t̲ ̲s̲e̲c̲r̲e̲t̲ via le paramètre loginOptions
de AccountManager.getAuthToken()
, que mon authentificateur personnalisé passerait simplement à mon fournisseur de ressources, selon le Protocole OAuth2).
Si cela est possible, est-ce un problème de sécurité valide/pratique dans un contexte OAuth2?
Vous ne pouvez jamais compter sur un jeton d'authentification donné à un utilisateur qui reste secret de cet utilisateur ... il est donc raisonnable pour Android d'ignorer cette sécurité par objectif d'obscurité dans sa conception -- Michael
[~ # ~] mais [~ # ~] - Je ne crains pas que l'utilisateur (le propriétaire de la ressource) obtienne le jeton d'authentification sans mon consentement ; Je suis préoccupé par les clients non autorisés (applications). Si l'utilisateur veut être un attaquant de ses propres ressources protégées, il peut alors se mettre KO. Je dis qu'il ne devrait pas être possible qu'un utilisateur installe mon application cliente et, sans le savoir, une application cliente "imposteur" qui est capable d'accéder au jeton d'authentification de mon application simplement parce qu'elle a transmis le bon authTokenType et que l'utilisateur était trop paresseux/ignorant/précipité pour examiner l'écran de demande d'accès. Cette analogie peut être un peu trop simplifiée, mais je ne considère pas que "la sécurité par l'obscurité" que mon application Facebook installée ne puisse pas lire les e-mails mis en cache par mon application Gmail, ce qui est différent de moi (l'utilisateur) enracinant mon téléphone et en examinant le cache contenu moi-même.
L'utilisateur devait accepter une demande d'accès (système Android fourni) pour que l'application utilise votre token ... Étant donné que la solution Android semble correcte) - les applications ne peuvent pas utiliser en silence l'authentification d'un utilisateur sans demander -- Michael
[~ # ~] mais [~ # ~] - C'est aussi un problème de autorisation - le jeton d'authentification émis pour mon client "officiel" est la clé d'un ensemble de ressources protégées pour lesquelles ce client et seulement ce client est autorisé. Je suppose que l'on pourrait faire valoir que puisque l'utilisateur est le propriétaire de ces ressources protégées, s'il accepte la demande d'accès d'un client tiers (que ce soit une application partenaire "facturée" ou un phishing), il autorise effectivement le tiers- client tiers qui a fait la demande d'accès à ces ressources. Mais j'ai des problèmes avec ceci:
Mais l'utilisateur peut explicitement autoriser les applications à réutiliser une authentification précédente auprès d'un service, ce qui est pratique pour l'utilisateur .-- Michael
[~ # ~] mais [~ # ~] - Je ne pense pas que le retour sur investissement dans la commodité justifie le risque de sécurité. Dans les cas où le mot de passe de l'utilisateur est stocké dans le compte de l'utilisateur, alors vraiment, la seule commodité achetée pour l'utilisateur est qu'au lieu d'envoyer une demande Web à mon service pour obtenir un nouveau jeton distinct qui est réellement autorisé pour le client demandeur, un jeton mis en cache localement qui n'est pas autorisé pour le client est renvoyé. Ainsi, l'utilisateur gagne la légère commodité de voir une boîte de dialogue de progression "Connexion ..." pendant quelques secondes de moins, au risque que l'utilisateur soit fortement gêné par le vol/l'utilisation abusive de ses ressources.
Gardant à l'esprit que je m'engage à A) utiliser le protocole OAuth2 pour sécuriser mes demandes d'API, B) fournir ma propre ressource OAuth2/fournisseur d'authentification (par opposition à l'authentification avec disons, Google ou Facebook), et C) en utilisant AccountManager d'Android pour gérer mon type de compte personnalisé et ses jetons, est-ce que l'une de mes solutions proposées est valide? Laquelle a le plus de sens? Suis-je en train de négliger l'un des avantages/inconvénients? Existe-t-il des alternatives intéressantes auxquelles je n'ai pas pensé?
[Utiliser] Clients alternatifs Ne pas avoir d'API secrète qui tente d'être accessible uniquement à un client officiel; les gens vont contourner cela. Assurez-vous que toutes vos API publiques sont sécurisées quel que soit le (futur) client que l'utilisateur utilise -- Michael
[~ # ~] mais [~ # ~] - Cela ne va-t-il pas à l'encontre de l'un des principaux objectifs de l'utilisation d'OAuth2 en premier lieu? À quoi sert l'autorisation si tous les titulaires potentiels sont autorisés à utiliser le même périmètre de ressources protégées?
Quelqu'un d'autre a-t-il senti que c'était un problème, et comment avez-vous travaillé autour de ce problème? J'ai fait de nombreuses recherches sur Google pour essayer de trouver si d'autres se sont sentis il s'agit d'un problème/préoccupation de sécurité, mais il semble que la plupart des publications/questions impliquant le AccountManager d'Android et les jetons d'authentification concernent la façon de s'authentifier avec un compte Google, et non avec un type de compte personnalisé et un fournisseur OAuth2. De plus, je n'ai trouvé personne qui se préoccupait de la possibilité que le même jeton d'authentification soit utilisé par différentes applications, ce qui me fait me demander si c'est effectivement une possibilité/digne de préoccupation en premier lieu (voir mes 2 premières questions clés " énumérés ci-dessus).
J'apprécie votre contribution/vos conseils!
Michael's Answer - Je pense que les principales difficultés que j'ai avec votre réponse sont:
Je suis toujours enclin à penser que les applications sont des clients séparés et distincts d'un service, par opposition à l'utilisateur/téléphone/appareil lui-même étant un "gros" client, et donc un jeton qui a été autorisé pour une application ne devrait pas, par par défaut, être transférable à celui qui ne l'a pas fait. Il semble que vous laissiez entendre qu'il est inutile de considérer chaque application comme un client distinct en raison de la possibilité que,
l'utilisateur pourrait exécuter un téléphone rooté et lire le jeton, accéder à votre API privée ... [ou] si le système de l'utilisateur était compromis (l'attaquant pourrait lire le jeton dans ce cas)
et que par conséquent, dans le grand schéma des choses, nous devrions considérer l'appareil comme un client du service, car nous ne pouvons pas garantir la sécurité entre les applications sur l'appareil lui-même. Il est vrai que si le système lui-même a été compromis, il ne peut y avoir aucune garantie d'authentification/autorisation des demandes envoyées de cet appareil à un service. Mais la même chose pourrait être dite, par exemple, TLS; la sécurité des transports n'est pas pertinente si les points d'extrémité eux-mêmes ne peuvent pas être sécurisés. Et pour la grande majorité des appareils Android, qui ne sont pas compromis, je pense qu'il est plus sûr de considérer chaque client d'application comme un point de terminaison distinct, au lieu de les regrouper tous en un en partageant les mêmes jeton d'authentification.
Pour le Client A officiel, mon fournisseur OAuth2 peut émettre un jeton de type/portée "super" qui accorde l'accès aux éléments publics et privés de mon API
Dans le cas général, vous ne pourriez jamais vous fier à un jeton d'authentification donné à un utilisateur restant secret de cet utilisateur. Par exemple, l'utilisateur peut exécuter un téléphone rooté et lire le jeton, en accédant à votre API privée. Idem si le système de l'utilisateur était compromis (l'attaquant pourrait lire le token dans ce cas).
Autrement dit, il n'y a rien de tel qu'une API "privée" qui est en même temps accessible à tout utilisateur authentifié, il est donc raisonnable pour Android d'ignorer cette sécurité par objectif d'obscurité dans sa conception) .
une application malveillante ... pourrait obtenir l'accès au jeton OAuth2 stocké de mon application
Dans le cas d'une application malveillante, il semble plus raisonnable qu'une application malveillante ne puisse pas utiliser le jeton du client, car nous nous attendons à ce que le système d'autorisation d'Android assure l'isolement des applications malveillantes (à condition que l'utilisateur ait lu/se soit soucié des autorisations qu'il a accepté lors de l’installation). Cependant, comme vous le dites, l'utilisateur doit accepter une demande d'accès (système Android fourni) pour que l'application utilise votre jeton.
Compte tenu de cela, la solution Android semble OK - les applications ne peuvent pas utiliser l'authentification d'un utilisateur en silence sans demander, mais l'utilisateur peut explicitement autoriser les applications à réutiliser une authentification précédente auprès d'un service, ce qui est pratique pour l'utilisateur.
"Secret" authTokenType ... ne semble pas très sécurisé
D'accord - c'est juste une autre couche de sécurité à travers l'obscurité; il semble que n'importe quelle application souhaitant partager votre authentification aurait dû chercher ce qu'était authTokenType de toute façon, donc l'adoption de cette approche rend juste un peu plus gênant pour ce développeur d'applications hypothétique.
Envoyer l'ID client/secret avec le jeton OAuth2 ... [pour] vérifier côté serveur que l'application est le client autorisé
Ce n'est pas possible dans le cas général (tout ce que le serveur reçoit est une série de messages dans un protocole - le code qui a généré ces messages ne peut pas être déterminé). Dans ce cas spécifique, il pourrait protéger contre la menace plus limitée d'un client alternatif (non root)/application malveillante - je ne connais pas suffisamment le AccountManager pour commenter (idem pour vos solutions de jetons d'authentification personnalisés).
Vous avez décrit deux menaces: les applications malveillantes qu'un utilisateur ne veut pas avoir accès à son compte et les clients alternatifs que vous (le développeur) ne voulez pas utiliser certaines parties de l'API.
Applications malveillantes: tenez compte de la sensibilité du service que vous fournissez et s'il n'est pas plus sensible que par exemple Comptes Google/Twitter, il suffit de s'appuyer sur les protections d'Android (autorisations d'installation, écran de demande d'accès). Si elle est plus sensible, demandez-vous si votre contrainte d'utiliser AccountManager d'Android est appropriée. Pour protéger fortement l'utilisateur contre une utilisation malveillante de son compte, essayez l'authentification à deux facteurs pour les actions dangereuses (par exemple, ajouter les détails du compte d'un nouveau destinataire dans les services bancaires en ligne).
Clients alternatifs: ne disposent pas d'une API secrète qui tente d'être uniquement accessible à un client officiel; les gens vont contourner cela. Assurez-vous que toutes vos API publiques sont sécurisées quel que soit le (futur) client que l'utilisateur utilise.
Votre observation est correcte. Authenticator s'exécutera avec le même UID que l'application d'installation. Lorsqu'une autre application se connecte au gestionnaire de compte et obtient un jeton pour cet authentificateur, elle se lie à votre service d'authentification fourni. Il fonctionnera comme votre UID, donc les nouveaux comptes seront liés à cet authentificateur. Lorsque l'application appelle getAuthToken, la liaison se produit et Authenticator s'exécute toujours dans le même UId. Les autorisations intégrées par défaut vérifient l'UID du compte, de sorte que différents authentificateurs ne puissent pas accéder à un autre compte à partir d'authentificateurs différents.
Vous pouvez résoudre ce problème en utilisant "Calling UID" pour addAccount et GetAuthToken, car le service de gestionnaire de compte ajoute cela à l'ensemble. Votre implémentation d'authentificateur peut vérifier cela.
@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
String authTokenType, Bundle loginOptions) throws NetworkErrorException {
Log.v(
TAG,
"getAuthToken() for accountType:" + authTokenType + " package:"
+ mContext.getPackageName() + "running pid:" + Binder.getCallingPid()
+ " running uid:" + Binder.getCallingUid() + " caller uid:"
+ loginOptions.getInt(AccountManager.KEY_CALLER_UID));
...
}
Je suggère de suivre le flux d'autorisation au lieu de stocker le secret client dans votre application native, car d'autres développeurs peuvent extraire ce secret. Votre application n'est pas une application Web et ne doit pas avoir de secrets.
Lorsque vous ajoutez un compte, vous pouvez également interroger l'ID appelant. Vous devez setUserData à votre addAccount activité liée qui s'exécutera comme UID de votre application, afin qu'elle puisse appeler setUserData.
getUserData et setUserData utilise une base de données sqllite intégrée, vous n'avez donc pas besoin de créer de cache par vous-même. Vous pouvez uniquement stocker le type de chaîne, mais vous pouvez analyser json et stocker des informations supplémentaires par compte.
Lorsque différentes applications tierces interrogent un compte et appellent getAuthtoken avec votre compte, vous pouvez vérifier l'UID dans les données utilisateur du compte. Si l'appel de l'UID n'est pas répertorié, vous pouvez effectuer l'invite et/ou d'autres choses pour obtenir l'autorisation. Si cela est autorisé, vous pouvez ajouter un nouvel UID au compte.
Partage de jetons entre les applications: Chaque application est normalement enregistrée avec un identifiant client différent et ne doit pas partager de jeton. Le jeton est destiné à une application client.
Stockage: AccountManager ne crypte pas vos données. Si vous avez besoin d'une solution plus sécurisée, vous devez crypter les jetons puis les stocker.
Je suis confronté au même problème d'architecture pour une application.
La solution que j'ai obtenue consiste à associer/hacher le jeton oauth, avec le jeton du fournisseur de l'application (par exemple, le jeton que Facebook donne à une application) et à l'ID de l'appareil (Android_id
). Ainsi, seule l'application est autorisée, car l'appareil peut utiliser le jeton du gestionnaire de compte.
Bien sûr, ce n'est qu'une nouvelle couche de sécurité, mais aucune preuve de balle.
Je pense que @Michael a parfaitement répondu à la question; cependant, pour rendre la réponse plus sensible et plus courte à ceux qui recherchent une réponse rapide, j'écris ceci.
Votre préoccupation concernant la sécurité de Android AccountManager
est correcte, mais c'est ce que OAuth est censé être, sur lequel Android AccountManager
s'appuie.
En d'autres termes, si vous recherchez un mécanisme d'authentification très sécurisé, ce ne serait pas une bonne option pour vous. Vous ne devez pas compter sur des jetons mis en cache pour l'authentification, car ils peuvent être facilement révélés à l'intrus en cas de vulnérabilité de sécurité sur l'appareil de l'utilisateur, comme l'octroi par inadvertance d'une autorisation d'accès à l'intrus, l'exécution d'un appareil enraciné, etc.
La meilleure alternative à OAuth dans les systèmes d'authentification plus sécurisés, par exemple les applications bancaires en ligne, est d'utiliser un cryptage asymétrique à l'aide de clés publiques et privées, dans lequel l'utilisateur doit saisir son mot de passe à chaque fois pour utiliser le Le mot de passe est ensuite chiffré à l'aide de la clé publique de l'appareil et envoyé au serveur. Ici, même si l'intrus est connu du mot de passe chiffré, il ne peut rien faire avec cela car il ne peut pas le déchiffrer avec cette clé publique et a besoin seule la clé privée du serveur.
Quoi qu'il en soit, si l'on veut utiliser le système AccountManager
du Android ainsi que maintenir un haut niveau de sécurité, il serait possible de ne pas enregistrer de jetons sur l'appareil La méthode getAuthToken
de AbstractAccountAuthenticator
peut alors être remplacée comme ceci:
@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String
authTokenType, Bundle options) throws NetworkErrorException {
AuthenticatorManager authenticatorManager = AuthenticatorManager.authenticatorManager;
Bundle result;
AccountManager accountManager = AccountManager.get(context);
// case 1: access token is available
result = authenticatorManager.getAccessTokenFromCache(account, authTokenType,
accountManager);
if (result != null) {
return result;
}
final String refreshToken = accountManager.getPassword(account);
// case 2: access token is not available but refresh token is
if (refreshToken != null) {
result = authenticatorManager.makeResultBundle(account, refreshToken, null);
return result;
}
// case 3: neither tokens is available but the account exists
if (isAccountAvailable(account, accountManager)) {
result = authenticatorManager.makeResultBundle(account, null, null);
return result;
}
// case 4: account does not exist
return new Bundle();
}
Dans cette méthode, ni le cas 1, ni le cas 2 ni le cas 4 ne sont vrais car il n'y a pas de jeton enregistré, même si le account
est là. Par conséquent, seul le cas 3 sera renvoyé, qui peut ensuite être défini dans le rappel approprié pour ouvrir un Activity
dans lequel l'utilisateur entre le nom d'utilisateur et le mot de passe pour l'authentification.
Je ne suis pas sûr d'être sur la bonne voie en décrivant davantage cela ici, mais mon site Web publie sur AccountManager
peut aider au cas où.