69 votes

Autorisation et authentification de l'API REST (Web + mobile)

J'ai lu sur oAuth, Amazon RESTE API HTTP de Base/Digest et ainsi de suite, mais ne peut pas obtenir tous en "seul morceau". C'est probablement le plus proche de la situation - Création d'une API pour les applications mobiles, l'Authentification et l'Autorisation

Je voudrais construit API-site web centré sur l' - service. Donc (au début) je voudrais avoir une API dans le centre et le site web (PHP + MySQL) permettrait de se connecter via cURL, Android et iPhone via leurs interfaces réseau. Donc 3 principaux clients - 3 clés API. Et n'importe quel autre développeur pourrait également développer via l'interface de l'API et ils auraient leur propre clé API. API actions seraient acceptées/rejetées sur la base d'userLevel statut, si je suis un admin, je peux rien supprimer, etc., tous les autres peuvent manipuler seulement leurs locaux (compte) de données.

Tout d'abord, l'autorisation - dois-je utiliser oAuth + xAuth ou mon quelque-sorte-de-mon-propre mise en oeuvre (voir http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/RESTAuthentication.html?r=9197)? Ce que je comprends, sur Amazon les utilisateurs des services == utilisateur API (ont clé API). Sur mon service, j'ai besoin de séparer les utilisateurs standard/compte (celui qui s'est inscrit sur le site) et les Comptes des Développeurs (qui devraient avoir leur clé API).

Donc, je voudrais tout d'abord besoin d' autoriser la clé API et puis Authentifier l'utilisateur lui-même. Si j'utilise Amazon du régime de vérification du développeur de l'API keys (autoriser leur application), qui sheme dois-je utiliser pour l'authentification de l'utilisateur?

J'ai lu sur l'obtention d'un jeton via api.example.org/auth après (via HTTPS, HTTP de Base) l'affichage de mon nom d'utilisateur et mot de passe, puis de le transférer à chaque demande. Comment gérer les invitations si je suis connecté simultanément sur Android et un site web? Ce de l'homme-dans-le-milieu-attaque si je suis en utilisant SSL uniquement lors de la première demande (lorsque le nom d'utilisateur et mot de passe sont transmis) et juste en HTTP sur tous les autres? N'est-ce pas un problème dans cet exemple, le Mot de passe de protection d'un service REST?

123voto

Eugen Rieck Points 33670

Comme toujours, la meilleure façon de protéger une clé n'est pas à la transmettre.

Cela dit, nous avons généralement l'utilisation d'un schéma, où chaque "API key" comporte deux parties: Un non-secret ID (par exemple 1234) et une clé secrète (par exemple, byte[64]).

  • Si vous donnez une clé API, ranger (salées et hachées) en vous base de données du service.
  • Si vous donnez des comptes d'utilisateur (protégé par mot de passe), le magasin de la les mots de passe (salées et hachées) dans votre base de données du service

Maintenant, quand un consommateur premier accède à votre API, pour vous connecter, demandez-lui de

  • Envoyer un "nom d'utilisateur" paramètre ("jean.doe" pas de secret)
  • Envoyer un "APIkeyID" paramètre ("1234", pas de secret)

et lui donner

  • les sels à partir de votre base de données (Dans le cas où l'un des paramètres est incorrect, juste redonner de la reproductible sel par exemple. sha1(nom d'utilisateur+"notverysecret").
  • Le timestamp du serveur

Le consommateur doit stocker le sel pour la durée de la session pour garder les choses vite et en douceur, et il doit calculer et garder le décalage dans le temps entre le client et le serveur.

Le consommateur doit maintenant calculer le salé des tables de hachage de la clé API et le mot de passe. De cette façon, le consommateur a exactement la même hachages pour le mot de passe et la clé API, comme ce qui est stocké dans votre base de données, mais sans rien de seceret va jamais sur le fil.

Maintenant, quand un consommateur subseqently accède à votre API, pour faire du vrai travail, demandez-lui de

  • Envoyer un "nom d'utilisateur" paramètre ("jean.doe" pas de secret)
  • Envoyer un "APIkeyID" paramètre ("1234", pas de secret)
  • Envoyer un "RequestSalt" paramètre (octet[64], aléatoire, pas de secret)
  • Envoyer un "RequestTimestamp" paramètre (calculé à partir du client de temps et connue de décalage)
  • Envoyer un "RequestToken" paramètre (hash(propriétés passwordhash+request_salt+request_timestamp+apikeyhash))

Le serveur ne doit pas accepter les horodatages de plus que de dire 2 secondes dans le passé, pour faire de ce coffre-fort à l'encontre d'une relecture de l'attaque.

Le serveur peut maintenant calculer le même hash(propriétés passwordhash+request_salt+request_timestamp+apikeyhash) que le client, et être sûr que

  • le client connaît la clé de l'API,
  • le client connaît le mot de passe correct

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X