web-dev-qa-db-fra.com

éviter de frapper DB pour authentifier un utilisateur à CHAQUE demande dans une architecture d'application web sans état?

Résumé

Une fois qu'un utilisateur se connecte à un site Web et que ses informations d'identification de nom d'utilisateur/mot de passe sont vérifiées et qu'une session active est établie, est-il possible d'éviter de toucher la base de données pour chaque demande de cet utilisateur? Quelle est la méthode recommandée pour authentifier en toute sécurité les demandes ultérieures pendant la durée de la session, tout en minimisant les requêtes DB et tout autre trafic réseau interne?

Contexte

Dans une architecture de serveur d'applications Web sans état, où chaque demande n'a aucune connaissance de toute activité antérieure de l'utilisateur, il serait nécessaire d'interroger la base de données sur chaque demande de cet utilisateur (généralement en interrogeant l'ID de session stocké dans un cookie et transféré dans l'en-tête de la demande). Mais que se passe-t-il si certaines informations de base ont été chiffrées et stockées dans ce cookie de session qui contenait suffisamment d'informations pour valider l'utilisateur pour les demandes non sensibles et non modifiables? Pour de telles demandes, vous pouvez par exemple crypter et stocker l'ID utilisateur et quelque chose qui identifie de manière unique sa machine autant que possible (agent utilisateur + adresse IP) dans les données de session. La clé utilisée pour crypter les données peut changer quotidiennement, ce qui rend difficile pour tout pirate de cloner les données de session sur une machine différente. Lorsque la session expire, vous devez valider entièrement les informations d'identification de l'utilisateur. Le fait est que la plus grande menace pour le piratage de la session d'un utilisateur serait que quelqu'un utilise l'ordinateur d'un utilisateur qu'il ou elle a laissé sans surveillance. Dois-je simplement ne pas m'inquiéter à ce sujet et laisser un certain niveau de mise en cache entre les serveurs d'applications Web et la base de données se charger d'accélérer le processus d'authentification? Bien que cela puisse sembler être une optimisation inutile, cela semble être un candidat mûr pour des améliorations d'efficacité car chaque demande nécessite ce processus. Merci pour toutes suggestions!

38
onlinespending

Oui c'est possible, et cette technique est largement utilisée.

Il présente quelques inconvénients mineurs par rapport aux sessions avec état:

  1. Il ne prend pas en charge la déconnexion renforcée. Si un utilisateur clique sur déconnexion, le cookie est effacé de son navigateur. Cependant, si un attaquant a capturé le cookie, il peut continuer à l'utiliser jusqu'à l'expiration du cookie.
  2. L'utilisation d'un secret côté serveur pour créer les jetons crée un point de défaillance unique: si le secret est capturé, un attaquant peut usurper l'identité de n'importe quel utilisateur.

La décision d'utiliser des sessions sans état ou avec état dépend de vos exigences de performances et de sécurité. Les services bancaires en ligne auraient tendance à utiliser des sessions avec état, tandis qu'un blog très chargé aurait tendance à utiliser des sessions sans état.

Quelques modifications sont nécessaires à votre schéma proposé:

  1. Le chiffrement du jeton ne le protège pas de la falsification. Vous souhaitez utiliser un code d'authentification de message (MAC) qui protège la falsification. Vous pouvez également utiliser le cryptage, mais cela est moins important.
  2. Vous devez inclure un horodatage dans le jeton et fixer une limite de temps à leur validité. Quelque part environ 15 minutes est raisonnable. Normalement, vous rééditez automatiquement peu de temps avant le délai d'expiration, et généralement la réédition entraîne un accès à la base de données (même si cela peut être évité)
  3. N'incluez pas l'adresse IP de l'utilisateur dans le jeton. Environ 3% des utilisateurs changeront légitimement l'adresse IP au cours d'une session Web, en raison des réinitialisations du modem, des points chauds WiFi changeants, des proxys à charge équilibrée et plus encore. Bien que vous puissiez inclure l'agent utilisateur dans le jeton, il n'est pas normal de le faire - considérez-le comme une technique avancée à utiliser si vous êtes sûr de savoir ce que vous faites.
  4. Si un attaquant capture un cookie de session, il peut usurper l'identité de cet utilisateur. Il n'y a rien que vous puissiez vraiment faire. Au lieu de cela, mettez tous vos efforts pour empêcher un attaquant de capturer le cookie en premier lieu. Utilisez SSL, utilisez l'indicateur de cookie "sécurisé", corrigez toutes les failles de script intersites, etc. Et demandez à l'utilisateur de verrouiller son écran lorsque son ordinateur est sans surveillance.

J'espère que ça t'aide. Si quelque chose n'est pas clair ou si vous avez besoin de plus d'informations, laissez un commentaire et je verrai si je peux vous aider davantage.

42
paj28

