Authentification API REST

181

Je construis une application qui sera hébergée sur un serveur. Je souhaite créer une API pour l'application afin de faciliter l'interaction avec n'importe quelle plate-forme (application Web, application mobile). Ce que je ne comprends pas, c'est que lors de l'utilisation de l'API REST, comment authentifier l'utilisateur.

Par exemple, lorsqu'un utilisateur s'est connecté et souhaite ensuite créer un sujet de forum. Comment saurai-je que l'utilisateur est déjà connecté?

Noor
la source
4
Vous devriez probablement rechercher «authentification REST» ici. Cela a été couvert dans de nombreuses autres questions.
Brian Kelly
10
En un mot, laissez le client envoyer un nom d'utilisateur et un mot de passe avec chaque demande en utilisant HTTP Basic Auth (sur SSL!), Ou authentifiez-vous une fois pour que le client ait une session authentifiée qui expirera après une certaine période d'inactivité (ou quelle que soit la manière dont vous choisissez de remplacer la gestion de session de votre framework web). Ladite session peut alors être stockée dans un cookie, ou être un paramètre passé à chaque requête (par exemple JSESSIONID dans Java land).
opyate
@opyate du point de vue de la sécurité, ce n'est pas vraiment une bonne idée de gérer la session à l'aide de cookies dans un cas d'API REST, car les attaquants peuvent envoyer des requêtes sans le consentement de l'utilisateur. Il est préférable d'inclure un hachage de session ou un jeton dans un en-tête HTTP (tel que l'autorisation).
s3v3n
1
@ s3v3n Corrigez-moi si je me trompe, mais vos suggestions et mes suggestions ne sont que des façons différentes d'utiliser un combo en-tête + stockage local pour effectuer la même chose. C'est l'en- Authorizationtête + par exemple l'en- tête du navigateur localStorage VS Cookie+ le stockage standard des cookies du navigateur.
opyate

Réponses:

72

Vous pouvez utiliser l'authentification HTTP Basic ou Digest. Vous pouvez authentifier en toute sécurité les utilisateurs en utilisant SSL par-dessus, cependant, cela ralentit un peu l'API.

  • Authentification de base - utilise le codage Base64 sur le nom d'utilisateur et le mot de passe
  • Authentification Digest - hache le nom d'utilisateur et le mot de passe avant de les envoyer sur le réseau.

OAuth est ce qu'il y a de mieux. Les avantages qu'oAuth donne est un jeton révocable ou expirable. Reportez-vous ci-dessous pour savoir comment mettre en œuvre: Lien de travail à partir des commentaires: https://www.ida.liu.se/~TDP024/labs/hmacarticle.pdf

ankitjaininfo
la source
4
Veuillez lire cette question et la réponse fournie par Les Hazelwood (auteur d'Apache Shiro).
justin.hughey
1
Lien utile comment Twitter protège-t-il son API REST: Sécurité de l'API REST Twitter
WildDev
Comme c'est la réponse acceptée, je pense qu'il est important de mentionner que vous pouvez également utiliser l'authentification Digest.
Découvrez les
116

Par exemple, lorsqu'un utilisateur s'est connecté, disons maintenant que l'utilisateur souhaite créer un sujet de forum, comment saurai-je que l'utilisateur est déjà connecté?

Pensez-y - il doit y avoir une poignée de main qui indique à votre API "Créer un forum" que cette requête en cours provient d'un utilisateur authentifié. Étant donné que les API REST sont généralement sans état, l'état doit être conservé quelque part . Votre client qui utilise les API REST est responsable du maintien de cet état. Habituellement, il se présente sous la forme d'un jeton qui est transmis depuis le moment où l'utilisateur s'est connecté. Si le jeton est bon, votre demande est bonne.

Vérifiez comment Amazon AWS effectue les authentifications. C'est un exemple parfait de «transfert de responsabilité» d'une API à une autre.

* J'ai pensé à ajouter une réponse pratique à ma réponse précédente. Essayez Apache Shiro (ou n'importe quelle bibliothèque d'authentification / d'autorisation). En bout de ligne, essayez d'éviter le codage personnalisé. Une fois que vous avez intégré votre bibliothèque préférée (j'utilise Apache Shiro, btw), vous pouvez alors faire ce qui suit:

  1. Créez une API de connexion / déconnexion comme: /api/v1/loginetapi/v1/logout
  2. Dans ces API de connexion et de déconnexion, effectuez l'authentification avec votre magasin d'utilisateurs
  3. Le résultat est un jeton (généralement JSESSIONID) qui est renvoyé au client (Web, mobile, peu importe)
  4. À partir de ce moment, tous les appels ultérieurs effectués par votre client incluront ce jeton
  5. Disons que votre prochain appel est effectué vers une API appelée /api/v1/findUser
  6. La première chose que ce code API fera est de vérifier le jeton ("cet utilisateur est-il authentifié?")
  7. Si la réponse revient par NON, vous renvoyez un état HTTP 401 au client. Laissez-les s'en occuper.
  8. Si la réponse est OUI, continuez pour renvoyer l'utilisateur demandé

