Création d'une API pour les applications mobiles-authentification et autorisation

vue d'ensemble

je cherche à créer une API (REST) pour mon application. Le but initial/principal sera la consommation par les applications mobiles (iPhone, Android, Symbian, etc). J'ai étudié différents mécanismes d'authentification et d'autorisation pour les API basées sur le web (en étudiant d'autres implémentations). J'ai réfléchi à la plupart des concepts fondamentaux, mais je suis toujours à la recherche de conseils dans certains domaines. La dernière chose que je veux faire est de réinventez la roue, mais je ne trouve pas de solutions standard qui correspondent à mes critères (cependant, mes critères sont mal orientés, alors n'hésitez pas à critiquer cela aussi). De plus, je veux que l'API soit la même pour toutes les plates-formes/applications qui la consomment.

oAuth

je vais aller de l'avant et rejeter mon objection à oAuth puisque je sais que ce sera probablement la première solution offerte. Pour les applications mobiles( ou plus spécifiquement Non web applications), il semble tout simplement mauvais pour quitter l'application (pour aller à un navigateur web) pour l'authentification. En outre, il n'y a aucun moyen (je suis au courant de) pour le navigateur de retourner le rappel à l'application (en particulier cross-plate-forme). Je connais quelques applications qui font ça, mais ça me semble mal et ça donne une pause dans l'application UX.

exigences

  1. L'utilisateur entre le nom d'utilisateur/mot de passe dans l'application.
  2. chaque API l'appel est identifié par la demande d'appel.
  3. Overhead est maintenu à un minimum et l'aspect auth est intuitif pour les développeurs.
  4. le mécanisme est sécurisé à la fois pour l'utilisateur final (leurs identifiants de connexion ne sont pas exposés) et pour le développeur (leurs identifiants d'application ne sont pas exposés).
  5. si possible, ne pas exiger https (en aucun cas une exigence dure).

Mes Pensées Actuelles sur la mise en œuvre

un développeur externe demandera un compte API. Ils recevront un apikey et un apisecret. Chaque demande nécessite au minimum trois paramètres.

  • apikey - développeur à regisration
  • timestamp-double comme Identificateur unique pour chaque message pour une clé API donnée
  • de hachage hachage de l'horodatage + le apisecret

l'apikey est nécessaire pour identifier la demande qui émet la demande. Le timestamp agit de la même façon que le oauth_nonce et évite/atténue les attaques de replay. Le hachage garantit que la demande a été effectivement délivrée par le propriétaire de l'apikey donné.

