Plan du site  
pixel
pixel

Articles - Étudiants SUPINFO

Les tokens d'authentification

Par Samir SELLAMI Publié le 18/10/2016 à 19:03:40 Noter cet article:
(0 votes)
Avis favorable du comité de lecture

Introduction

Les tokens d'authentification (ou jetons d'authentification) représentent un concept puissant d'authentification. Il permet d'autoriser des utilisateurs à entrer leur nom d'utilisateur et leur mot de passe afin d'obtenir un jeton qui leur permet d'accèder à une ressource spécifique sans réutiliser un nom d'utilisateur et un mot de passe. Une fois son jeton obtenu, l'utilisateur peut profiter du jeton qui offre un accès à une ressource spécifique pour une période de temps précise sur un site distant. En d'autres mots, il permet d'ajouter un niveau d'authentification indirect au lieu d'avoir à connecter avec le nom d'utilisateur et mot de passe pour chaque ressource protégée. l'utilisateur s'authentifie de cette façon qu'une seule fois (dans une session d'une durée limitée), obtient en retour un jeton pour une durée limitée, et utilise ce même jeton pour une authentification supplémentaire au cours de sa session.

Ce qu'il faut savoir sur les tokens


1. les Tokens doivent être stockés quelque part (stockage en local / en session ou utilisation de cookies)

Dans le cadre de jetons utilisés sur les applications développées sur une seule et unique page web, certaines personnes ont soulevé la question sur l'actualisation de la page dans le navigateur, et ce qui se passe avec le jeton. La réponse est simple: vous devez stocker le jeton quelque part: dans le stockage de la session, le stockage local ou dans un cookie du côté client . La plupart des polyfills (fonctions) de stockage de sessions font appel aux cookies lorsque le navigateur ne les supporte pas. Si vous vous demandez «mais si je stocke le jeton dans le cookie , je retourne à la case de départ" . Pas vraiment, dans ce cas , vous utilisez les cookies comme un mécanisme de stockage, non pas comme un mécanisme d'authentification. Par exemple, le cookie ne sera pas utilisé par le framework web pour authentifier un utilisateur. Il n y aura donc pas de risque CSRF (Cross-Site Request Forgery) qui est un type de vulnérabilité des services d'authentification web.


2. Les Tokens peuvent expirer comme les cookies, mais vous aurez plus de contrôle dessus

Les Tokens ont tous une date d'expiration (en JSON Web Tokens est représenté par la propriété exp ), sinon quelqu'un pourrait authentifier à jamais à l'API une fois il s'y est connecté au moins une fois. Les cookies ont également une date d'expiration pour exactement les mêmes raisons.

Dans les cookies, il existe différentes options pour contrôler la durée de vie du cookie:

1. Les cookies peuvent être supprimés après la fermeture du navigateur (cookies de session).

2. En plus de cela, vous pouvez développer un contrôle côté serveur (typiquement fait pour vous par le framework web utilisé), et vous pourrez mettre en œuvre l'expiration ou une fenêtre coulissante d'expiration.

3. Les cookies peuvent être persistants (non supprimés après la fermeture du navigateur) avec une date d'expiration.

Dans le monde des tokens, une fois le token expiré, la méthode est simple si vous voulez obtenir un nouveau.

Vous pourrez mettre en place un point final pour rafraîchir un token qui:

1. Valide l'ancien token.

2. Vérifie si l'utilisateur existe encore ou que l'accès n'a pas été révoqué ou tout ce qui a un sens pour votre application.

3. Délivre un nouveau token avec un renouvellement de son expiration.

Vous pouvez même stocker dans le token la date d'attribution initiale, et d'imposer une nouvelle connexion au bout de deux semaines par exemple.


app.post('/token_maj', function (req, res) {
  // verifier le token existant
  var profil = jwt.verify(req.body.token, secret);

  // Si la dernère authentification date de plus de 14 jours, forcer une nouvelle authentification
  if (profil.delivree_le - new Date() > 14) { // delivree_le == date autorisation token
    return res.send(401); // réauthentifier
  }

  // vérifier si l'utilisateur existe encore ou que son autorisation aie été révoquée 
  if (!valid) 
  return res.send(401); // réauthentifier

  // délivrer un nouveau token
  var token_refresh = jwt.sign(profile, secret, { expiresInMinutes: 60*5 });
  res.json({ token: token_refresh });
});

Si vous avez besoin de révoquer des jetons (utile si les jetons sont de longue durée), vous aurez besoin d'avoir une sorte de registre des jetons émis pour vérifier dessus.


3. Le stockage en Local ou en session, ne fonctionnera pas à travers les noms de domaines, utilisez un cookie

Si vous définissez le domaine d'un cookie en .votredomaine.com, il peut être consulté à partir de votredomaine.com et de app.votredomaine.com, ce qui rend plus facile à détecter à partir du domaine principal (où vous avez probablement, disons, votre site marketing) que l'utilisateur est déjà connecté et le redirgie vers app.votredomaine.com.

