Je conçois un service Web RESTful auquel les utilisateurs doivent avoir accès, mais également d'autres services et applications Web. Toutes les demandes entrantes doivent être authentifiées. Toutes les communications ont lieu via HTTPS. L'authentification de l'utilisateur fonctionnera sur la base d'un jeton d'authentification, acquis en POSTANT le nom d'utilisateur et le mot de passe (via une connexion SSL) à une ressource / session fournie par le service.
Dans le cas des clients de service Web, il n'y a aucun utilisateur final derrière le service client. Les demandes sont initiées par des tâches planifiées, des événements ou d'autres opérations informatiques. La liste des services de connexion est connue à l'avance (évidemment, je suppose). Comment dois-je authentifier ces demandes provenant d'autres services (Web)? Je souhaite que le processus d'authentification soit aussi simple que possible à mettre en œuvre pour ces services, mais pas au détriment de la sécurité. Quelles seraient les normes et les meilleures pratiques pour un scénario comme celui-ci?
Options auxquelles je peux penser (ou qui m'ont été suggérées):
Demandez aux services clients de recourir à un «faux» nom d'utilisateur et mot de passe, et de les authentifier de la même manière que les utilisateurs. Je n'aime pas cette option - ça ne me semble pas juste.
Attribuez un identifiant d'application permanent pour le service client, éventuellement une clé d'application. Autant que j'ai compris, c'est la même chose que d'avoir un nom d'utilisateur + un mot de passe. Avec cet identifiant et cette clé, je peux soit authentifier chaque demande, soit créer un jeton d'authentification pour authentifier d'autres demandes. Quoi qu'il en soit, je n'aime pas cette option, car toute personne qui peut obtenir l'identifiant et la clé de l'application peut se faire passer pour le client.
Je pourrais ajouter une vérification d'adresse IP à l'option précédente. Cela rendrait plus difficile d'effectuer de fausses demandes.
Certificats clients. Configurez ma propre autorité de certification, créez un certificat racine et créez des certificats clients pour les services clients. Cependant, quelques problèmes me viennent à l'esprit: a) comment puis-je encore permettre aux utilisateurs de s'authentifier sans certificats et b) à quel point ce scénario est-il compliqué à mettre en œuvre du point de vue du service client?
Quelque chose d'autre - il doit y avoir d'autres solutions là-bas?
Mon service fonctionnerait sur Java, mais j'ai délibérément omis des informations sur le cadre spécifique sur lequel il serait construit, car je suis plus intéressé par les principes de base et pas tant par les détails de mise en œuvre - je suppose que la meilleure solution pour cela sera être possible de mettre en œuvre quel que soit le cadre sous-jacent. Cependant, je suis un peu inexpérimenté avec ce sujet, donc des conseils et des exemples concrets sur la mise en œuvre réelle (tels que des bibliothèques tierces utiles, des articles, etc.) seront également très appréciés.
Réponses:
Toute solution à ce problème se résume à un secret partagé. Je n'aime pas non plus l'option de nom d'utilisateur et de mot de passe codés en dur, mais elle a l'avantage d'être assez simple. Le certificat client est également bon, mais est-il vraiment très différent? Il y a un certificat sur le serveur et un sur le client. Son principal avantage est qu'il est plus difficile de recourir à la force brute. J'espère que vous avez mis en place d'autres protections pour vous protéger contre cela.
Je ne pense pas que votre point A pour la solution de certificat client soit difficile à résoudre. Vous utilisez juste une branche.
if (client side certificat) { check it } else { http basic auth }
Je ne suis pas un expert Java et je n'ai jamais travaillé avec lui pour créer des certificats côté client. Cependant, un rapide Google nous conduit à ce tutoriel qui regarde droit dans votre allée.Malgré toute cette discussion sur «ce qu'il y a de mieux», permettez-moi de souligner qu'il existe une autre philosophie qui dit: «moins de code, moins d'intelligence, c'est mieux». (Je détiens personnellement cette philosophie). La solution de certificat client ressemble à beaucoup de code.
Je sais que vous avez exprimé des questions sur OAuth, mais la proposition OAuth2 inclut une solution à votre problème appelée « jetons de support » qui doit être utilisée en conjonction avec SSL. Je pense que, par souci de simplicité, je choisirais soit l'utilisateur / pass codé en dur (un par application afin qu'ils puissent être révoqués individuellement), soit les jetons de support très similaires.
la source
Après avoir lu votre question, je dirais, générez un jeton spécial pour faire la demande requise. Ce jeton vivra à un moment précis (disons en un jour).
Voici un exemple de pour générer un jeton d'authentification:
par exemple: 3 juin 2011
puis concaténer avec le mot de passe de l'utilisateur, par exemple "my4wesomeP4ssword!"
Puis faites MD5 de cette chaîne:
Quand appelez-vous une demande, utilisez toujours ce jeton,
Ce jeton est toujours unique au quotidien, donc je suppose que ce type de protection est plus que suffisant pour toujours protéger votre service.
L'espoir aide
:)
la source
Il existe plusieurs approches différentes.
Les puristes RESTful voudront que vous utilisiez l'authentification BASIC et que vous envoyiez des informations d'identification à chaque demande. Leur raisonnement est que personne ne stocke aucun état.
Le service client peut stocker un cookie, qui conserve un identifiant de session. Personnellement, je ne trouve pas cela aussi offensant que certains des puristes que j'entends - cela peut coûter cher de s'authentifier encore et encore. Il semble que vous n'aimiez pas trop cette idée, cependant.
D'après votre description, il semble vraiment que vous soyez intéressé par OAuth2. Mon expérience jusqu'à présent, d'après ce que j'ai vu, c'est que c'est un peu déroutant et un peu avant-gardiste. Il existe des implémentations, mais elles sont rares. En Java, je comprends qu'il a été intégré dans les modules de sécurité de Spring3 . (Leur tutoriel est bien écrit.) J'attendais de voir s'il y aurait une extension dans Restlet , mais jusqu'à présent, bien que cela ait été proposé, et peut-être dans l'incubateur, il n'a toujours pas été complètement intégré.
la source
Je crois que l'approche:
est assez standard, indépendamment de la façon dont vous implémentez et d'autres détails techniques spécifiques.
Si vous voulez vraiment pousser l'enveloppe, vous pourriez peut-être considérer la clé https du client dans un état temporairement invalide jusqu'à ce que les informations d'identification soient validées, limiter les informations si elles ne le sont jamais et accorder l'accès lorsqu'elles sont validées, en fonction à nouveau de l'expiration.
J'espère que cela t'aides
la source
En ce qui concerne l'approche du certificat client, elle ne serait pas terriblement difficile à implémenter tout en permettant aux utilisateurs sans certificats client d'entrer.
Si vous créiez en fait votre propre autorité de certification auto-signée et que vous délivriez des certificats client à chaque service client, vous disposeriez d'un moyen simple d'authentifier ces services.
Selon le serveur Web que vous utilisez, il devrait y avoir une méthode pour spécifier l'authentification client qui acceptera un certificat client, mais qui n'en exigera pas. Par exemple, dans Tomcat, lorsque vous spécifiez votre connecteur https, vous pouvez définir «clientAuth = want» au lieu de «true» ou «false». Vous vous assureriez alors d'ajouter votre certificat CA auto-signé à votre truststore (par défaut, le fichier cacerts dans le JRE que vous utilisez, à moins que vous n'ayez spécifié un autre fichier dans la configuration de votre serveur Web), de sorte que les seuls certificats de confiance seraient ceux émis hors de votre autorité de certification auto-signée.
Côté serveur, vous n'autorisez l'accès aux services que vous souhaitez protéger que si vous êtes en mesure de récupérer un certificat client à partir de la demande (non nul), et réussissez les vérifications de DN si vous préférez une sécurité supplémentaire. Pour les utilisateurs sans certificat client, ils pourront toujours accéder à vos services, mais n'auront simplement aucun certificat présent dans la demande.
À mon avis, c'est le moyen le plus «sûr», mais il a certainement sa courbe d'apprentissage et ses frais généraux, ce n'est donc pas nécessairement la meilleure solution pour vos besoins.
la source
5. Autre chose - il doit y avoir d'autres solutions là-bas?
Vous avez raison, il y en a! Et cela s'appelle JWT (JSON Web Tokens).
JSON Web Token (JWT) est une norme ouverte (RFC 7519) qui définit un moyen compact et autonome de transmettre en toute sécurité des informations entre les parties en tant qu'objet JSON. Ces informations peuvent être vérifiées et fiables car elles sont signées numériquement. Les JWT peuvent être signés à l'aide d'un secret (avec l'algorithme HMAC) ou d'une paire de clés publique / privée à l'aide de RSA.
Je recommande vivement d'examiner les JWT. Ils constituent une solution beaucoup plus simple au problème par rapport aux solutions alternatives.
https://jwt.io/introduction/
la source
Vous pouvez créer une session sur le serveur et la partager
sessionId
entre le client et le serveur à chaque appel REST.Première Authentifier demande REST:
/authenticate
. Renvoie la réponse (selon le format de votre client) avecsessionId: ABCDXXXXXXXXXXXXXX
;Conservez ce
sessionId
enMap
avec la session actuelle.Map.put(sessionid, session)
ou utiliserSessionListener
pour créer et détruire des clés pour vous;Obtenez sessionid avec chaque appel REST, comme
URL?jsessionid=ABCDXXXXXXXXXXXXXX
(ou d'une autre manière);HttpSession
de la carte en utilisantsessionId
;la source
J'utiliserais pour qu'une application redirige un utilisateur vers votre site avec un paramètre d'ID d'application, une fois que l'utilisateur approuve la demande, génère un jeton unique qui est utilisé par l'autre application pour l'authentification. De cette façon, les autres applications ne gèrent pas les informations d'identification des utilisateurs et d'autres applications peuvent être ajoutées, supprimées et gérées par les utilisateurs. Foursquare et quelques autres sites s'authentifient de cette manière et c'est très facile à mettre en œuvre comme l'autre application.
la source
Outre l'authentification, je vous suggère de réfléchir à la situation dans son ensemble. Pensez à rendre votre service RESTful backend sans aucune authentification; puis placez un service de couche intermédiaire très simple d'authentification requise entre l'utilisateur final et le service backend.
la source