74 votes

Sécuriser l'API REST sans réinventer la roue

Lors de la conception d'API REST est-il commun pour authentifier un utilisateur en premier?

Le cas d'utilisation typique, je suis à la recherche de:

  • L'utilisateur veut obtenir les données. Assurez-vous cool on aime partager! Obtenir une API publique de la clé et de lire de suite!
  • L'utilisateur veut enregistrer/mettre à jour les données... woah attendre! qui êtes-vous, pouvez-vous faire cela?

Je voudrais construire une fois et permettre à dire une application web, une application android ou une application iPhone pour l'utiliser.

Une API REST qui semble être un choix logique avec les exigences comme ceci

Pour illustrer ma question, je vais utiliser un exemple simple.

J'ai un objet dans une base de données, qui a une cote d'attribut (entier de 1 à 5).

Si je comprends RESTE correctement je voudrais mettre en œuvre une requête GET à l'aide de la langue de mon choix qui renvoie csv, xml ou json comme ceci:

http://example.com/product/getrating/{id}/

Dites-nous prendre en JSON nous retourner:

{
  "id": "1",
  "name": "widget1",
  "attributes": { "rating": {"type":"int", "value":4} }
}

C'est bien pour le public face à des Api. Je reçois la partie.

Où j'ai des tonnes de question est comment puis-je combiner cela avec un modèle de sécurité? J'ai l'habitude de web-sécurité des applications où j'ai un état de la session de l'identification de mon utilisateur à tous les temps donc je peux contrôler ce qu'ils peuvent faire n'importe quoi, ils décident de m'envoyer. Ce que je comprends, ce n'est pas Reposant serait une mauvaise solution dans ce cas.

Je vais essayer d'utiliser un autre exemple d'utilisation de la même item/notation.

Si l'utilisateur "JOE" veut ajouter une notation à un élément

Cela peut être fait en utilisant:

http://example.com/product/addrating/{id}/{givenRating}/

À ce point, je tiens à stocker les données en disant que "JOE" a donné le produit {id} une cote de {givenRating}.

Question: Comment puis-je sais que la demande est venue de "JOE" et non pas "BOB".

Par ailleurs, si c'était pour les plus sensibles comme les données d'un utilisateur à un numéro de téléphone?

Ce que j'ai obtenu jusqu'à présent est:

1) Utiliser la fonctionnalité intégrée de HTTP pour authentifier à chaque demande, la plaine HTTP ou HTTPS.

Cela signifie que chaque demande maintenant prendre la forme de:

https://joe:joepassword@example.com/product/addrating/{id}/{givenRating}/

2) Utiliser une approche comme celle d'Amazon S3 avec clé privée et publique: http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/

3) Utiliser un cookie de toute façon et de briser les apatrides partie de REPOS.

La deuxième approche semble mieux pour moi, mais je suis de gauche, vous demandez-vous à faire j'ai vraiment besoin de ré-inventer toute cette histoire? Le hachage, le stockage, la génération de clés, etc, tout par moi-même?

Cela sonne un peu comme à l'aide de session dans une application web typique et la réécriture de l'ensemble de la pile vous-même, qui d'habitude me dire "Vous faites mal" surtout lorsqu'il s'agit de sécurité.

EDIT: je suppose que je devrais avez mentionné OAuth.

21voto

Daniel Pereira Points 1413

Ne vous inquiétez pas d'être de "repos", vous soucier de la sécurité. Voici comment je le fais:

Etape 1: l'Utilisateur appuie sur le service d'authentification des informations d'identification.

Étape 2: Si les informations d'identification de vérifier, de retour d'une empreinte digitale, l'id de session, etc..., et de la pop dans la mémoire partagée pour la récupération rapide plus tard, ou l'utilisation d'une base de données si vous n'avez pas l'esprit en ajoutant quelques millisecondes à votre site web, le temps de traitement.

Étape 3: Ajouter un point d'entrée d'appel à la partie supérieure de chaque service web script qui valide les empreintes digitales et l'id de session pour chaque demande de service web.

Étape 4: Si l'empreinte et l'id de session ne sont pas valide ou a expiré rediriger vers d'authentification.