C'est tout. J'espère que cela t'aides.

Kingz
la source
Donc, ce que vous décrivez est essentiellement un cookie de session, non?
LordOfThePigs
oui, mais la session est "maintenue" à 2 endroits différents. Un dans le serveur API, un autre dans le navigateur. La réponse JSON (ou autre) au navigateur après la connexion réussie doit communiquer l'ID de session sur le serveur API au navigateur. Ces sessions sont gérées indépendamment par leurs agents respectifs.
Kingz
11
Je crois que Kingz essayait de transmettre l'idée que le mécanisme de maintien de la session est intentionnellement vague. Un cookie de session n'est qu'une implémentation de ce mécanisme.
justin.hughey
2
@Kingz, qu'en est-il de la sécurité dans cette solution, par exemple si un pirate informatique renifle le lien avec session_id et commence à envoyer des requêtes quel contenu corrige session_id? Nous pouvons le résoudre en ajoutant ssl à la connexion au serveur, mais qu'en est-il des clients?
Ahmad Samilo
1
Comment éviter le détournement de session dans le cas de l'homme au milieu de l'attrack?
m0z4rt
38
  1. Utilisez HTTP Basic Auth pour authentifier les clients, mais ne traitez le nom d'utilisateur / mot de passe que comme un jeton de session temporaire .

    Le jeton de session est juste un en-tête attaché à chaque requête HTTP, par exemple: Authorization: Basic Ym9ic2Vzc2lvbjE6czNjcmV0

    La chaîne Ym9ic2Vzc2lvbjE6czNjcmV0 ci-dessus est juste la chaîne "bobsession1: s3cret" (qui est un nom d'utilisateur / mot de passe) encodée en Base64.

  2. Pour obtenir le jeton de session temporaire ci-dessus, fournissez une fonction API (par exemple:) http://mycompany.com/apiv1/loginqui prend le nom d'utilisateur principal et le mot de passe principal comme entrée, crée un nom d'utilisateur / mot de passe HTTP Basic Auth temporaire côté serveur et renvoie le jeton (par exemple: Ym9ic2Vzc2lvbjE6czNjcmV0). Ce nom d'utilisateur / mot de passe doit être temporaire, il doit expirer après environ 20 minutes.

  3. Pour plus de sécurité, assurez-vous que votre service REST est servi via HTTPS afin que les informations ne soient pas transférées en clair

Si vous êtes sur Java, la bibliothèque Spring Security fournit un bon support pour implémenter la méthode ci-dessus

gerrytan
la source
1
Pourquoi devrait-il expirer après 20 minutes? et si c'est un site Web comme Facebook que la connexion est jusqu'à ce que l'utilisateur se déconnecte?
Dejell
1
@dejel J'étais sous l'hypothèse que "session" est de nature temporaire. Il est courant qu'il expire si l'utilisateur est au ralenti
gerrytan
À quoi sert le Base64? Vous pouvez simplement renvoyer le mot de passe temporaire. Dans les deux cas, ce qui compte vraiment, c'est que ce mot de passe temporaire soit fort. Vérifiez security.stackexchange.com/a/19686/72945
e18r le
7

Je pense que la meilleure approche est d'utiliser OAuth2. Google et vous trouverez de nombreux articles utiles pour vous aider à le configurer.

Cela facilitera le développement d'applications client pour votre API à partir d'une application Web ou d'une application mobile.

J'espère que cela vous aide.

Paulo Henrique
la source
2
Veuillez lire cette question et la réponse de Les Hazelwood (auteur d'Apache Shiro).
justin.hughey
0

J'utilise l'authentification JWT. Fonctionne très bien dans mon application.

Il existe une méthode d'authentification qui nécessitera les informations d'identification de l'utilisateur. Cette méthode valide les informations d'identification et renvoie un jeton d'accès en cas de succès.

Ce jeton doit être envoyé à toutes les autres méthodes de mon API Web dans l'en-tête de la requête.

C'est assez facile à mettre en œuvre et très facile à tester.

Arthur Medeiros
la source