pour les requêtes authentifiées (celles qui sont faites au nom d'un utilisateur), Je ne sais toujours pas si j'utilise une route access_token ou un combo de hachage nom d'utilisateur et mot de passe. De toute façon, à un moment donné un nom d'utilisateur / mot de passe combo sera nécessaire. Ainsi, lorsqu'il le fait, un hachage de plusieurs informations (apikey, apisecret, timestamp) + le mot de passe serait utilisé. j'aimerais avoir des commentaires sur cet aspect. POUR INFO, il faudrait d'abord hachez le mot de passe, puisque je ne stocke pas les mots de passe dans mon système sans hachage.

Conclusion

FYI, ce n'est pas une requête pour savoir comment construire/structurer l'API en général seulement comment gérer l'authentification et l'autorisation de l'intérieur d'une seule demande.

Aléatoire Réflexions/Questions Prime

pour les API qui n'ont besoin que d'un apikey dans le cadre de la requête, comment empêcher quelqu'un d'autre que le propriétaire de l'apikey de voir l'apikey (depuis envoyé dans le clear) et de faire des requêtes excessives pour les pousser au-delà des limites d'utilisation? Peut-être que je ne pense plus à ça, mais ne devrait-il pas y avoir quelque chose pour authentifier qu'une demande a été vérifiée à la propriétaire apikey? Dans mon cas, c'était le but de l'apisecret, il n'est jamais montré/transmis sans être hachée.

en parlant de hashes, qu'en est-il de md5 vs hmac-sha1? Est-il vraiment important lorsque toutes les valeurs sont hachés avec suffisamment de temps les données (ie. apisecret)?

j'avais déjà envisagé d'ajouter un sel par utilisateur/ligne à mon hachage de mot de passe utilisateurs. Si je devais faire, comment pourrait-il être en mesure de créer une correspondance de hachage sans connaître le sel utilisé?

183
demandé sur jsuggs 2010-10-19 02:21:42

5 réponses

la façon dont je pense faire la partie login de ceci dans mes projets est:

  1. avant de se connecter, l'utilisateur demande un login_token à partir du serveur. Ceux-ci sont générés et stockés sur le serveur sur demande, et ont probablement une durée de vie limitée.

  2. pour se connecter l'application calcule le hachage du mot de passe de l'utilisateur, puis le hachage du mot de passe avec le login_token pour obtenir une valeur, ILS puis retourner à la fois le login_token et le hachage combiné.

  3. le serveur vérifie que login_token est celui qu'il a généré, le retirant de sa liste de login_token valides. Le serveur combine alors son hachage stocké du mot de passe de l'utilisateur avec le login_token et s'assure qu'il correspond au token combiné soumis. S'il correspond, Vous avez authentifié votre utilisateur.

les avantages de ceci sont que vous ne stockez jamais le mot de passe de l'utilisateur sur le serveur, le mot de passe n'est jamais passé dans le clear, le hachage de mot de passe est seulement passé dans le clear sur la création de compte (bien qu'il puisse y avoir des moyens de contourner cela), et il devrait être à l'abri des attaques de replay que le login_token est retiré de la base de données sur l'utilisation.

42
répondu Michael Anderson 2015-10-11 12:03:47

C'est tout un tas de questions en une seule, je suppose que pas mal de gens n'ont pas réussi à lire tout le chemin jusqu'à la fin:)

mon expérience de l'authentification de service web est que les gens généralement overengineer il, et les problèmes sont les mêmes que vous rencontreriez sur une page web. Les options très simples possibles comprendraient https pour l'étape de connexion, renvoyer un token, exiger qu'il soit inclus avec les requêtes futures. Vous pouvez également utiliser l'authentification http de base, et il suffit de passer au choses dans l'en-tête. Pour plus de sécurité, tournez/expirez les tokens fréquemment, vérifiez que les requêtes proviennent du même bloc D'IP (cela pourrait être un peu confus, car les utilisateurs mobiles se déplacent entre les cellules), combinez avec la clé API ou similaire. Alternativement, faites l'étape" request key " de oauth (quelqu'un l'a déjà suggéré dans une réponse précédente et c'est une bonne idée) avant d'authentifier l'utilisateur, et utilisez cette touche comme une clé requise pour générer le token d'accès.

An alternative que je n'ai pas encore utilisé mais j'ai beaucoup entendu parler comme une alternative facile à l'appareil de oAuth est xAuth . Si vous l'utilisez, j'aimerais connaître vos impressions.

pour le hachage, sha1 est un peu mieux, mais ne vous y accrochez pas - quoi que les appareils peuvent facilement (et rapidement dans un sens de performance) mettre en œuvre est probablement très bien.

Espère que ça aide, bonne chance :)

12
répondu Lorna Mitchell 2010-10-29 08:20:35

Twitter a abordé la question de l'application externe à oAuth en soutenant une variante qu'ils appellent xAuth . Malheureusement, il y a déjà une pléthore d'autres plans avec ce nom donc il peut être déroutant de trier.

Le protocole est oAuth, sauf qu'il ignore le jeton de demande de phase et simplement émet un jeton d'accès de la paire lors de la réception d'un nom d'utilisateur et mot de passe. (À partir de étape E ici .) Ce initial request and response doit être sécurisé - il envoie le nom d'utilisateur et le mot de passe en clair et de recevoir en retour le token d'accès et le token secret. Une fois que la paire de tokens d'accès a été configurée, que l'échange initial de tokens ait eu lieu via le modèle oAuth ou le modèle xAuth n'est pas pertinent pour le client et le serveur pour le reste de la session. Ceci a l'avantage que vous pouvez tirer parti de l'existant infrastructure et ont presque la même implémentation pour les applications mobiles/web/bureautique. Le principal inconvénient est que l'application se voit accorder l'accès au nom d'utilisateur et au mot de passe du client, mais il semble que vos exigences imposent cette approche.