LIRE CECI:

Réparateur D'Authentification

21voto

Evert Points 17625

Non, il n'y a absolument pas besoin d'utiliser un cookie. Il n'est pas aussi sécurisé que HTTP Digest, authentification OAuth ou d'Amazon AWS (qui n'est pas difficile de copie).

La façon dont vous devriez regarder un cookie est que c'est un jeton d'authentification autant que de Base/Digest/OAuth/quel serait, mais de moins en moins adapté.

Cependant, je ne me sens pas à l'aide d'un cookie va à l'encontre de principes Reposant en soi, aussi longtemps que le contenu du cookie de session n'a pas d'influence sur le contenu de la ressource que vous êtes de retour à partir du serveur.

Les Cookies sont de mal, arrêtez de les utiliser.

8voto

inf3rno Points 2989

L'utilisation d'un témoin de toute façon et de briser les apatrides partie de REPOS.

Ne pas utiliser les sessions, avec des sessions de votre service ne sera pas bien évolutive... Il y a 2 membres ici: l'état de l'application (ou le client de l'état ou de la session s) et des ressources de l'état. L'état de l'Application contient les données de la session et il est maintenu par le client REST. Des ressources de l'état contient des propriétés et des relations, et est maintenu par le service REST. Vous pouvez décider très facile de savoir si une variable est une partie de l'état de l'application ou de la ressource de l'etat. Si la quantité de données augmente avec le nombre de sessions actives, alors il appartient à l'état de l'application. Ainsi, par exemple, l'identité de l'utilisateur par la session en cours appartient à l'état de l'application, mais la liste des utilisateurs ou des autorisations de l'utilisateur appartient à la ressource de l'etat.

Donc, le RESTE client doit stocker l'identification des facteurs et de les envoyer avec chaque demande. Ne pas confondre le RESTE client avec le client HTTP. Ils ne sont pas les mêmes. RESTE client peut être sur le côté serveur, même si elle utilise curl, ou il peut créer par exemple un serveur http côté seulement cookie qui il peut partager avec le RESTE du service via la SCRO. La seule chose que les questions que le RESTE de service doit s'authentifier à chaque demande, de sorte que vous devez envoyer les informations d'identification (nom d'utilisateur, mot de passe) à chaque demande.

  • Si vous écrivez un côté client RESTE client, alors cela peut être fait avec SSL + HTTP auth. Dans ce cas, vous pouvez créer un credentials -> (identity, permissions) cache sur le serveur pour faire de l'authentification plus rapide. Être conscient de ce que si vous effacez le cache, et les utilisateurs d'envoyer la même demande, ils recevront la même réponse, tout cela va prendre un peu plus longtemps. Vous pouvez comparer cela avec les sessions: si vous désactivez la session de vente, les utilisateurs pourront obtenir un status: 401 unauthorized de réponse...
  • Si vous écrivez un serveur côté client REST et vous envoyer les éléments d'identification pour le RESTE de service via curl, alors vous avez 2 choix. Vous pouvez utiliser http auth ainsi, ou vous pouvez utiliser un gestionnaire de session dans votre REPOS client mais pas dans le RESTE du service.
  • Si quelqu'un non fiables écrit de votre client, alors vous devez écrire une application pour authentifier les utilisateurs et de leur donner la possibilité de décider s'ils veulent accorder des autorisations pour les différents clients ou non. Oauth est un déjà existant solution pour cela. Oauth1 est plus sécurisé, oauth2 est moins sûr mais c'est plus simple, et je pense qu'il y a plusieurs autre solution pour ce problème... Vous n'avez pas à réinventer le présent. Il y a complète d'authentification et d'autorisation des solutions à l'aide d'oauth, par exemple: le bureau des services mondiaux de l'identité du serveur.

Les Cookies ne sont pas nécessairement mauvais. Vous pouvez les utiliser dans une bonne voie, jusqu'à ce qu'ils détiennent état du client et le service détient des ressources de l'état. Par exemple, vous pouvez stocker la charrette ou le préféré paramètres de pagination dans les cookies...

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