Que signifie l'authentification RESTful et comment fonctionne-t-elle? Je ne trouve pas un bon aperçu sur Google. Ma seule compréhension est que vous passez la clé de session (remeberal) dans l'URL, mais cela pourrait être horriblement faux.
745
Réponses:
Comment gérer l'authentification dans une architecture client-serveur RESTful est un sujet de débat.
Généralement, cela peut être réalisé, dans le monde SOA sur HTTP via:
Vous devrez adapter, ou encore mieux mélanger ces techniques, pour correspondre au mieux à votre architecture logicielle.
Chaque schéma d'authentification a ses propres avantages et inconvénients, en fonction de l'objectif de votre politique de sécurité et de votre architecture logicielle.
Authentification de base HTTP sur HTTPS
Cette première solution, basée sur le protocole HTTPS standard, est utilisée par la plupart des services Web.
Il est facile à implémenter, disponible par défaut sur tous les navigateurs, mais présente certains inconvénients connus, comme la terrible fenêtre d'authentification affichée sur le navigateur, qui persistera (il n'y a pas de fonctionnalité de type LogOut ici), une consommation supplémentaire de CPU côté serveur, et le fait que le nom d'utilisateur et le mot de passe sont transmis (via HTTPS) au serveur (il devrait être plus sûr de laisser le mot de passe uniquement côté client, lors de la saisie au clavier, et être stocké en tant que hachage sécurisé sur le serveur) .
Nous pouvons utiliser l' authentification Digest , mais elle nécessite également HTTPS, car elle est vulnérable aux attaques MiM ou Replay , et est spécifique à HTTP.
Session via les cookies
Pour être honnête, une session gérée sur le serveur n'est pas vraiment sans état.
Une possibilité pourrait être de conserver toutes les données dans le contenu des cookies. Et, par conception, le cookie est géré côté serveur (le client, en fait, n'essaie même pas d'interpréter ces données de cookie: il les restitue simplement au serveur à chaque demande successive). Mais ces données de cookie sont des données d'état d'application, donc le client doit les gérer, pas le serveur, dans un monde sans état pur.
La technique des cookies elle-même est liée à HTTP, donc ce n'est pas vraiment RESTful, qui devrait être indépendant du protocole, à mon humble avis. Il est vulnérable aux attaques MiM ou Replay .
Accordé via Token (OAuth2)
Une alternative consiste à placer un jeton dans les en-têtes HTTP afin que la demande soit authentifiée. C'est ce que fait OAuth 2.0, par exemple. Voir la RFC 6749 :
En bref, cela est très similaire à un cookie et souffre des mêmes problèmes: pas apatride, s'appuyant sur les détails de transmission HTTP et soumis à de nombreuses faiblesses de sécurité - y compris MiM et Replay - ne doit donc être utilisé que via HTTPS. En règle générale, un JWT est utilisé comme un jeton.
Authentification de requête
L'authentification de requête consiste à signer chaque demande RESTful via certains paramètres supplémentaires sur l'URI. Voir cet article de référence .
Il a été défini comme tel dans cet article:
Cette technique est peut-être la plus compatible avec une architecture sans état, et peut également être implémentée avec une gestion de session légère (en utilisant des sessions en mémoire au lieu de la persistance de la base de données).
Par exemple, voici un exemple d'URI générique à partir du lien ci-dessus:
doivent être transmis comme tels:
La chaîne en cours de signature est
/object?apikey=Qwerty2010×tamp=1261496500
et la signature est le hachage SHA256 de cette chaîne à l'aide du composant privé de la clé API.La mise en cache des données côté serveur peut être toujours disponible. Par exemple, dans notre framework, nous mettons en cache les réponses au niveau SQL, pas au niveau URI. L'ajout de ce paramètre supplémentaire ne rompt donc pas le mécanisme de cache.
Consultez cet article pour plus de détails sur l'authentification RESTful dans notre infrastructure client-serveur ORM / SOA / MVC, basée sur JSON et REST. Étant donné que nous autorisons la communication non seulement via HTTP / 1.1, mais également les canaux nommés ou les messages GDI (localement), nous avons essayé d'implémenter un modèle d'authentification véritablement RESTful, et de ne pas compter sur la spécificité HTTP (comme l'en-tête ou les cookies).
Remarque ultérieure : l'ajout d'une signature dans l'URI peut être considéré comme une mauvaise pratique (car, par exemple, elle apparaîtra dans les journaux du serveur http), elle doit donc être atténuée, par exemple par un TTL approprié pour éviter les relectures. Mais si vos journaux http sont compromis, vous aurez certainement de plus gros problèmes de sécurité.
Dans la pratique, la prochaine authentification des jetons MAC pour OAuth 2.0 pourrait être une énorme amélioration par rapport au schéma actuel "Accordé par jeton". Mais c'est toujours un travail en cours et est lié à la transmission HTTP.
Conclusion
Il convient de conclure que REST n'est pas uniquement basé sur HTTP, même si, dans la pratique, il est également principalement implémenté sur HTTP. REST peut utiliser d'autres couches de communication. Ainsi, une authentification RESTful n'est pas seulement synonyme d'authentification HTTP, quelles que soient les réponses de Google. Il ne doit même pas utiliser du tout le mécanisme HTTP mais doit être abstrait de la couche de communication. Et si vous utilisez la communication HTTP, grâce à l' initiative Let's Encrypt, il n'y a aucune raison de ne pas utiliser le HTTPS approprié, qui est requis en plus de tout schéma d'authentification.
la source
Cookie
un meilleur remplacement,HTTP Basic Auth
vous pouvez effectuer une authentification sans état avec une méthode pour expirer l'authentification et la possibilité de vous déconnecter. Un exemple d'implémentation pourrait utiliser un cookie appeléEmulated-HTTP-Basic-Auth
avec une valeur similaire à l'authentification HTTP de base réelle et en plus définir un délai d'expiration. La déconnexion peut ensuite être mise en œuvre en supprimant ce cookie. Je suppose que tout client capable de prendre en charge l'authentification de base HTTP peut également prendre en charge l'authentification par cookie effectuée de cette manière.Cookie
) peut être utilisée à la place.Je doute que les gens criant avec enthousiasme "Authentification HTTP" aient jamais essayé de créer une application basée sur un navigateur (au lieu d'un service Web de machine à machine) avec REST (aucune infraction prévue - je ne pense pas qu'ils aient jamais fait face aux complications) .
Les problèmes rencontrés avec l'utilisation de l'authentification HTTP sur les services RESTful qui produisent des pages HTML à afficher dans un navigateur sont les suivants:
Un article très perspicace qui aborde ces points par point est ici , mais il en résulte beaucoup de piratage javascript spécifique au navigateur, des solutions de contournement pour les solutions de contournement, et cetera. En tant que tel, il n'est pas non plus compatible en amont et nécessitera donc une maintenance constante à mesure que de nouveaux navigateurs seront lancés. Je ne considère pas ce design épuré et clair, et je pense que c'est beaucoup de travail supplémentaire et de maux de tête juste pour pouvoir montrer avec enthousiasme mon badge REST à mes amis.
Je pense que les cookies sont la solution. Mais attendez, les cookies sont mauvais, non? Non, ils ne le sont pas, la façon dont les cookies sont souvent utilisés est mauvaise. Un cookie lui-même n'est qu'un élément d'information côté client, tout comme les informations d'authentification HTTP dont le navigateur garderait la trace pendant votre navigation. Et cette information côté client est envoyée au serveur à chaque demande, à nouveau comme le seraient les informations d'authentification HTTP. Sur le plan conceptuel, la seule différence est que le contenu de cet élément d'état côté client peut être déterminé par le serveur dans le cadre de sa réponse.
En faisant des sessions une ressource RESTful avec juste les règles suivantes:
La seule différence avec l'authentification HTTP, maintenant, est que la clé d'authentification est générée par le serveur et envoyée au client qui continue de la renvoyer, au lieu que le client la calcule à partir des informations d'identification entrées.
converter42 ajoute que lors de l'utilisation de https (ce que nous devrions), il est important que le cookie ait son indicateur sécurisé défini afin que les informations d'authentification ne soient jamais envoyées via une connexion non sécurisée. Grand point, je ne l'avais pas vu moi-même.
Je pense que c'est une solution suffisante qui fonctionne bien, mais je dois admettre que je ne suis pas assez expert en sécurité pour identifier les trous potentiels dans ce schéma - tout ce que je sais, c'est que des centaines d'applications Web non RESTful utilisent essentiellement les mêmes protocole de connexion ($ _SESSION en PHP, HttpSession en Java EE, etc.). Le contenu de l'en-tête du cookie est simplement utilisé pour adresser une ressource côté serveur, tout comme une langue acceptée peut être utilisée pour accéder aux ressources de traduction, etc. Je sens que c'est pareil, mais peut-être que d'autres non? Que pensez-vous, les gars?
la source
On en dit déjà assez sur ce sujet par de bonnes personnes ici. Mais voici mes 2 cents.
Il existe 2 modes d'interaction:
La machine est le dénominateur commun, exprimé sous forme d'API REST, et les acteurs / clients étant soit les humains, soit les machines.
Maintenant, dans une architecture véritablement RESTful, le concept d'apatridie implique que tous les états d'application pertinents (c'est-à-dire les états côté client) doivent être fournis avec chaque demande. Par pertinent, cela signifie que tout ce qui est requis par l'API REST pour traiter la demande et servir une réponse appropriée.
Lorsque nous considérons cela dans le contexte des applications homme-machine, "basées sur un navigateur" comme le souligne Skrebbel ci-dessus, cela signifie que l'application (Web) exécutée dans le navigateur devra envoyer son état et les informations pertinentes à chaque demande. cela rend les API REST dorsales.
Considérez ceci: Vous disposez d'un atout exposé par la plateforme de données / informations des API REST. Vous disposez peut-être d'une plateforme de BI en libre-service qui gère tous les cubes de données. Mais vous voulez que vos clients (humains) y accèdent via (1) une application Web, (2) une application mobile et (3) une application tierce. En fin de compte, même une chaîne de MTM mène à HTM - à droite. Les utilisateurs humains restent donc au sommet de la chaîne d'information.
Dans les 2 premiers cas, vous avez un cas d'interaction homme-machine, les informations étant réellement consommées par un utilisateur humain. Dans le dernier cas, vous disposez d'un programme machine utilisant les API REST.
Le concept d'authentification s'applique à tous les niveaux. Comment allez-vous concevoir cela pour que vos API REST soient accessibles de manière uniforme et sécurisée? La façon dont je vois cela, il y a 2 façons:
Voie 1:
Voie 2:
De toute évidence, dans Way-2, les API REST auront besoin d'un moyen de reconnaître et d'approuver le jeton comme valide. L'API de connexion a effectué la vérification d'authentification et, par conséquent, cette "clé de valet" doit être approuvée par d'autres API REST de votre catalogue.
Cela signifie bien sûr que la clé / le jeton d'authentification devra être stocké et partagé entre les API REST. Ce référentiel de jetons partagé et approuvé peut être local / fédéré, ce qui permet aux API REST d'autres organisations de se faire mutuellement confiance.
Mais je m'égare.
Le fait est qu'un "état" (concernant l'état authentifié du client) doit être maintenu et partagé afin que toutes les API REST puissent créer un cercle de confiance. Si nous ne le faisons pas, ce qui est la voie 1, nous devons accepter qu'un acte d'authentification doit être effectué pour toutes les demandes qui arrivent.
L'authentification est un processus gourmand en ressources. Imaginez exécuter des requêtes SQL, pour chaque demande entrante, sur votre magasin d'utilisateurs pour vérifier la correspondance uid / pwd. Ou, pour crypter et effectuer des correspondances de hachage (le style AWS). Et sur le plan architectural, chaque API REST devra effectuer cela, je suppose, en utilisant un service de connexion principal commun. Parce que, si vous ne le faites pas, vous jetez le code d'authentification partout. Un gros désordre.
Donc plus de couches, plus de latence.
Maintenant, prenez Way-1 et postulez à HTM. Votre utilisateur (humain) se soucie-t-il vraiment si vous devez envoyer uid / pwd / hash ou autre chose à chaque demande? Non, tant que vous ne la dérangez pas en lançant la page d'authentification / connexion à chaque seconde. Bonne chance d'avoir des clients si vous le faites. Donc, ce que vous allez faire est de stocker les informations de connexion quelque part côté client, dans le navigateur, dès le début, et de les envoyer avec chaque demande. Pour l'utilisateur (humain), elle s'est déjà connectée et une "session" est disponible. Mais en réalité, elle est authentifiée à chaque demande.
Même chose avec Way-2. Votre utilisateur (humain) ne le remarquera jamais. Aucun mal n'a donc été fait.
Et si nous appliquons Way-1 à MTM? Dans ce cas, puisque c'est une machine, nous pouvons supporter l'enfer de ce type en lui demandant de soumettre des informations d'authentification à chaque demande. Tout le monde s'en fout! L'exécution de Way-2 sur MTM ne provoquera aucune réaction particulière; c'est une putain de machine. Il s'en foutait moins!
Alors vraiment, la question est de savoir ce qui convient à votre besoin. L'apatridie a un prix à payer. Payez le prix et continuez. Si vous voulez être un puriste, alors payez le prix aussi et continuez.
En fin de compte, les philosophies n'ont pas d'importance. Ce qui compte vraiment, c'est la découverte, la présentation et l'expérience de consommation de l'information. Si les gens aiment vos API, vous avez fait votre travail.
la source
Way-3
, l'approche hybride. Le client se connecte comme dansWay-2
mais, comme dansWay-1
, les informations d'identification ne sont vérifiées par rapport à aucun état côté serveur. Quoi qu'il en soit, un jeton d'authentification est créé et renvoyé au client comme dansWay-2
. L'authenticité de ce jeton est vérifiée ultérieurement à l'aide d'une cryptographie asymétrique sans rechercher aucun état spécifique au client.Voici une solution d'authentification véritablement et complètement RESTful:
Lorsqu'un client s'authentifie:
3.1. émettez un jeton qui contient les éléments suivants:
3.2. Chiffrez le jeton avec la clé privée.
3.3. Renvoyez le jeton chiffré à l'utilisateur.
Lorsque l'utilisateur accède à une API, il doit également transmettre son jeton d'authentification.
Il s'agit d'une authentification sans état / RESTful.
Notez que si un hachage de mot de passe était inclus, l'utilisateur enverrait également le mot de passe non chiffré avec le jeton d'authentification. Le serveur a pu vérifier que le mot de passe correspondait au mot de passe utilisé pour créer le jeton d'authentification en comparant les hachages. Une connexion sécurisée utilisant quelque chose comme HTTPS serait nécessaire. Javascript côté client peut gérer l'obtention du mot de passe de l'utilisateur et son stockage côté client, soit en mémoire, soit dans un cookie, éventuellement chiffré avec la clé publique du serveur .
la source
Pour être honnête avec vous, j'ai vu de grandes réponses ici, mais quelque chose qui me dérange un peu, c'est quand quelqu'un va pousser le concept de l'apatridie à l'extrême où il devient dogmatique. Cela me rappelle ces anciens fans de Smalltalk qui voulaient seulement adopter OO pur et si quelque chose n'est pas un objet, alors vous le faites mal. Laisse-moi tranquille.
L'approche RESTful est censée vous faciliter la vie et réduire les frais généraux et le coût des sessions, essayez de la suivre car c'est une chose sage à faire, mais la minute où vous suivez une discipline (n'importe quelle discipline / directive) à l'extrême où elle n'offre plus l'avantage auquel il était destiné, alors vous le faites mal. Certains des meilleurs langages d'aujourd'hui ont à la fois une programmation fonctionnelle et une orientation objet.
Si la façon la plus simple de résoudre votre problème est de stocker la clé d'authentification dans un cookie et de l'envoyer sur l'en-tête HTTP, faites-le, mais n'en abusez pas. N'oubliez pas que les sessions sont mauvaises lorsqu'elles deviennent lourdes et grandes, si toute votre session est constituée d'une courte chaîne contenant une clé, alors quel est le problème?
Je suis ouvert à accepter des corrections dans les commentaires, mais je ne vois pas l'intérêt (jusqu'à présent) de rendre nos vies misérables pour simplement éviter de garder un gros dictionnaire de hachages sur notre serveur.
la source
D'abord et avant tout, un service Web RESTful est STATELESS (ou en d'autres termes, SESSIONLESS). Par conséquent, un service RESTful n'a pas et ne devrait pas avoir de concept de session ou de cookies impliqué. La méthode d'authentification ou d'autorisation dans le service RESTful consiste à utiliser l'en-tête d'autorisation HTTP tel que défini dans les spécifications HTTP RFC 2616. Chaque demande unique doit contenir l'en-tête d'autorisation HTTP et la demande doit être envoyée via une connexion HTTP (SSL). C'est la bonne façon de procéder à l'authentification et de vérifier l'autorisation des demandes dans un service Web HTTP RESTful. J'ai implémenté un service Web RESTful pour l'application Cisco PRIME Performance Manager chez Cisco Systems. Et dans le cadre de ce service Web, j'ai également implémenté l'authentification / l'autorisation.
la source
Il ne s'agit certainement pas de "clés de session" car elles sont généralement utilisées pour faire référence à une authentification sans session qui est effectuée dans toutes les contraintes de REST. Chaque demande est auto-descriptive et contient suffisamment d'informations pour autoriser la demande seule sans aucun état d'application côté serveur.
La façon la plus simple d'aborder cela est de commencer par les mécanismes d'authentification intégrés de HTTP dans RFC 2617 .
la source
L'article «très perspicace» mentionné par @skrebel ( http://www.berenddeboer.net/rest/authentication.html ) traite d'une méthode d'authentification compliquée mais vraiment cassée.
Vous pouvez essayer de visiter la page (qui est censée être visible uniquement pour l'utilisateur authentifié) http://www.berenddeboer.net/rest/site/authenticated.html sans aucun identifiant de connexion.
(Désolé, je ne peux pas commenter la réponse.)
Je dirais que REST et l'authentification ne se mélangent tout simplement pas. REST signifie apatride mais «authentifié» est un état. Vous ne pouvez pas les avoir tous les deux sur le même calque. Si vous êtes un défenseur RESTful et froncez les sourcils sur les États, alors vous devez opter pour HTTPS (c'est-à-dire laisser le problème de sécurité à une autre couche).
la source
Je pense que l'authentification reposante implique le passage d'un jeton d'authentification comme paramètre dans la demande. Des exemples sont l'utilisation des apikeys par les api. Je ne pense pas que l'utilisation de cookies ou d'authentification http soit admissible.
la source
Mise à jour du 16 février 2019
L'approche mentionnée ci-dessous est essentiellement le type d'octroi "Resource Owner Password Credential" de OAuth2.0 . C'est un moyen facile de se mettre en marche. Cependant, avec cette approche, chaque application de l'organisation se retrouvera avec ses propres mécanismes d'authentification et d'autorisation. L'approche recommandée est le type de subvention "Code d'autorisation". De plus, dans ma réponse précédente ci-dessous, j'ai recommandé le navigateur localStorage pour stocker les jetons d'authentification. Cependant, j'en suis venu à croire que le cookie est la bonne option à cet effet. J'ai détaillé mes raisons, l'approche de mise en œuvre du type d'octroi de code d'autorisation, les considérations de sécurité, etc. dans cette réponse StackOverflow .
Je pense que l'approche suivante peut être utilisée pour l'authentification du service REST:
Avec cette approche, nous effectuons l'opération coûteuse de chargement du cache avec des détails de droits d'accès spécifiques à l'utilisateur toutes les 30 minutes. Donc, si un accès est révoqué ou qu'un nouvel accès est accordé, il faut 30 minutes pour réfléchir ou une déconnexion suivie d'une connexion.
la source
C'est la façon de procéder: utiliser OAuth 2.0 pour la connexion .
Vous pouvez utiliser d'autres méthodes d'authentification que celle de Google tant qu'elle prend en charge OAuth.
la source
L'utilisation d'une infrastructure de clé publique dans laquelle l'enregistrement d'une clé implique une liaison appropriée garantit que la clé publique est liée à la personne à laquelle elle est affectée de manière à garantir la non-répudiation
Voir http://en.wikipedia.org/wiki/Public_key_infrastructure . Si vous suivez les normes PKI appropriées, la personne ou l'agent qui utilise incorrectement la clé volée peut être identifié et verrouillé. Si l'agent doit utiliser un certificat, la liaison devient assez serrée. Un voleur intelligent et rapide peut s'échapper, mais ils laissent plus de miettes.
la source
Pour répondre à cette question de ma compréhension ...
Un système d'authentification qui utilise REST afin que vous n'ayez pas besoin de suivre ou de gérer réellement les utilisateurs de votre système. Cela se fait en utilisant les méthodes HTTP POST, GET, PUT, DELETE. Nous prenons ces 4 méthodes et les considérons en termes d'interaction avec la base de données comme CREATE, READ, UPDATE, DELETE (mais sur le Web, nous utilisons POST et GET car c'est ce que les balises d'ancrage prennent actuellement en charge). Ainsi, en traitant POST et GET comme notre CRÉER / LIRE / METTRE À JOUR / SUPPRIMER (CRUD), nous pouvons concevoir des itinéraires dans notre application Web qui seront en mesure de déduire quelle action de CRUD nous réalisons.
Par exemple, dans une application Ruby on Rails, nous pouvons créer notre application Web de telle sorte que si un utilisateur qui est connecté visite http://store.com/account/logout, le GET de cette page peut être vu comme l'utilisateur tentant de se déconnecter . Dans notre contrôleur de rails, nous construisons une action qui déconnecte l'utilisateur et le renvoie à la page d'accueil.
Un GET sur la page de connexion donnerait un formulaire. un POST sur la page de connexion serait considéré comme une tentative de connexion et prendrait les données POST et les utiliserait pour se connecter.
Pour moi, c'est une pratique d'utiliser des méthodes HTTP mappées à leur signification de base de données, puis de créer un système d'authentification en gardant à l'esprit que vous n'avez pas besoin de passer autour d'un identifiant de session ou de suivre des sessions.
J'apprends toujours - si vous trouvez quelque chose que j'ai dit de mal, corrigez-moi, et si vous en savez plus, postez-le ici. Merci.
la source
Conseils valides pour sécuriser n'importe quelle application Web
Si vous souhaitez sécuriser votre application, vous devez certainement commencer par utiliser HTTPS au lieu de HTTP , cela garantit une création de canal sécurisé entre vous et les utilisateurs qui empêchera de renifler les données envoyées d'avant en arrière aux utilisateurs et aidera à conserver les données échangé confidentiel.
Vous pouvez utiliser des JWT (JSON Web Tokens) pour sécuriser les API RESTful , cela présente de nombreux avantages par rapport aux sessions côté serveur, les avantages sont principalement:
1- Plus évolutif, car vos serveurs API n'auront pas à maintenir de sessions pour chaque utilisateur (ce qui peut être un gros fardeau lorsque vous avez plusieurs sessions)
2- Les JWT sont autonomes et ont les revendications qui définissent le rôle d'utilisateur par exemple et ce à quoi il peut accéder et émis à la date et à la date d'expiration (après quoi le JWT ne sera pas valide)
3- Plus facile à gérer entre les équilibreurs de charge et si vous avez plusieurs serveurs API car vous n'aurez pas à partager les données de session ni à configurer le serveur pour acheminer la session vers le même serveur, chaque fois qu'une demande avec un JWT frappe n'importe quel serveur, elle peut être authentifiée & autorisé
4- Moins de pression sur votre base de données et vous n'aurez pas à stocker et récupérer en permanence l'identifiant et les données de session pour chaque demande
5- Les JWT ne peuvent pas être falsifiés si vous utilisez une clé forte pour signer le JWT, vous pouvez donc faire confiance aux réclamations dans le JWT envoyé avec la demande sans avoir à vérifier la session utilisateur et s'il est autorisé ou non , vous pouvez simplement vérifier le JWT et vous êtes prêt à savoir qui et ce que cet utilisateur peut faire.
De nombreuses bibliothèques offrent des moyens simples de créer et de valider des JWT dans la plupart des langages de programmation, par exemple: dans node.js, l'un des plus populaires est jsonwebtoken
Étant donné que les API REST visent généralement à garder le serveur sans état, les JWT sont plus compatibles avec ce concept car chaque demande est envoyée avec un jeton d'autorisation qui est autonome (JWT) sans que le serveur doive garder une trace de la session utilisateur par rapport aux sessions qui font le serveur avec état pour qu'il se souvienne de l'utilisateur et de son rôle, cependant, les sessions sont également largement utilisées et ont leurs avantages, que vous pouvez rechercher si vous le souhaitez.
Une chose importante à noter est que vous devez livrer le JWT en toute sécurité au client en utilisant HTTPS et l'enregistrer dans un endroit sûr (par exemple dans le stockage local).
Vous pouvez en savoir plus sur les JWT à partir de ce lien
la source