J'ai développé une application qui supportera de nombreux utilisateurs. Le problème est que je ne peux pas comprendre comment authentifier le client / utilisateur.
Je crée une application comme http://quickblox.com/ où je donnerai des informations d'identification à mes utilisateurs et ils les utiliseront pour créer N applications dans lesquelles ils ne pourront pas mettre leur nom d'utilisateur et leur mot de passe pour s'authentifier.
Supposons que cela se passe comme suit. (Tout comme QuickBlox)
1. L'utilisateur crée un compte sur mon site Web.
2. L'utilisateur peut créer N clés API et sécréter des informations d'identification. (Pour plusieurs applications)
3. L'utilisateur utilisera ces informations d'identification dans ses applications (Android, iOS, Javascript, etc.) pour parler avec mes API REST.
(Les API REST ont un accès en lecture et en écriture.)
Ma préoccupation?
Les utilisateurs mettront leurs informations d'identification (clé API et clé secrète) dans les applications qu'ils créent, que se passe-t-il si quelqu'un obtient ces clés et essaie d'imiter l'utilisateur? (En décompilant l'APK ou en consultant directement le code JavaScript.
Ai-je tort quelque part?
Je suis confus pour concevoir ce mécanisme utilisateur à trois niveaux.
Réponses:
Je conçois des API REST depuis quelques années. Vous vous inquiétez trop. Récemment, un autre utilisateur de ce forum a posé une question, où il craignait de stocker les points de terminaison URI dans son code côté client JavaScript .
Les mêmes règles s'appliquent à vous que celles applicables au développeur JavaScript. Si vous autorisez des personnes de l'extérieur à intégrer votre API, votre API a la même visibilité qu'un site Web normal et vous devez la traiter de la même manière.
Citation de la réponse originale:
Vous devez concevoir vos jetons d'accès à l'application pour n'autoriser que les opérations que vous souhaitez autoriser. Vous pouvez avoir deux types de jetons d'accès:
Mais qu'est-ce que quelqu'un déconstruit le code source, prend les jetons de l'application, découvre quels sont les points de terminaison publics et abuse de votre service Web?
À moins que vous ne gériez directement le développement des applications consommant votre API, rien n'interdit vraiment aux gens d'abuser de votre API de la même manière directement depuis l'application.
la source
filtered data
(B) de son utilisateur . Est-il maintenant possible, ou existe-t-il une solution de contournement pour empêcher un troisième utilisateur de voler toutes les données (A + B) de mon utilisateur . Est-ce que ça fait du sens?Votre problème n'est pas tant technique que commercial.
Disons que vous disposez de votre API, que vous vendez à vos clients (les développeurs d'applications) pour un montant forfaitaire de 100 £ par an, un accès illimité.
Eh bien, évidemment, je peux acheter votre service à 100 £ et le revendre à 10 personnes à 50 $ chacune. Tu ne veux pas ça! vous essayez donc de penser à une restriction qui vous permettra de vendre votre API sans qu'elle soit ouverte à l'arbitrage.
Si vous limitez simplement le nombre d'applications, un client peut créer une seule application qui accepte les connexions d'autres applications et les transmet.
Si vous limitez les utilisateurs, encore une fois, le client peut masquer les utilisateurs derrière sa propre authentification et apparaître comme un seul utilisateur.
Ce que vous devez faire, c'est transmettre le coût de chaque appel API à votre client. c'est-à-dire facturer par appel API ou définir un quota d'appels par an.
Cela pousse le même problème d'arbitrage sur vos clients. Cela les oblige à mettre en place des mesures pour empêcher leurs utilisateurs de voler leurs clés. Dans ce cas, cachez votre API derrière leur propre API authentifiée par l'utilisateur.
la source
Les autres réponses semblent toutes suggérer que le problème du stockage d'un secret dans une application sur des appareils grand public n'est pas résoluble.
Bien sûr que ça l'est.
Deux principes (les détails de mise en œuvre suivront):
Étant donné que, si le client fait une demande au point de terminaison d'authentification avec des informations d'identification, et que le serveur l'authentifie, le serveur peut générer un jeton temporaire dynamique (temporaire signifiant temporellement). Ce jeton doit être mémorisé dans le client et envoyé avec les demandes suivantes.
Vous aurez besoin d'un mécanisme pour «actualiser» périodiquement le jeton, c'est-à-dire en obtenir un nouveau. Créez simplement un point de terminaison REST qui permet de générer un nouveau jeton à partir d'un point existant, pour éviter d'avoir à vous authentifier à nouveau à partir des informations d'identification.
Si vous essayez d'éviter que l'utilisateur final ne s'authentifie de nouveau, cette authentification peut être une configuration initiale unique dans l'application lors de son installation.
Cette solution évite simplement la nécessité de stocker un jeton statique incorporé dans le binaire de l'application. Un jeton est généré à la volée par le serveur uniquement en réponse à une authentification réussie. Pour qu'un utilisateur malveillant inspecte votre application et essaie d'obtenir un accès API non autorisé, il devra toujours s'authentifier comme tout le monde.
la source
Si vous avez des clés uniques par application, vous ne pouvez les utiliser que lors d'une authentification de connexion initiale, lancée par le client, après quoi vous passez à un jeton d'authentification unique par application mobile.
Votre serveur modifie (roule) le jeton de chaque application cliente de temps à autre (périodiquement, plus / moins un certain délai aléatoire flou / aléatoire, par exemple). Le jeton roulant n'est connu qu'entre le serveur et le client authentifié.
Les nouveaux jetons sont retournés piggy-back sur les réponses régulières. Chaque fois que la réponse contient un nouveau jeton, l'application réceptrice doit passer à son utilisation dans les demandes suivantes.
Chaque fois que l'échange avec un client se désynchronise (une erreur de protocole quelconque), votre serveur demandera une ré-authentification (par le biais d'une réponse d'erreur à la prochaine demande du client, ou s'appuiera sur la réponse valide à la demande du client, pour exemple).
L'authentification initiale initiée par les clients alors qu'un jeton roulant est activement utilisé doit être considérée avec suspicion - cela pourrait très bien être une tentative de mimétisme. Je ne l'autoriserais que si l'échange devient inactif pendant un intervalle plus long que prévu, ce qui pourrait, par exemple, être causé par une panne / redémarrage du client avec une nouvelle instance qui n'a pas le jeton roulant.
Il serait encore mieux de conserver le jeton du côté client de sorte qu'un client redémarré puisse continuer d'où son prédécesseur est parti - en réduisant considérablement l'ouverture pour l'imitation.
Un tel schéma rendrait l'imitation au moins assez difficile - le client imitant devrait prévoir exactement la fenêtre lorsque le client autorisé arrêterait d'envoyer des demandes suffisamment longtemps pour que le serveur décide qu'il est acceptable d'accepter une nouvelle authentification client avec la clé prescrite. De telles demandes en dehors de la fenêtre autorisée peuvent être utilisées comme détection de tentatives de mimétisme et éventuellement initier certaines contre-mesures (liste noire IP, etc.).
la source
D'après ce que je sais, ce que vous avez mentionné est la seule façon de procéder. L'application stockant la clé est certainement un risque, mais il existe différentes manières de le contourner. Vous pouvez toujours utiliser le magasin de clés pour stocker la clé, que le codage en dur, forçant ainsi une connexion unique.
En outre, vous devez envisager de lier une clé à un client.Par conséquent, si quelqu'un imite, vous devez disposer d'une couche de sécurité pour vérifier le client, la clé et les agents utilisateurs pour bloquer immédiatement la demande. Ayez un cas d'utilisation pour ré-émettre ou vous assurer que les clés ne sont pas imitées.
la source
Si vous comptez donner à vos clients des jetons d'autorisation pour mettre leurs applications, il sera toujours théoriquement possible pour quelqu'un de procéder à une rétro-ingénierie de l'application et de les extraire. Pour éviter cela, vous auriez besoin d'un mécanisme qui ne nécessiterait pas de secret dans l'application cliente. C'est délicat. Je peux cependant vous suggérer quelques options.
Vous avez un problème une fois que vous avez donné les informations d'identification, vous n'avez aucun contrôle sur la sécurité de leur stockage. De plus, si vous demandez à l'utilisateur de vous envoyer les informations d'identification, quelqu'un peut MITM votre connexion et voler les jetons directement sans se soucier de l'ingénierie inverse de l'application.
Une façon de rendre plus difficile l'extraction de votre jeton d'autorisation est de le masquer. Cela soulève simplement la barre, mais ne le rend pas impossible, et pour ce faire, vous devrez garder le contrôle du secret. Vous pouvez implémenter une bibliothèque contenant les informations secrètes et spécifique à chaque client. Vous pouvez utiliser la bibliothèque pour communiquer avec vos serveurs et vous n'aurez peut-être même pas à dire à votre utilisateur les informations secrètes, elles pourraient simplement être intégrées dans la bibliothèque. Cela ne résout pas le problème de l'ingénierie inverse de votre bibliothèque, mais cela vous permet de contrôler le niveau d'obscurcissement. Un inconvénient est qu'une fois qu'une personne a brisé l'obscurcissement dans la bibliothèque, elle peut attaquer n'importe quelle bibliothèque, à moins que vous n'écriviez du code qui rend chaque bibliothèque significativement différente. Cela introduit son propre ensemble de problèmes.
Cela peut s'écarter légèrement de la portée de votre question, mais cela est lié à la sécurité de votre jeton, je vais donc le mentionner. Pour éviter le vol trivial du jeton sur le câble, vous ne souhaiterez probablement pas envoyer le jeton directement, mais vous pourriez signer le trafic à l'aide d'une fonction HMAC. Vous pouvez vérifier la validité du message en calculant le HMAC du message sur le serveur et en le comparant au HMAC envoyé par le client. Vous utiliseriez le jeton comme clé de la fonction HMAC afin que seule une personne connaissant le jeton puisse signer le trafic. C'est mieux pour la sécurité de votre token car vous ne l'envoyez jamais directement au serveur, il ne peut donc pas être intercepté et volé directement. Pour plus d' informations sur HMAC voir cette question: /security/20129/how-and-when-do-i-use-hmac/20301
Aucune solution de sécurité ne sera imprenable, vous devez décider combien cela vous coûtera à mettre en œuvre par rapport à la probabilité et au coût d'être compromis.
la source
Vous citer:
Maintenant, c'est un peu une contradiction, n'est-ce pas? ;)
Comme d'autres l'ont dit, vous ne pouvez pas. Si une application utilise une clé API, on peut la décompiler comme vous le dites pour obtenir la ou les clés et l'utiliser également.
En plus d'exiger une authentification utilisateur appropriée supplémentaire, vous ne pouvez que limiter les dommages:
la source