Les Tokens stockés en local ou en session, d'autre part, ne peuvent pas être accessibles à partir de différents domaines (même si ceux-ci sont sous-domaines). Alors que pourrait-on faire?

Une option possible est de générer un token lorsque l'utilisateur authentifie sur app.votredomaine.com , vous pouvez également définir un cookie pour votredomaine.com



$.post('/authentification, function() {
  // stocker le token pour un stockage en local/session storage ou un cookie
    ....

    // créer un cookie qui signale qu'un utilisateur est authentifié 
  $.cookie('authentifié', profil.name, '.votredomaine.com');
});

Puis, dans youromdain.com, vous pouvez vérifier l'existence de ce cookie et rediriger vers app.yourdomain.com si le cookie existe. Le token sera disponible sur le sous-domaine de l'application, et à partir de là, le flux habituel s'applique (si le token est toujours valide,utilisez le. Sinon obtenez un nouveau , sauf si la dernière connexion a dépassé le seuil défini).

Il peut arriver que le cookie existe, mais que le token aie été supprimé ou qu'il ne soit plus disponible. Dans ce cas, l'utilisateur devra se connecter à nouveau. Mais ce qu'il faut de souligner ici est, comme nous l'avons dit, que nous n'utilisons pas le cookie en tant que mécanisme d'authentification, mais comme un mécanisme de stockage qui arrive à supporter le stockage de données dans différents domaines.


4. Les requêtes de contrôle en amont seront envoyés à chaque requête CORS « Cross-Origin Resource Sharing »

CORS est un mécanisme qui permet aux ressources limitées (par exemple des polices) sur une page Web à demander à un autre domaine en dehors du domaine à partir duquel la ressource est originaire. Une page Web peut librement intégrer des images, des feuilles de style , scripts, iframes , vidéos. Certaines demandes "inter-domaines", notamment les requêtes AJAX, mais sont interdites par défaut par la politique de sécurité de la même origine . L'en-tête HTTP d'autorisation est n'est pas une simple en-tête , une requête de pré-envoi serait donc nécessaire pour toutes les requêtes vers une URL particulière.



OPTIONS https://api.foo.com/Auth
GET https://api.foo.com/Auth
   Authorization: Bearer  ....

OPTIONS https://api.foo.com/Auth2
GET https://api.foo.com/Auth2
   Authorization: Bearer  ....

GET https://api.foo.com/Auth
   Authorization: Bearer  ....
   

Mais cela se produit si vous envoyez Content-Type: application/json par exemple. Ce qui est déjà le cas pour la plupart des applications.

Une petite mise en garde, la requête OPTIONS n'aura pas l'en-tête d'autorisation elle-même. De sorte que votre framework web devrait supporter le traitement deOPTIONS les requêtes suivantes différemment ( Remarque: Microsoft IIS semble avoir des difficultés avec cela par exemple).


5. Lorsque vous avez besoin de tracer, utiliser le token pour obtenir une requête signée

Lors de l' utilisation des cookies, vous pouvez déclencher un téléchargement de fichiers et un suivi du flux de contenu facilement. Cependant, dans les tokens, où la requête se fait via XMLHttpRequest (XHR), vous ne pouvez pas compter sur cela. Vous résolverez ce problème en générant une demande signée comme Amazon Web Services le fait, par exemple. Hawk Bewits est un cadre idéal pour permettre ceci:

Requête :



POST /download-file/abc
Authorization: Bearer ...

Retour :

ticket=lahdoiasdhoiwdowijaksjdoaisdjoasidja

Ce ticket est apatride et il est construit sur la base de l'URL: hôte + chemin + requête + en-têtes + temps + HMAC, et a une date d'expiration. Ainsi, il peut être utilisé prochainement, soit dans les 5 minutes, pour télécharger le fichier.

Vous pouvez ensuite vous rediriger vers /download-file/abc?ticket=lahdoiasdhoiwdowijaksjdoaisdjoasidja. Le serveur vérifie que le billet est valide et continue à fonctionner comme d' habitude.


6. Il est plus facile de prévenir le cross-site scripting (XSS) que le Cross-Site Request Forgery (XSRF)

Les cookies ont cette fonctionnalité qui permet l'ajout d'une valeur de flaggage HttpOnly du côté serveur pour être accessibles sur le serveur et non à partir de code JavaScript. Ceci est utile pour protèger le contenu du cookie d'être consulté par injection de code côté client (XSS).

Depuis que les tokens sont stockés en local et en session ou en cookies côté client, ils sont ouverts à une attaque XSS permettant à l'attaquant d'avoir accès attaquant au token. Ceci est une préoccupation récurrente, et pour cette raison, vous devriez toujours définir un délai d'expiration du token court.

