web-dev-qa-db-fra.com

Comment faire une authentification sans état (sans session) et sans cookie?

Bob utilise une application Web pour réaliser quelque chose. Et:

  • Son navigateur est en régime, il ne supporte donc pas cookies.
  • L’application Web est populaire, elle s’adresse à un grand nombre d’utilisateurs à un moment donné - elle doit bien évoluer . Tant que maintenir la session imposerait ne limite au nombre de connexions simultanées, et, bien sûr, apportera une non-négligeable pénalité de performance, nous pourrions souhaiter avoir un système sans session :)

Quelques notes importantes:

  • nous avons sécurité du transport ( [~ # ~] https [~ # ~] et ses meilleurs amis);
  • derrière les rideaux, l'application Web délègue de nombreuses opérations à services externes, à l'actuel nom de l'utilisateur (ces systèmes reconnaissent Bob comme l'un de leurs utilisateurs) - cela signifie que nous devons leur transmettre les références de Bob.

Maintenant, comment authentifions-nous Bob (à chaque requête)? Quel serait un moyen raisonnable de mettre en œuvre une telle chose?

  • jouer au tennis avec les identifiants via champs masqués du formulaire HTML ... le ballon contient les informations d'identification (nom d'utilisateur et mot de passe) et les deux raquettes sont le navigateur et le application Web, respectivement. En d'autres termes, nous pouvons transporter des données dans les deux sens via des champs de formulaire plutôt que via des cookies. À chaque demande Web, le navigateur publie les informations d'identification. Bien que, dans le cas d'une application d'une seule page, cela peut ressembler à jouer squash contre un mur en caoutchouc, au lieu de en jouant au tennis , car le formulaire Web contenant les informations d'identification peut rester en vie toute la durée de vie de la page Web (et le serveur sera configuré pour ne pas restituer les informations d'identification).
  • stocker le nom d'utilisateur et le mot de passe dans le contexte de la page - variables JavaScript, etc. Une seule page est requise ici, à mon humble avis.
  • authentification par jeton crypté. Dans ce cas, l'action de connexion entraînerait la génération d'un jeton de sécurité crypté (nom d'utilisateur + mot de passe + quelque chose d'autre). Ce jeton sera retourné au client et les demandes à venir seront accompagnés du jeton. Est-ce que ça a du sens? Nous avons déjà HTTPS ...
  • autres...
  • dernier recours: ne le faites pas, stockez les identifiants dans la session! La session est bonne. Avec ou sans cookies.

Avez-vous des préoccupations en matière de sécurité/Web à propos des idées précédemment décrites? Par exemple,

  • expiration du temps - nous pouvons conserver un horodatage, avec les informations d'identification (horodatage = l'heure à laquelle Bob a entré ses informations d'identification) ). Par exemple. when NOW - timestamp> threshold, nous pourrions refuser la demande.
  • La protection des scripts entre sites - ne devrait en aucun cas être différente, n'est-ce pas?

Merci beaucoup d'avoir pris le temps de lire ceci :)

105
turdus-merula

Ah, j'adore ces questions - maintenir une session sans session.

J'ai vu plusieurs façons de le faire pendant mes périodes d'évaluation des applications. L’un des moyens les plus populaires est le moyen jouer au tennis que vous avez mentionné - l’envoi du nom d’utilisateur et du mot de passe dans chaque demande d’authentification de l’utilisateur. Ceci, à mon avis, est dangereux, surtout si l'application n'est pas une page unique. Il n’est pas non plus évolutif, en particulier si vous souhaitez ajouter une autorisation à votre application en plus de l’authentification à l’avenir (bien que je suppose que vous puissiez également créer quelque chose basé sur les connexions).

Un mécanisme populaire, bien que pas complètement sans état (en supposant que vous ayez une exécution JavaScript), consiste à incorporer le cookie de session dans JavaScript. Le responsable de la sécurité en moi hurle dessus, mais cela pourrait fonctionner - chaque demande a un X-Authentication-Token en-tête ou quelque chose comme ça, et vous mappez cela vers une base de données, un magasin de fichiers en mémoire, etc. sur le backend pour valider l'utilisateur. Ce jeton peut avoir un délai d'expiration de l'heure que vous avez spécifiée, et s'il expire, l'utilisateur doit se reconnecter. Il est assez évolutif - si vous le stockez dans une base de données, si sa seule instruction SQL est exécutée et si les index sont corrects, son exécution ne devrait prendre que très peu de temps, même avec plusieurs utilisateurs simultanés. Des tests de charge ici seraient certainement utiles. Si je lis correctement la question, il s’agira de votre mécanisme de jeton crypté - bien que je vous suggère fortement d’utiliser un jeton cryptographiquement aléatoire de 32 caractères, par opposition à une combinaison de nom d’utilisateur + mot de passe + quoi que ce soit d'autre. imprévisible, mais vous pouvez toujours l'associer à l'ID utilisateur ou à un autre.

Quel que soit le produit que vous utilisez, assurez-vous qu'il vous soit envoyé en toute sécurité. HTTPS vous protège de bout en bout, mais il ne vous protège pas si vous divulguez le jeton de session via l'URL (ou pire, les informations d'identification via l'URL). Je recommanderais d'utiliser un en-tête ou, si ce n'est pas faisable, d'envoyer le jeton via une demande POST à chaque fois (cela signifierait un champ de formulaire caché sur le navigateur de l'utilisateur).) Une demande POST devrait utiliser les défenses CSRF, juste au cas où, bien que je soupçonne que le jeton lui-même pourrait être une sorte de défense CSRF.

Dernier point, mais non le moindre, assurez-vous de disposer d'un mécanisme dans le backend pour purger les jetons expirés. Cela a été le fléau de nombreuses applications dans le passé - une base de données en croissance rapide de jetons d'authentification qui semble ne jamais disparaître. Si vous devez prendre en charge plusieurs connexions, veillez à limiter le nombre ou à limiter la durée de chaque jeton. Comme je l'ai dit précédemment, le test de charge peut être la solution.

Il y a d'autres problèmes de sécurité auxquels je peux penser, mais ils sont trop généraux pour être traités à ce stade - si vous gardez à l'esprit tous les cas d'utilisation (et d'abus), vous devriez probablement pouvoir faire une assez bonne mise en œuvre de. ce système.

73
Karthik Rangarajan

À propos de l'option de connexion - Je pense que vous souhaitez généralement que les sessions soient également prises en charge pour les invités.

Donc, si vous voulez imposer la connexion, l'option de jeton crypté peut être bonne. Cela pourrait être bon aussi pour une session invité. Dans un autre sens, je combinerais l’ajout du jeton à l’URL et de l’option tennis.

Notez que l'envoi d'informations d'identification uniquement dans l'URL peut être dangereux. Par exemple, vous pouvez perdre le jeton via l'en-tête du référent HTTP ou même par quelqu'un qui inspecte simplement votre trafic ou surveille votre ordinateur.

Autre chose, même si vous pouviez utiliser des cookies, je vous recommanderais d’ajouter un jeton aléatoire ou un vérificateur aléatoire, afin de vous protéger des attaques de type CSRF (Cross Site Request Forgery).

1
Gari BN