web-dev-qa-db-fra.com

Comment implémenter la connexion dans un service Web RESTful?

Je construis une application Web avec une couche de services. La couche de services va être construite en utilisant une conception RESTful. L'idée est que, dans le futur, nous pourrions créer d'autres applications (iPhone, Android, etc.) utilisant la même couche de services que l'application Web. Ma question est la suivante: comment implémenter la connexion? Je pense avoir du mal à passer d'une conception plus traditionnelle basée sur un verbe à une conception basée sur des ressources. Si je construisais ceci avec SOAP, j'aurais probablement une méthode appelée Login. Dans REST je devrais avoir une ressource. J'ai de la difficulté à comprendre comment construire mon URI pour un identifiant de connexion.

http: // myservice / {nom d'utilisateur}? p = {mot de passe}

ÉDITER: l'application Web front-end utilise le framework ASP.NET traditionnel pour l'authentification. Cependant, à un moment donné du processus d'authentification, je dois valider les informations d'identification fournies. Dans une application Web traditionnelle, je ferais une recherche dans une base de données. Mais dans ce scénario, j'appelle un service au lieu d'effectuer une recherche dans une base de données. J'ai donc besoin de quelque chose dans le service qui validera les informations d'identification fournies. Et en plus de valider les informations d'identification fournies, j'ai probablement aussi besoin d'une sorte d'informations sur l'utilisateur une fois l'authentification réussie - des informations telles que son nom complet, son identifiant, etc. J'espère que cela clarifie la question.

Ou est-ce que je ne pense pas à cela de la bonne façon? J'ai l'impression que j'ai du mal à décrire ma question correctement.

Corey

77
Corey Burnett

Comme S.Lott l’a déjà souligné, nous avons deux éléments: l’identification et l’authentification

L'authentification est hors de portée ici, car cela fait l'objet de nombreuses discussions et d'un accord commun. Cependant, de quoi avons-nous réellement besoin pour qu'un client s'authentifie avec succès auprès d'un service Web RESTful? Bon, une sorte de jeton, appelons-le jeton d'accès.

Client) Donc, tout ce dont j'ai besoin est un jeton d'accès, mais comment obtenir un tel RESTful?
Serveur) Pourquoi ne pas simplement le créer?
Client) Comment ça se passe?
Serveur) Pour moi, un jeton d'accès n'est rien d'autre qu'une ressource. Ainsi, je vais en créer un pour vous en échange de votre nom d'utilisateur et mot de passe.

Ainsi, le serveur pourrait proposer l’URL de la ressource "/ accesstokens", pour la publication du nom d’utilisateur et du mot de passe, renvoyant le lien vers la ressource nouvellement créée "/ accesstokens/{accesstoken}". Vous pouvez également retourner un document contenant le jeton d'accès et un href avec le lien de la ressource:

 <jeton d'accès 
 id = "{l'identifiant du jeton d'accès va ici; par exemple, GUID}" 
 href = "/ accesstokens/{id}" 
 /> 

Très probablement, vous ne créez pas réellement le jeton d'accès en tant que sous-ressource et n'incluez donc pas son href dans la réponse.
Toutefois, si vous le faites, le client pourrait générer le lien en son nom ou non? Non!
Rappelez-vous, les services Web véritablement RESTful relient les ressources entre elles de manière à ce que le client puisse naviguer sans avoir à générer de liens de ressource.

La dernière question que vous avez probablement est de savoir si vous devez POST le nom d'utilisateur et le mot de passe sous la forme d'un formulaire HTML ou d'un document, par exemple XML ou JSON - cela dépend ... :-)

59
Patrick

Vous ne vous "connectez" pas. Vous "authentifiez". Monde de différence.

Vous avez beaucoup d'alternatives d'authentification.

authentification HTTP Basic, Digest, NTLM et AWS S

  • Authentification HTTP Basic et Digest. Ceci utilise le HTTP_AUTHORIZATION entête. C'est très gentil, très simple. Mais peut conduire à beaucoup de trafic.

  • Authentification par nom d'utilisateur/signature. Parfois appelée authentification "ID et KEY". Cela peut utiliser une chaîne de requête.

    ?username=this&signature=some-big-hex-digest

    C'est ce que des endroits comme Amazon utilisent. Le nom d'utilisateur est "id". La "clé" est un condensé, similaire à celui utilisé pour l'authentification HTTP Digest. Les deux parties doivent se mettre d'accord sur le résumé pour continuer.

  • Une sorte d'authentification basée sur les cookies. OpenAM , par exemple, peut être configuré en tant qu'agent pour authentifier et fournir un cookie que votre serveur Web RESTful peut ensuite utiliser. Le client s'authentifiera d'abord, puis fournira le cookie avec chaque demande RESTful.

