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

107

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

  • Son navigateur est au régime, il ne prend donc pas en charge les cookies .
  • L'application Web est populaire, elle traite de nombreux utilisateurs à un moment donné - elle doit bien évoluer . Tant que le maintien de la session imposerait une limite au nombre de connexions simultanées et, bien sûr, entraînerait une pénalité de performances non négligeable , nous pourrions souhaiter avoir un système sans session :)

Quelques remarques importantes:

  • nous avons la sécurité des transports ( HTTPS et ses meilleurs amis);
  • derrière les rideaux, l'application Web délègue de nombreuses opérations à des services externes , au nom de l' utilisateur actuel (ces systèmes reconnaissent Bob comme l'un de leurs utilisateurs) - cela signifie que nous devons leur transmettre les informations d'identification de Bob .

Maintenant, comment authentifier Bob (sur chaque demande)? Quelle serait une manière raisonnable de mettre en œuvre une telle chose?

  • jouer au tennis avec les informations d'identification via les champs masqués du formulaire HTML ... la balle contient les informations d'identification ( nom d'utilisateur et mot de passe ) et les deux raquettes sont respectivement le navigateur et l'application Web. 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. Cependant, dans le cas d'une application d'une seule page , cela peut ressembler à jouer au squash contre un mur en caoutchouc, au lieu de jouer au tennis , car le formulaire Web contenant les informations d'identification peut être conservé pendant toute la durée de vie de la page Web. (et le serveur sera configuré pour ne pas offrir 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 requise ici, à mon humble avis.
  • authentification cryptée basée sur des jetons. Dans ce cas, l'action de connexion entraînerait la génération d'un jeton de sécurité chiffré (nom d'utilisateur + mot de passe + autre chose). Ce jeton sera servi au client et les demandes à venir seront accompagnées du jeton. Est-ce que ça a du sens? Nous avons déjà HTTPS ...
  • autres...
  • dernier recours: ne faites pas cela, stockez les informations d'identification dans la session! La session est bonne. Avec ou sans cookies.

Est-ce que des problèmes de sécurité / Web vous viennent à l'esprit, concernant l'une des idées décrites précédemment? Par exemple,

  • time-out - nous pouvons conserver un horodatage , ainsi que les informations d'identification (horodatage = l'heure à laquelle Bob a entré ses informations d'identification). Par exemple, lorsque MAINTENANT - horodatage> seuil , nous pouvons refuser la demande.
  • Protection contre les scripts intersites - ne devrait en aucun cas être différente, non?

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

turdus-merula
la source
1
Vous pouvez ajouter un jeton à chaque URL. ASP.NET a un mode (hérité) pour ce faire. Cela prouve que cela peut fonctionner.
usr
1
Où est tout le monde? :)
turdus-merula
2
Je pense que vous avez une assez bonne idée des options disponibles. Faites confiance à votre raisonnement et décidez vous-même.
usr
un plugin comme Silverlight of Flash est-il une option?
Giu
@usr ne sait pas si c'est une bonne idée, car si un pirate accédait à vos journaux Websever pouvait voler votre jeton et se connecter à votre système.
GibboK le

Réponses:

74

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

J'ai vu plusieurs façons de le faire au cours de mes séjours lors des évaluations des candidatures. L'un des moyens les plus populaires est la manière de jouer au tennis que vous avez mentionnée - l'envoi du nom d'utilisateur et du mot de passe dans chaque demande d'authentification de l'utilisateur. Ceci, à mon avis, n'est pas sûr, surtout si l'application n'est pas une seule page. Il n'est pas non plus évolutif, surtout si vous souhaitez ajouter une autorisation à votre application en plus de l'authentification à l'avenir (même si je suppose que vous pouvez également créer quelque chose en fonction des 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 crie à cela, mais cela pourrait fonctionner - chaque demande a unX-Authentication-Tokenen-tête ou quelque chose comme ça, et vous mappez cela à une base de données, un stockage 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, sa seule instruction SQL exécutée et avec les bons index, son exécution ne devrait prendre que très peu de temps, même avec plusieurs utilisateurs simultanés. Les tests de charge ici aideraient certainement. Si je lis correctement la question, ce serait 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 exemple, plutôt que d'utiliser une combinaison de nom d'utilisateur + mot de passe + quoi que ce soit d'autre - de cette façon, cela reste imprévisible, mais vous pouvez toujours l'associer à l'ID utilisateur ou à quelque chose du genre.

Quoi que vous utilisiez, assurez-vous qu'il vous est envoyé en toute sécurité. HTTPS vous protège à travers le câble, mais il ne vous protège pas si vous perdez 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 possible, d'envoyer le jeton via une requête POST à ​​chaque fois (cela signifierait un champ de formulaire masqué sur le navigateur de l'utilisateur.) Cette dernière approche consistant à utiliser une requête POST devrait utiliser les défenses CSRF, juste au cas où, bien que je soupçonne que l'utilisation du 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 ne semble jamais disparaître. Si vous devez prendre en charge plusieurs connexions utilisateur, assurez-vous de limiter le nombre ou de limiter la durée de chaque jeton. Comme je l'ai déjà dit, les tests de charge peuvent être la réponse à cela.

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

Karthik Rangarajan
la source
Ne faites-vous pas ce que fait le framework de jeu et envoyez un cookie signé à l'utilisateur? Puis ce cookie est-il renvoyé au serveur pour chaque requête ultérieure?
j sera le
8
> Son navigateur est au régime, il ne prend donc pas en charge les cookies.
Karthik Rangarajan
4
Certaines de ces suggestions sont-elles réellement apatrides / sans session ? De vos cinq paragraphes principaux (à partir de l'édition 2013-12-19 de l'article): # 1 est une introduction, # 2 propose des sessions extra-kludgy Web2.0 ™ -Flavored, # 3 est juste des avertissements, # 4 discute des implications d'état , et # 5 est une vague outro ... comment cela a-t-il été accepté ?? Au mieux, c'est tangentiellement informatif!
JamesTheAwesomeDude
1

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

Donc, si vous souhaitez appliquer la connexion, l'option de jeton chiffré peut être bonne. Cela pourrait également être bon pour la session d'invité. Dans une autre direction, je combinerais entre l'ajout du jeton à l'URL et l'option tennis.

Notez que l'envoi d'informations d'identification uniquement dans l'URL peut être dangereux. Par exemple, vous pouvez divulguer 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.

Une 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, pour vous protéger contre les attaques de Cross Site Request Forgery (CSRF).

Gari BN
la source
3
Une session est un état stocké sur le serveur. La question demande une authentification sans état.
Kwebble