43 votes

Service web Restful authentification

J'ai un service web Restful API, qui est utilisé par les différents 3e parties. Une partie de cette API est limité (vous avez besoin du nom d'utilisateur/mot de passe pour y accéder). Je me demandais quel serait le meilleur moyen de la mise en œuvre de l'authentification?

Je suis en utilisant le protocole https, donc la communication est cryptée. J'ai deux idées:

  • Avant que l'utilisateur commence à utiliser (restreint) de service, il envoie le nom d'utilisateur/mot de passe à l'aide de la POSTE (depuis https est utilisé les informations d'identification sont cryptées). Après la connexion est réussie, le serveur renvoie aléatoire simple de la valeur d'usage (pour l'instant) qui est mis en correspondance avec ce nom d'utilisateur. Lors de la prochaine demande est faite, le long du côté d'un nom d'utilisateur, le client envoie déjà retourné nonce. Les serveurs matches nom d'utilisateur et le nonce et retourne le nouveau nonce à côté de données demandées. Chaque nouvelle requête utilise le nouveau nonce. Fondamentalement, c'est une version allégée de Digest authentification d'accès.
  • Depuis cette API est utilisée à partir de la 3ème partie, le nom d'utilisateur/mot de passe peut être utilisé pour chaque (restreint) de la demande. Depuis https est utilisé, ils seront cryptées. La chute de cette approche est le fait que ce ne serait pas Reposante conforme (POST serait toujours utilisé).

Je suis beaucoup plus proche de choix à la première approche (c'est Reposant conforme, relativement facile à mettre en œuvre, XML, json ou html peut être utilisé sans changer quoi que ce soit), mais je voulais voir quelle est votre opinion? Que recommandez-vous: d'abord, deuxième ou une troisième approche?

Btw, je suis à l'aide de Python à côté serveur.

22voto

Chris Nicola Points 3699

Une façon dont j'ai vu cela en l'Api (et le suis actuellement en œuvre) est de créer une bonne ressource appelée Session qui est créé par un POST qui fournit un nom d'utilisateur et mot de passe.

Voici en gros comment j'ai mis en place:

POST /sessions { Username: "User", Password: "Password" }

Créer un temps limité, à une session, et retourne la session de ressources qui contient la valeur de la clé de session et la date de péremption. Vous pouvez également retourner ce qu'un cookie valeur pour la commodité de mise en œuvre de l'API clients.

DELETE /session/{id}

Immédiatement l'expiration de la session, de sorte qu'il ne peut plus être utilisé. Ce est utilisé pour la connexion explicite les aboutissants.

J'ai ensuite demandez à l'utilisateur de fixer la clé de session par l'intermédiaire d'un paramètre de requête, mais vous pouvez également lui permettre d'être soumis par l'intermédiaire d'une valeur de cookie, je le recommande permettant à la fois.

Ce que je préfère, c'est qu'il est extrêmement simple.

Évidemment, le scénario dicter quelque peu comment vos séances doivent être gérés, et peut-être qu'ils ne sont pas limitées dans le temps et durer indéfiniment, et peut-être qu'ils sont hachés ou crypté pour plus de sécurité.

Si vous utilisez le protocole HTTPS everywhere vous n'avez probablement pas besoin de trop s'inquiéter. Cependant, si vous souhaitez utiliser HTTP, vous aurez besoin d'utiliser quelque chose comme une table de hachage avec une clé secrète et de dire un timbre de temps pour générer une clé sécurisée par demande. De cette façon, vous pouvez partager le secret de la clé sur HTTPS et ensuite passer en HTTP pour les appels supplémentaires. Même si quelqu'un parvient à flairer la clé à partir d'une requête, il peut expirer presque immédiatement et d'être inutile.

Avertissement: je ne suis pas un expert en sécurité ;-).

8voto

Will Hartung Points 57465

Il n'y a pas de raison de ne pas utiliser l'authentification HTTP ici.

Cela dit, la notion de Détachement pour obtenir un bloc de temps de nonce peut bien fonctionner. Mais ce sont les motivations pour lesquelles vous devez passer par le biais de ce surplus de cerceau dans la première place.

Cette technique a été considérée lors de l'utilisation d'un bcrypt hachage du mot de passe d'origine, en raison de la dépense réelle de la validation d'un utilisateur (si vous ne savez pas, bcrypt peut être réglé pour prendre un vrai temps pour effectuer la fonction de hachage). Le choix a été fait d'offrir la possibilité d'avoir le service "connexion" une fois en utilisant le mot de passe qui serait aller à travers le coûteux processus de validation via bcrypt, et ensuite obtenir un temps bloqué jeton en retour pour de futures demandes qui permettrait de contourner le bcrypt processus.

Dans le cas de la bcrypt processus, utiliser l'Authentification HTTP, le service serait de travailler avec les deux à la normale mot de passe ainsi qu'avec le jeton. De cette façon, l'utilisateur peut toujours utiliser le mot de passe pour leur service, mais ça devient cher. Ainsi, ils PEUVENT faire cela, ils NE devraient tout simplement PAS. Le service ne se soucie pas de qui technique d'authentification, le client utilise.

Le nonce service est offert une parenthèse afin d'améliorer le débit.

Autre que cela, c'est la norme d'authentification HTTP, mais avec un nouveau système.

6voto

Tahbaza Points 5878

Amazon web services qu'elle le fait bien, regardez, il y méthodologie pour quelques idées. Essentiellement, ils obtenir des clients pour chiffrer un en-tête http spécial à l'aide de leur mot de passe.

Voici le lien:

http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html

4voto

tbi Points 391

En supposant que le service n'est jamais consommée dans un navigateur et de la communication est cryptée, de toute façon, je ne vois pas de mal à une variation de la deuxième méthode: Ajouter des en-Têtes X pour envoyer le nom d'utilisateur/mot de passe à chaque demande, par exemple:

GET /foo HTTP/1.1
Host: www.bar.com
X-MyUsername: foo
X-MyPassword: bar

Une autre idée serait d'utiliser HTTP Basic Auth et il suffit d'envoyer un Authorization: Basic base64(user:password)-d'en-Tête. Qui est, si la connexion est toujours crypté.

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