24
S.Lott

Excellente question, bien posée. J'aime beaucoup la réponse de Patrick. J'utilise quelque chose comme

-/utilisateurs/{nom d'utilisateur}/loginsession

Avec POST et GET en cours de traitement. Ainsi, je publie une nouvelle session de connexion avec des informations d'identification et je peux ensuite afficher la session en cours en tant que ressource via GET.

La ressource est une session de connexion et peut comporter un jeton d'accès ou un code d'autorisation, une date d'expiration, etc.

Curieusement, mon appelant MVC doit lui-même présenter un jeton clé/porteur via un en-tête pour prouver qu'il a le droit d'essayer de créer de nouvelles sessions de connexion car le site MVC est un client de l'API.

Éditer

Je pense que d’autres réponses et commentaires ici résolvent le problème avec un secret partagé hors bande et s’authentifient simplement avec un en-tête. Cela convient dans de nombreuses situations ou pour les appels de service à service.

L'autre solution consiste à faire passer un jeton, OAuth ou JWT ou autre, ce qui signifie que la "connexion" a déjà eu lieu par un autre processus, probablement une interface utilisateur de connexion normale dans un navigateur basé sur un formulaire POST.

Ma réponse concerne le service situé derrière cette interface utilisateur, en supposant que vous souhaitiez que la connexion, l’authentification et la gestion des utilisateurs soient placées dans un service REST et non dans le code MVC du site. Il IS le service de connexion de l'utilisateur.

Il permet également à d'autres services de "se connecter" et d'obtenir un jeton expiré, au lieu d'utiliser une clé pré-partagée, ainsi que des scripts de test dans une CLI ou Postman.

1
Luke Puplett

La première chose à comprendre sur REST est qu’il s’agit d’un accès aux ressources basé sur un jeton. Contrairement aux moyens traditionnels, l’accès est accordé en fonction de la validation du jeton. En termes simples, si vous avez le droit, vous pouvez accéder aux ressources .Maintenant, il y a beaucoup d'autres éléments pour la création et la manipulation de jetons.

Pour votre première question, vous pouvez concevoir une API Restfull. Les informations d'identification (nom d'utilisateur et mot de passe) seront transmises à votre couche de service. La couche de service valide ensuite ces informations d'identification et accorde un jeton. Les informations d'identification peuvent être un simple nom d'utilisateur/mot de passe ou des certificats SSL. Les certificats SSL utilisent le protocole OAUTH) et sont plus sécurisés.

Vous pouvez concevoir votre URI comme ceci: URI pour la demande de jeton -> http: // myservice/some-directory/token ? (Vous pouvez transmettre des Credentilals dans cet URI pour un jeton)

Pour utiliser ce jeton pour l'accès aux ressources, vous pouvez ajouter ceci [Autorisation: porteur (jeton)] à votre en-tête http.

Ce jeton peut être utilisé par le client pour accéder à différents composants de votre couche de service. Vous pouvez également modifier la période d'expiration de ce jeton pour éviter toute utilisation abusive.

Pour votre deuxième question, vous pouvez autoriser différents jetons pour accéder à différents composants de ressources de votre couche de service. Pour cela, vous pouvez spécifier un paramètre de ressource dans votre jeton, ainsi qu'une grande autorisation basée sur ce champ.

Vous pouvez également suivre ces liens pour plus d’informations - http://www.codeproject.com/Articles/687647/Detailed-Tutorial-for-Building-ASP-NET-WebAPI-REST

http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

0
Rishabh Soni

Depuis pas mal de choses ont changé depuis 2011 ...

Si vous êtes prêt à utiliser un outil tiers et que vous vous écartez légèrement de REST légèrement pour l'interface utilisateur Web, considérez http://shiro.Apache.org .

Shiro vous fournit essentiellement un filtre de servlet destiné à l'authentification et à l'autorisation. Vous pouvez utiliser toutes les méthodes de connexion répertoriées par @ S.Lott, y compris une authentification basée sur un formulaire simple.

Filtrez les autres URL nécessitant une authentification, et Shiro fera le reste.

J'utilise actuellement cela dans mon propre projet et cela a plutôt bien fonctionné pour moi jusqu'à présent.

Voici quelque chose d'autre qui pourrait intéresser les gens. https://github.com/PE-INTERNATIONAL/shiro-jersey#readme

0
Half_Duplex