Mais si vous pensez à la capacité d'attaque sur les cookies, l'une des principales est XSRF. La réalité est que XSRF est l'une des attaques les plus mal comprises, et le développeur moyen, pourrait même ne pas comprendre le risque. Donc beaucoup de demandes manquent de mécanisme anti-XSRF. Cependant, tout le monde comprend ce qu'est l'injection. Plus simplement, si vous permettez l'écriture sur votre site, et ensuite l'afficher sans le quitter, vous êtes exposés à XSS. Donc,il est plus facile de se protéger contre XSS que de se protéger contre XSRF. En outre, les anti-XSRF ne sont pas intégrés sur chaque framework web. XSS, d'autre part, est facile à prévenir en utilisant la syntaxe de contournement disponible par défaut sur la plupart des templates modèle.


7. Le token est envoyé à chaque requête, surveiller sa taille

A chaque fois que vous faites une requête vers l'API vous devez envoyer le token dans l'en-tête Authorization.



GET /foo
Authorization: Bearer ...3kb token...
   

Par contre



GET /foo
connect.sid: ...30 bytes cookie...
   

Selon la quantité d'informations que vous stockez dans le token, il pourrait augmenter de taille. D'autre part, les cookies de session représentent habituellement juste un identifiant (connect.sid, PHPSESSID, etc.) et le reste du contenu des existe sur le serveur (en mémoire si vous avez un seul serveur ou sur une base de données si vous exécutez sur plusieurs serveurs).

Maintenant, rien ne vous empêche de mettre en œuvre un mécanisme similaire avec des tokens. Le token aurait les informations nécessaires de base et du côté serveur , vous pourrez enrichir avec davantage de données sur chaque appel d'API. Il s'agit du même mode de fonctionnement des cookies. La différence est que vous avez l'avantage que ce soit une décision consciente, sur laquelle vous avez le total contrôle, et qu'elle fait partie de votre code.



GET /foo
Authorization: Bearer ……700 bytes token…. 

Ensuite, sur le serveur:



app.use('/api',
  // valider le token
  expressJwt({secret: secret}),

  // enrichir req.user avec plus de données de la base de données
  function(req, res, next) {
    req.user.extra_data = get_from_db();
    next();
  });
  

Il convient de mentionner que vous pourriez aussi avoir la session complètement stockée sur le cookie ( au lieu d'être simplement un identifiant). Certaines platesformes Web supportent cela, d'autres non. Par exemple, dans node.js vous pouvez utiliser mozilla/node-client-sessions .


8. Si vous stockez des informations confidentielles, il faut chiffrer le Token

La signature sur le token empêche sa modification. le protocle TLS / SSL protége des attaques. Mais si vous avez des informations sensibles sur l'utilisateur (par exemple SSN, ou autres), vous pouvez également les chiffrer. Il y a les points de JWT spec et JWE Spec mais la plupart des bibliothèques ne mettent pas encore en œuvre JWE, donc le plus simple serait de chiffrer avec AES-CBC comme indiqué ci-dessous.



 app.post('/authentification', function (req, res) {
  // valider l'utilisateur

  // encoder le profil
  var encode = { token: encodeAesSha256('shhhh', JSON.stringify(profil)) };

  // signer le token
  var token = jwt.sign(encode, secret, { expiresInMinutes: 60*5 });

  res.json({ token: token });
}

function encodeAesSha256 (password, textaencoder) {
  var cipher = crypto.createCipher('aes-256-cbc', password);
  var code = cipher.update(textaencoder, 'utf8', 'hex');
  code += cipher.final('hex');
  return code;
}
 

Bien sûr, vous pouvez utiliser l'approche sur # 7 et garder les informations confidentielles dans une base de données.

Conclusion

Le but de cet article était de parcourir les diffèrentes choses à savoir avant de commencer à travailler sur l'authentification basée sur les tokens. Nous avons parcouru les diffèrents aspects à prendre en considération à savoir le stockage, la taille ou le chiffrement du token. Il faut résister à la tentation de tout mettre en tokens et faire une analyse et un dimensionnement avant de tout attaquer avec cette approche. En effet,comme c'est toujours le cas dans le domaine de la sécurité informatique, tout varie selon les cas d'utilisation.

A propos de SUPINFO | Contacts & adresses | Enseigner à SUPINFO | Presse | Conditions d'utilisation & Copyright | Respect de la vie privée | Investir
Logo de la société Cisco, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société IBM, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Sun-Oracle, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Apple, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Sybase, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Novell, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Intel, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Accenture, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société SAP, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Prometric, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Toeic, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo du IT Academy Program par Microsoft, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management

SUPINFO International University
Ecole d'Informatique - IT School
École Supérieure d'Informatique de Paris, leader en France
La Grande Ecole de l'informatique, du numérique et du management
Fondée en 1965, reconnue par l'État. Titre Bac+5 certifié au niveau I.
SUPINFO International University is globally operated by EDUCINVEST Belgium - Avenue Louise, 534 - 1050 Brussels