31 votes

Authentification par WebSockets

Quels sont les moyens possibles d'authentifier l'utilisateur lorsque la connexion websocket est utilisée ?

Exemple de scénario : Application de chat multi-utilisateurs basée sur le Web via une connexion Websocket cryptée. Comment puis-je m'assurer (ou garantir) que chaque connexion dans cette application appartient à un certain utilisateur authentifié et ne peut pas être exploitée par une fausse usurpation d'identité pendant la connexion.

44voto

Derek Dahmer Points 2700

Si vous procédez déjà à l'authentification pour la partie non websocket de votre application, transmettez simplement le cookie de session comme premier message après la connexion et vérifiez le cookie comme vous le feriez normalement.

AVERTISSEMENT : Il a été signalé que ce qui suit ne fonctionne pas lorsque des douilles flash sont utilisées :
Si vous utilisez socket.io Si vous avez besoin de plus d'informations, c'est encore plus facile : les cookies sont transmis automatiquement lors de la connexion et vous pouvez y accéder de la manière suivante :

var io = require('socket.io');
var socket = io.listen(app); 
socket.on('connection', function(client){ 
    cookies = client.headers['cookie'];
});

4 votes

Etes-vous sûr que cela fonctionne toujours ? Si Socket.IO se rabat sur les sockets Flash, par exemple, les cookies du navigateur ne seront pas (AFAIK) envoyés.

1 votes

Thomas, tu as raison, il y a un sujet traité qui mentionne que vous devriez plutôt faire l'authentification via le premier message.

1 votes

C'est une méthode pratique, mais elle exige que la page Web qui effectue la connexion (et le paramétrage du cookie) provienne de la même origine que le WebSocket, car sinon le cookie (paramétré à partir de la page de connexion) ne sera pas envoyé sur la connexion WebSocket.

3voto

Rook Points 34698

SSL/TLS peut être utilisé pour authentifier le client et le serveur à l'aide de certificats X.509. Cela dépend de la plateforme d'application web que vous utilisez. Dans Apache, le certificat SSL_CLIENT_CERT variable d'environnement peut être vérifié par rapport à une liste de certificats connus pour être valides. Cela ne nécessite pas l'utilisation d'une ICP complète et ne vous oblige pas à acheter des certificats pour chaque client. Bien que je recommande d'utiliser une autorité de certification pour sauvegarder le certificat SSL de votre serveur.

0 votes

Vous voulez dire que le certificat SSL sera utilisé pour les connexions HTTP et WebSocket respectivement ?

0 votes

Je ne suis pas d'accord avec ce que rook a dit. SSL/TLS peut garantir que les données ne sont pas modifiées dans la couche transport. Mais le problème ici est que comment pouvons-nous savoir que la demande de socket web provient de l'utilisateur A et non de l'utilisateur B ? Image : les utilisateurs A et B sont tous deux connectés. Comme le web-socket n'envoie pas de cookie après que la connexion soit établie. Donc, plus tard, comment ce web-socket assure-t-il que la demande provient du véritable utilisateur A plutôt que de l'utilisateur B ?

1voto

kag0 Points 374

Il y a deux façons de procéder.

L'un des moyens consiste à permettre à quiconque d'ouvrir une connexion websocket. Demandez au client d'envoyer un jeton d'autorisation comme premier message après l'ouverture de la connexion. Si le client n'envoie pas un jeton valide dans un certain délai, fermez la connexion.

Une autre solution consiste à utiliser des cookies (ils sont envoyés automatiquement par le navigateur à chaque demande). Cela nécessite de mettre en place une protection CSRF (encore plus que la normale, car il n'existe pas de politique de même origine (SOP) pour les websockets. Vous pouvez trouver des détails ici . Le plan est le suivant :

  1. faire une requête "websocket preauth" vers le backend depuis js en utilisant l'authentification normale du site
  2. renvoie un jeton CSRF dans le corps de la réponse et définit un cookie "websocket auth" avec SameSite=Strict dans les en-têtes de la réponse
  3. tentative d'établir une connexion websocket avec le backend, avec l'ajout du jeton CSRF dans un paramètre de requête
  4. le backend vérifie
    • que le cookie d'authentification websocket et le jeton CSRF sont valides.
    • que la valeur de la Origin correspond à un domaine approuvé
  5. le backend envoie une réponse et met à niveau la connexion pour utiliser des websockets

La première méthode est plus simple, mais elle présente l'inconvénient d'exiger que vous ayez un certain état côté serveur en attendant que le client s'authentifie. Cela peut permettre à un attaquant de réaliser une attaque par déni de service en consommant toutes les sockets disponibles.

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