en tout cas, je voudrais être d'accord avec votre intuition et celle de plusieurs autres répondants ici: n'essayez pas de construire quelque chose de nouveau à partir de zéro. Les protocoles de sécurité peuvent être faciles à démarrer mais sont toujours difficiles à faire et bien, et plus ils sont compliqués, moins vos développeurs tiers sont en mesure de mettre en œuvre contre eux. Votre hypothétique protocole est très similaire à o(x)Auth - api_key/api_secret, nonce, le hachage sha1 - mais au lieu d'être en mesure d'utiliser l'une des nombreuses bibliothèques existantes à vos développeurs vont avoir besoin de rouler leur propre.

9
répondu lantius 2015-02-05 12:30:43

alors ce que vous cherchez est une sorte de mécanisme d'authentification côté serveur qui traitera les aspects d'authentification et d'autorisation d'une application mobile?

en supposant que c'est le cas, alors je l'aborderais comme suit (mais seulement parce que je suis un développeur Java donc un c# guy le ferait différemment):

Le repos de l'authentification et de l'autorisation de service

  1. Ce sera ne travaillez que sur HTTPS pour éviter les écoutes.
  2. il sera basé sur une combinaison de RESTEasy , Spring Security et CAS (pour un seul signe sur des applications multiples).
  3. Il fonctionne avec les navigateurs internet ou d'applications client
  4. il y aura une interface de gestion de Compte basée sur le web pour permettre aux utilisateurs de modifier leurs détails, et admins (pour des applications particulières) pour modifier les niveaux d'autorisation

Le côté client de la sécurité de la bibliothèque/application

  1. pour chaque plate-forme supportée (p.ex. Symbian, Android, iOS etc) adapté de la mise en œuvre de la bibliothèque de sécurité dans le natif langue de la plateforme (par exemple Java, ObjectiveC, C etc)
  2. la bibliothèque devrait gérer la requête HTTPS formation utilisation des API disponibles pour la plate-forme donnée (par exemple Java use URLConnection etc)
  3. les Consommateurs de l'authentification générale et l'autorisation de la bibliothèque (parce que tout ce qu'il est) codera à un spécifique interface et ne sera pas heureux si elle ça change toujours, alors assure-toi que c'est très flexible. Suivez conception existante des choix tels que la sécurité du ressort.

alors maintenant que la vue à 30 000 pieds est complète, comment vous y prenez-vous? Eh bien, ce n'est pas difficile de créer une authentification et d'autorisation système basé sur les technologies côté serveur avec un navigateur client. En combinaison avec HTTPS, les frameworks fourniront un processus sécurisé basé sur un token partagé (généralement présenté comme un cookie) généré par le processus d'authentification et utilisé chaque fois que l'Utilisateur souhaite faire quelque chose. Ce jeton est présenté par le client au serveur chaque fois qu'une demande a lieu.

dans le cas du local application mobile, il semble que vous êtes à la recherche d'une solution qui fait ce qui suit:

  1. application Client a défini une Liste de Contrôle d'Accès (ACL) le contrôle de l'exécution d'accès pour les appels de méthode. Par exemple, un utilisateur donné peut lire une collection à partir d'une méthode, mais leur ACL permet seulement l'accès à des objets qui ont un Q dans leur nom de sorte que certaines données dans la collection est peu de tirer par l'intercepteur de sécurité. En Java, c'est simple, il suffit d'utiliser le ressort Annotations de sécurité sur le code appelant et mettre en œuvre un processus de réponse ACL approprié. Dans d'autres langues, vous êtes sur votre propre et vous aurez probablement besoin de fournir le code de sécurité boilerplate qui appelle dans votre bibliothèque de sécurité. Si le langage prend en charge L'AOP (Aspect Oriented Programming) puis l'utiliser au maximum pour cette situation.
  2. la bibliothèque de sécurité cache la liste complète des autorisations dans sa mémoire privée pour l'application actuelle afin qu'elle ne rester connecté. Selon la durée de la session de connexion, il peut s'agir d'une opération unique qui ne se répète jamais.

quoi que vous fassiez, n'essayez pas d'inventer votre propre protocole de sécurité , ou utilisez la sécurité par l'obscurité. Vous ne serez jamais capable d'écrire un meilleur algorithme pour ce que ceux qui sont actuellement disponibles et gratuit. De plus, les gens font confiance à des algorithmes bien connus. Donc, si vous dites que votre bibliothèque de sécurité fournit autorisation et authentification pour les applications mobiles locales en utilisant une combinaison de SSL, HTTPS, SpringSecurity et des tokens cryptés AES, vous aurez immédiatement une crédibilité sur le marché.

J'espère que cela vous aidera, et bonne chance avec votre projet. Si vous voulez plus d'information, faites - moi savoir-j'ai écrit pas mal d'applications web basées sur la sécurité de printemps, ACLs et autres.

8
répondu Gary Rowe 2010-10-28 12:36:49

Super-fin de la partie, mais je voulais la jeter dans certains autres points à considérer pour quiconque s'intéresse à cette question. Je travaille pour une entreprise qui fait des solutions de sécurité API mobiles ( approov ) de sorte que tout ce domaine est certainement pertinent pour mes intérêts.

pour commencer, la chose la plus importante à considérer lorsque vous essayez de sécuriser une API mobile est combien il vaut pour vous . La bonne solution pour une banque différent de la bonne solution pour quelqu'un qui fait juste des choses pour le plaisir.

Dans la solution proposée, vous mentionnez qu'un minimum de trois paramètres:

  • apikey - développeur lors de l'inscription
  • timestamp-double comme Identificateur unique pour chaque message pour une clé API donnée
  • de hachage hachage de l'horodatage + le apisecret

Cela implique que pour certains appels API aucun nom d'utilisateur / mot de passe n'est requis. Cela peut être utile pour les applications où vous ne voulez pas forcer une connexion (navigation dans les boutiques en ligne par exemple).

il s'agit d'un problème légèrement différent de celui de l'authentification de l'utilisateur et qui ressemble davantage à une authentification ou à une attestation du logiciel. Il n'y a pas d'utilisateur, mais vous voulez toujours s'assurer qu'il n'est pas malveillant d'accéder à votre API. Donc vous utilisez votre API secret pour signer le le trafic et identifier le code d'accès à L'API comme authentique. Le problème de cette solution est que vous devez donner le secret à l'intérieur de chaque version de l'application. Si quelqu'un peut extraire le secret, il peut utiliser votre API, imitant votre logiciel mais faisant ce qu'il veut.

pour contrer cette menace, il y a un tas de choses que vous pouvez faire en fonction de la valeur des données. Obfuscation est un moyen simple de rendre plus difficile à extrait de le secret. Il y a des outils qui le feront pour Vous, plus encore pour Android, mais vous devez toujours avoir du code qui génère votre hachage et une personne suffisamment qualifiée peut toujours appeler simplement la fonction qui fait le hachage directement.

une autre façon d'atténuer l'utilisation excessive d'une API qui ne nécessite pas de login est de réduire le trafic et potentiellement identifier et bloquer les adresses IP suspectes. Le montant de l'effort que vous voulez pour aller à dépendra en grande partie sur la façon dont vos données sont fiables.

au-delà de cela, vous pouvez facilement commencer à entrer dans le domaine de mon travail de jour. Quoi qu'il en soit, c'est un autre aspect de la sécurisation des API que je pense important et que je voulais signaler.

3
répondu ThePragmatist 2017-01-24 20:08:39