De manière générique, il est possible de "stocker" des informations d'état sur le client, même des informations sensibles telles que des données d'authentification; un tel stockage est utilisé pour économiser des ressources sur le serveur, par ex. pour minimiser la charge de la base de données. Voir ces questions précédentes:

En bref, chaque fois que vous souhaitez stocker des informations s sur le serveur, pour être recherché si le même client revient, vous pouvez à la place l'envoyer sous forme de cookie au client. Vous pouvez souhaiter le cryptage car ces informations peuvent être "privées", dans le sens où vous ne voulez pas les montrer au client lui-même. Vous voulez probablement l'intégrité parce que vous ne voulez pas que le client puisse modifier les données sans votre consentement. Donc, vous voulez à la fois le cryptage et un MAC , ou mieux encore, l'un de ces modes de cryptage astucieux qui font les deux correctement ( GCM étant la norme souvent citée pour cela).

De manière générique, lorsque vous stockez des informations d'état sur le client et le client, vous perdez un certain contrôle sur le cycle de vie de ces informations. Le client peut choisir de ne pas renvoyer le cookie, c'est-à-dire simuler un nouveau client frais; le client peut également renvoyer une ancienne valeur de cookie. Que ce soit un problème pour vous dépend de votre situation exacte. Vous souhaiterez probablement inclure dans les données des cookies un horodatage, vous permettant de reconnaître les valeurs des cookies qui sont vraiment trop anciennes.

16
Thomas Pornin

Il existe plusieurs façons de résoudre ce problème (et j'ai vu cette approche utilisée dans REST).

  1. Utilisation de HTTP pour s'authentifier, puis utiliser l'API sans état.
  2. Utilisation d'une méthode d'authentification HTTP de base et utilisation d'un tokenID expirant dans chaque demande.

De toute façon, si vous avez besoin d'authentification et sans état, vous devrez gérer l'authentification dans votre session d'application. Après avoir vérifié les informations d'identification, vous pouvez réellement effectuer la requête de base de données sans la créer à nouveau via un utilisateur de confiance ou similaire.

Assurez-vous de ne pas autoriser la connexion directe à la base de données à partir d'un autre utilisateur que celui que vous avez autorisé à le faire après la vérification des informations d'identification.

1
kiBytes

Je suis sûr que vous comprenez que l'omission d'une authentification basée sur une authentification précédente fait de votre application Web une application de session. N'est-ce pas un état de session authentifié? Sachez que vous étudiez pour avoir une session; vous pouvez vous demander pourquoi vous aviez besoin d'une application de lies de session. Normalement, les gens veulent des applications de session lees pour deux raisons principales: Les demandes peuvent être envoyées à différents serveurs sans se soucier de toute dépendance entre le client et n'importe quel membre d'une batterie de serveurs. Liaison de mémoire lorsqu'un grand nombre d'utilisateurs accèdent simultanément. Même sur les applications de session, vous pouvez répondre à ces exigences en obligeant le serveur à émettre un jeton signé chiffré lors de l'authentification afin que les autres membres de la batterie de serveurs Web puissent vérifier ce jeton pour avoir une idée que l'utilisateur peut être légitime. L'emprunt d'identité est toujours possible car la demande suivante nécessite le même jeton. Vous pouvez inclure dans les données de jeton des en-têtes http et des adresses IP de demande pour restreindre son utilisation, mais les mandataires intermédiaires peuvent toujours utiliser le jeton en faisant NAT et en copiant les en-têtes client. Ensuite, seul moyen de rendre invulnérable à l'homme au milieu des attaques consiste à protéger la demande d'authentification par https et à laisser le client vous envoyer avec les informations d'identification une clé générée au hasard qui sera utilisée pour décrypter la signature de la demande, le client dans chaque demande cryptera certaines données de la demande comme signature. Les données chiffrées peuvent être l'ID de session et un élément de séquence d'un générateur de séquenceur préétabli. N'utilisez pas le simple incrémenté de un en raison de son comportement prévisible. Comme dans chaque demande, cette signature est différente des signatures précédentes, vous pouvez être sûr que le client est authentifié. Si le générateur de séquenceur l'incrémente toujours, vous pouvez mettre en cache le dernier élément utilisé pour effectuer une vérification simple avant une vérification complète; diffuser les autres membres de la ferme elemen t de la séquence utilisée dans l'ID de session et ils ne répondront que si l'élément n'est pas valide. Une séquence d'éléments n'est pas valide si elle a été utilisée dans une demande précédente dans le serveur de réponse ou si les éléments suivants de la séquence expirent dans le cache. La prévention du lignage de la mémoire est une simple implémentation d'un serveur SQL pour chaque batterie de membres afin de rendre ces informations persistantes et de n'avoir en mémoire que les informations les plus fréquemment utilisées. Les périphériques de réseau utilisés pour la communication entre les membres de la batterie doivent être tous administrés par le propriétaire de l'application car la communication n'est pas sécurisée. Avec cette structure, l'évolutivité est assurée.

0
Oscar Gras