JWT JSON Web Token

Table Des Matières

Introduction


JSON Web Token, ou JWT en abrégé, est une norme permettant de transmettre des revendications en toute sécurité dans des environnements à contraintes d’espace. Il a trouvé sa place dans tous les principaux frameworks web. La simplicité, la compacité et la facilité d’utilisation sont des caractéristiques clés de son architecture. Bien que des systèmes beaucoup plus complexes soient encore utilisés, les JWT ont un large éventail d’applications.

Qu’est-ce qu’un JSON Web Token?

JSON Web Token ressemble à ceci (les nouvelles lignes insérées pour la lisibilité):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

Bien que cela ressemble à du charabia, il est en fait très compact, représentation imprimable d’une série de revendications, avec une signature pour vérifier son authenticité.

{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}

Les revendications sont des définitions ou des assertions faites à propos d’une certaine partie ou d’un objet. Certaines de ces revendications et leur signification sont définies dans le cadre de la spécification JWT. D’autres sont définis par l’utilisateur. La magie derrière JWTs est qu’ils normalisent certaines revendications qui sont utiles dans le cadre de certaines opérations communes. Par exemple, une de ces opérations communes établit l’identité d’une certaine partie. Donc, l’une des revendications standard trouvées dans les JWT est la sous-déclaration (de «sujet»). Nous examinerons de plus près chacune des revendications standard dans un prochain article.

Un autre aspect clé de JWT est la possibilité de les signer, utilisant des signatures Web JSON (JWS, RFC 7515), et / ou les crypter, en utilisant JSON Web Encryption (JWE, RFC 7516). Ensemble avec JWS et JWE, les JWT fournissent une solution puissante et sécurisée à de nombreux problèmes différents.

Quel problème résout JSON Web Token?

Bien que le but principal de JWTs est de transférer des revendications entre deux parties, sans doute l’aspect le plus important de ceci est l’effort de normalisation sous la forme d’un format de conteneur simple, éventuellement validé et / ou crypté. Des solutions ad hoc à ce même problème ont été mises en œuvre à la fois privées et publiques dans le passé. Des normes plus anciennes pour établir des réclamations au sujet de certaines parties sont également disponibles. Ce que JWT apporte à la table est un format de conteneur simple, utile et standard.

Bien que la définition donnée soit un peu abstraite jusqu’à présent, ce n’est vraiment pas difficile d’imaginer comment ils peuvent être utilisés: Systèmes de connexion (bien que d’autres utilisations soient possibles). Nous allons regarder de plus près les applications pratiques à la section 2. Certaines de ces applications comprennent:

  • Authentification
  • Autorisation
  • Identité fédérée
  • Sessions côté client (sessions « sans état »)
  • Secrets côté client

Un Peu D’Histoire

Le groupe JSON Object Signing and Encryption (JOSE) a été créé en 2011. L’objectif du groupe était de standardiser le mécanisme de protection d’intégrité (signature et MAC) et de cryptage ainsi que le format des clés et des identifiants d’algorithmes pour prendre en charge l’interopérabilité des services de sécurité pour les protocoles utilisant JSON. En 2013, une série de projets, y compris un livre de cuisine avec différents exemples de l’utilisation des idées produites par le groupe, étaient disponibles. Ces brouillons deviendront plus tard les WT, JWS, JWE, JWK et JWA RFCs. À partir de l’année 2016, ces RFCs sont dans le processus de normalisation et les errata n’y ont pas été trouvés. Le groupe est actuellement inactif.

Les principaux auteurs derrière les spécifications sont Mike Jones, Nat Sakimura, John Bradley et Joe Hildebrand

Applications Pratiques


Avant de plonger dans la structure et la construction d’un JWT, nous examinerons plusieurs applications pratiques. Cette section vous donnera une idée de la complexité (ou de la simplicité) des solutions JWT courantes utilisées dans l’industrie aujourd’hui. Tout le code est disponible dans les dépôts publics pour votre commodité. Sachez que les démonstrations suivantes ne sont pas destinées à être utilisées en production. Les cas de test, la journalisation et les meilleures pratiques en matière de sécurité sont tous essentiels pour le code adapté à la production. Ces échantillons sont uniquement à des fins éducatives et restent donc simples et précis.

Sessions Côté Client / sans état

Les sessions dites sans état ne sont en fait rien de plus que des données côté client. L’aspect clé de cette application réside dans l’utilisation de la signature et éventuellement du chiffrement pour authentifier et protéger le contenu de la session. Les données côté client sont sujettes à la falsification. En tant que tel, il doit être manipulé avec beaucoup de soin par le backend.

JWT, en vertu de JWS et JWE, peut fournir différents types de signatures et de cryptage. Les signatures sont utiles pour valider les données contre la falsification. Le cryptage est utile pour protéger les données contre leur lecture par des tiers.

La plupart du temps, les sessions doivent seulement être signées. En d’autres termes, il n’y a pas de problème de sécurité ou de confidentialité lorsque les données qui y sont stockées sont lues par des tiers. Un exemple courant d’une revendication qui peut généralement être lue en toute sécurité par des tiers est la sous-revendication ‘sujet’. La revendication du sujet identifie généralement l’une des parties à l’autre (pensez aux identifiants d’utilisateur ou aux courriels). Ce n’est pas une exigence que cette revendication soit unique. En d’autres termes, des revendications supplémentaires peuvent être nécessaires pour identifier de manière unique un utilisateur. C’est laissé aux utilisateurs de décider.

Une réclamation qui pourrait ne pas être laissée à l’air libre pourrait être une réclamation ‘articles’ représentant le panier d’un utilisateur. Ce panier peut être rempli avec des articles que l’utilisateur est sur le point d’acheter et sont ainsi associés à sa session. Un tiers (un script côté client) pourrait être en mesure de récolter ces éléments s’ils sont stockés dans un JWT non crypté, ce qui pourrait soulever des problèmes de confidentialité.

JWT Données signées Côté client
Image: Sessions Côté Client / sans état

 

Considérations De Sécurité

Signature Stripping

Une méthode courante pour attaquer un JWT signé est simplement de supprimer la signature. Les JWT signés sont construits à partir de trois parties différentes: l’en-tête, la charge utile et la signature. Ces trois parties sont codées séparément. En tant que tel, il est possible de supprimer la signature, puis de modifier l’en-tête pour affirmer que le JWT n’est pas signé. L’utilisation imprudente de certaines bibliothèques de validation JWT peut entraîner la prise de tokens non signés en tant que tokens valides, ce qui peut permettre à un attaquant de modifier la charge utile à sa discrétion. Ceci est facilement résolu en s’assurant que l’application qui effectue la validation ne considère pas les JWT non signés comme valides.

JWT Signature Stripping
Image: Signature Stripping
Attaques par script inter-site (CSRF)

Les attaques de contrefaçon par demande inter-site tentent d’exécuter des requêtes sur des sites où l’utilisateur est connecté en incitant le navigateur de l’utilisateur à envoyer une requête depuis un site différent. Pour y parvenir, un site (ou un objet) spécialement conçu doit contenir l’URL de la cible. Un exemple courant est une balise <img> incorporée dans une page malveillante avec la src pointant vers la cible de l’attaque. Par exemple:

<!-- This is embedded in another domain's site -->
<img src="http://target.site.com/add-user?user=name&grant=admin">

La balise <img> ci-dessus enverra une requête à la cible (.site.com) chaque fois que la page qui la contient est chargée. Si l’utilisateur s’était déjà connecté sur le site cible, et le site a utilisé un cookie pour garder la session active, ce cookie sera également envoyé. Si le site cible n’applique aucune technique d’atténuation CSRF, la demande sera traitée comme une demande valide au nom de l’utilisateur. Les JWT, comme toutes les autres données client, peuvent être stockées en tant que cookies.

JWT Attaques De Contrefaçon Par Demande Inter-Site (CSRF)
Image: attaques de contrefaçon par demande inter-site

Les JWT à courte durée de vie peuvent aider dans ce cas. Les techniques d’atténuation CSRF courantes incluent des en-têtes spéciaux qui sont ajoutés aux demandes uniquement lorsqu’elles sont exécutées à partir de la bonne origine, des cookies de session et des jetons (tokens) de demande. Si les fichiers JWT (et les données de session) ne sont pas stockés en tant que cookies, les attaques CSRF ne seront pas possibles. Cependant, les attaques par script inter-site sont toujours possibles.

Attaques Par Script Inter-Site (XSS)

les attaques par script inter-site (xss) tentent d’injecter JavaScript dans les sites de confiance. Une fois injecté, Javascript peut ensuite voler des jetons à partir de cookies et de stockage local. Si un token (jeton) d’accès est divulgué avant son expiration, un utilisateur malveillant pourrait l’utiliser pour accéder à des ressources protégées. Les attaques XSS courantes sont généralement causées par une mauvaise validation des données transmises au backend (de la même manière que les attaques par injection SQL).

Un exemple d’attaque XSS pourrait être lié à la section des commentaires d’un site public. Chaque fois qu’un utilisateur ajoute un commentaire, il est stocké par le backend et affiché aux utilisateurs qui chargent la section des commentaires. Si le backend ne désinfecte pas les commentaires, un utilisateur malveillant pourrait écrire un commentaire de manière à ce qu’il puisse être interprété par le navigateur comme une balise <script>. Ainsi, un utilisateur malintentionné pourrait insérer du code JavaScript arbitraire et l’exécuter dans le navigateur de chaque utilisateur, pour pouvoir ensuite voler des informations d’identification stockées en tant que cookies et dans le stockage local.

JWT Attaques Par Script Inter-Site (XSS)
Image: Attaques Par Script Inter-Site Persistant
JWT Attaques Par Script Inter-Site Réfléchissante
Image: Attaques Par Script Inter-Site Réfléchissantes

Les techniques d’atténuation reposent sur une validation correcte de toutes les données transmises au backend. En particulier, toutes les données reçues des clients doivent toujours être nettoyées. Si des cookies sont utilisés, il est possible de les protéger contre l’accès par JavaScript en définissant l’indicateur HttpOnly. L’indicateur HttpOnly, bien qu’utile, ne protégera pas le cookie contre les attaques CSRF.

Les Sessions Côté Client Sont-Elles Utiles?

Il y a des avantages et des inconvénients à toute approche, et les sessions côté client n’échappent à cette règle. Certaines applications peuvent nécessiter de grandes sessions. Envoyer cet état d’avant en arrière pour chaque demande (ou groupe de demandes) peut facilement surmonter les avantages du bavardage réduit dans le backend. Un certain équilibre entre les données côté client et les recherches de base de données dans le backend est nécessaire. This depends
on the data model of your application. Certaines applications ne correspondent pas aux sessions côté client. D’autres peuvent dépendre entièrement des données côté client. C’est à vous que revient le dernier mot en ce qui concerne cette question! Exécuter des repères, étudier les avantages de garder certains clients côté client. Les JWT sont-ils trop gros? Cela a-t-il un impact sur la bande passante? Cette bande passante ajoutée renverse-t-elle la latence réduite dans le backend? Les petites requêtes peuvent-elles être agrégées en une seule requête plus importante? Est-ce que ces requêtes nécessitent toujours de grandes recherches de base de données? Répondre à ces questions vous aidera à décider de la bonne approche.

Exemple

Pour notre exemple, nous allons faire une simple application de magasinage. Le panier de l’utilisateur sera stocké côté client. Dans cet exemple, plusieurs JWT sont présents. Notre panier sera l’un d’entre eux.

  • Un JWT pour le token d’identification, un token qui contient les informations de profil de l’utilisateur, utiles pour l’interface utilisateur.
  • Un JWT pour interagir avec le backend de l’API (le token d’accès).
  • Un JWT pour notre état côté client: le panier.

Voici à quoi ressemble le panier lorsqu’il est décodé:

{
"items": [
0,
2,
4
],
"iat": 1493139659,
"exp": 1493143259
}

Chaque élément est identifié par un ID numérique. Le JWT codé et signé ressemble à:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJpdGVtcyI6WzAsMiw0XSwiaWF0IjoxNDkzMTM5NjU5LCJleHAiOjE0OTMxNDMyNTl9.
932ZxtZzy1qhLXs932hd04J58Ihbg5_g_rIrj-Z16Js
Pour rendre les éléments dans le panier, le client n’a besoin que de le récupérer depuis son cookie:

function populateCart() {
const cartElem = $('#cart');
cartElem.empty();
const cartToken = Cookies.get('cart');
if(!cartToken) {
return;
}
const cart = jwt_decode(cartToken).items;
cart.forEach(itemId => {
const name = items.find(item => item.id == itemId).name;
cartElem.append(`<li>${name}</li>`);
});
}

Notez que le frontend ne vérifie pas la signature, il décode simplement le JWT afin qu’il puisse afficher son contenu. Les vérifications réelles sont effectuées par le backend. Tous les JWT sont vérifiés.
Voici le backend vérifier la validité du panier JWT implémenté en tant que middleware Express:

function cartValidator(req, res, next) {
if(!req.cookies.cart) {
req.cart = { items: [] };
} else {
try {
req.cart = {
items: jwt.verify(req.cookies.cart,
process.env.AUTH0_CART_SECRET,
cartVerifyJwtOptions).items
};
} catch(e) {
req.cart = { items: [] };
}
}
next();
}

Lorsque des éléments sont ajoutés, le backend construit un nouveau JWT avec le nouvel élément et une nouvelle signature:

app.get('/protected/add_item', idValidator, cartValidator, (req, res) => {
14
req.cart.items.push(parseInt(req.query.id));
const newCart = jwt.sign(req.cart,
process.env.AUTH0_CART_SECRET,
cartSignJwtOptions);
res.cookie('cart', newCart, {
maxAge: 1000 * 60 * 60
});
res.end();
console.log(`Item ID ${req.query.id} added to cart.`);
});

Notez que les emplacements préfixés par / protected sont également protégés par le token d’accès à l’API. Ceci est configuré en utilisant express-jwt:

app.use('/protected', expressJwt({
secret: jwksClient.expressJwtSecret(jwksOpts),
issuer: process.env.AUTH0_API_ISSUER,
audience: process.env.AUTH0_API_AUDIENCE,
requestProperty: 'accessToken',
getToken: req => {
return req.cookies['access_token'];
}
}));

En d’autres termes, le point de terminaison / protected / add_item doit d’abord passer l’étape de validation du token d’accès avant de valider le chariot. Un token valide l’accès (autorisation) à l’API et l’autre token valide l’intégrité des données côté client (le panier).

Le jeton d’accès et le jeton d’identification sont attribués par Auth0 à notre application. Cela nécessite la configuration d’un client et d’un point de terminaison API à l’aide du tableau de bord Auth0. Ceux-ci sont ensuite récupérés en utilisant la bibliothèque JavaScript Auth0, appelée par notre interface:

//Auth0 Client ID
const clientId = "t42WY87weXzepAdUlwMiHYRBQj9qWVAT";
//Auth0 Domain
const domain = "speyrott.auth0.com";
const auth0 = new window.auth0.WebAuth({
domain: domain,
clientID: clientId,
audience: '/protected',
scope: 'openid profile purchase',
responseType: 'id_token token',
redirectUri: 'http://localhost:3000/auth/',
responseMode: 'form_post'
});
//(...)
$('#login-button').on('click', function(event) {
auth0.authorize();
});

La demande d’audience doit correspondre à celle de votre point de terminaison API à l’aide du tableau de bord Auth0.
Le serveur d’authentification et d’autorisation Auth0 affiche un écran de connexion avec nos paramètres, puis redirige vers notre application à un chemin spécifique avec les jetons que nous avons demandés. Ceux-ci sont gérés par notre backend qui les définit simplement comme des cookies:

app.post('/auth', (req, res) => {
res.cookie('access_token', req.body.access_token, {
httpOnly: true,
maxAge: req.body.expires_in * 1000
});
res.cookie('id_token', req.body.id_token, {
maxAge: req.body.expires_in * 1000
});
res.redirect('/');
})

La mise en œuvre des techniques d’atténuation du CSRF est laissée à l’appréciation du lecteur. L’exemple complet de ce code peut être trouvé dans le répertoire samples / stateless-sessions.

Identité Fédérée

Les systèmes d’identité fédérée permettent à des parties différentes, éventuellement non apparentées, de partager des services d’authentification et d’autorisation avec d’autres parties. En d’autres termes, l’identité d’un utilisateur est centralisée. Il existe plusieurs solutions pour la gestion des identités fédérées: SAML et OpenID Connect sont deux des plus courantes. Certaines entreprises fournissent des produits spécialisés centralisant l’authentification et l’autorisation. Ceux-ci peuvent mettre en œuvre l’une des normes mentionnées ci-dessus ou utiliser quelque chose de complètement différent. Certaines de ces entreprises utilisent des JWT à cette fin.
L’utilisation des JWT pour l’authentification et l’autorisation centralisées varie d’une entreprise à l’autre, mais le flux essentiel du processus d’autorisation est:

JWT Flux d'identité fédérée commune
Image: Flux d’identité fédérée commune
  1. L’utilisateur tente d’accéder à une ressource contrôlée par un serveur.
  2. L’utilisateur n’a pas les informations d’identification appropriées pour accéder à la ressource. Le serveur redirige donc l’utilisateur vers le serveur d’autorisation. Le serveur d’autorisation est configuré pour permettre aux utilisateurs de se connecter à l’aide des informations d’identification gérées par un fournisseur d’identité.
  3. L’utilisateur est redirigé par le serveur d’autorisation vers l’écran de connexion du fournisseur de l’identité.
  4. L’utilisateur se connecte avec succès et est redirigé vers le serveur d’autorisation. Le serveur d’autorisation utilise les informations d’identification fournies par le fournisseur d’identité pour accéder aux informations d’identification requises par le serveur de ressources.
  5. L’utilisateur est redirigé vers le serveur de ressources par le serveur d’autorisation. La requête a maintenant les informations d’identification correctes requises pour accéder à la ressource.
  6. L’utilisateur accède à la ressource avec succès.

Toutes les données transmises du serveur au serveur transitent par l’utilisateur en étant intégrées dans les requêtes de redirection (généralement dans le cadre de l’URL). Cela rend la sécurité des transports (TLS) et la sécurité des données essentielles.

Les informations d’identification renvoyées par le serveur d’autorisation à l’utilisateur peuvent être codées en tant que JWT. Si le serveur d’autorisation autorise les connexions via un fournisseur d’identité (comme c’est le cas dans cet exemple), on peut dire que le serveur d’autorisation fournit une interface unifiée et des données unifiées (le JWT) à l’utilisateur.

Pour notre exemple plus loin dans cette section, nous utiliserons Auth0 comme serveur d’autorisation et gérerons les connexions via Twitter, Facebook et une base de données utilisateur courante.

Tokens D’Accès Et D’Actualisation

Les tokens d’accès et d’actualisation sont deux types de jetons que vous verrez souvent lors de l’analyse de différentes solutions d’identité fédérée. Nous allons expliquer brièvement ce qu’ils sont et comment ils aident dans le contexte de l’authentification et de l’autorisation.

Les deux concepts sont généralement implémentés dans le contexte de la spécification OAuth2. La spécification OAuth2 définit une série d’étapes nécessaires pour fournir l’accès aux ressources en séparant l’accès de la propriété (en d’autres termes, cela permet à plusieurs parties ayant des niveaux d’accès différents d’accéder à la même ressource). Plusieurs parties de ces étapes sont définies par l’implémentation. Autrement dit, les implémentations OAuth2 concurrentes peuvent ne pas être interopérables. Par exemple, le format binaire réel des tokens n’est pas spécifié. Leur but et fonctionnalité est:

Les tokens d’accès sont des tokens qui donnent accès à des ressources protégées à ceux qui les ont. Ces tokens sont généralement de courte durée et peuvent comporter une date d’expiration intégrée. Ils peuvent également porter ou être associés à des informations supplémentaires (par exemple, un token d’accès peut porter l’adresse IP à partir de laquelle les requêtes ont été autorisées). Ces données supplémentaires sont définies par l’implémentation.

Les tokens d’actualisation quant à eux,  permettent aux clients de demander de nouveaux tokens d’accès. Par exemple, après l’expiration d’un token d’accès, un client peut effectuer une requête pour un nouveau jeton d’accès au serveur d’autorisation. Pour que cette requête soit satisfaite, un token d’actualisation est requis. Contrairement aux tokens d’accès, les tokens d’actualisation sont généralement de longue durée.

JWT Tokenns D'accès et D'actualisation
Image: Tokenns D’accès et D’actualisation

L’aspect clé de la séparation entre les Tokens d’accès et ceux de rafraîchissement réside dans la possibilité de rendre les tokens d’accès faciles à valider. Un token d’accès portant une signature (telle qu’un JWT signé) peut être validé par le serveur de ressources seul. Il n’est pas nécessaire de contacter le serveur d’autorisation à cette fin.

Par contre, les tokens de rafraîchissement nécessitent un accès au serveur d’autorisation. En conservant la validation distincte des requêtes au serveur d’autorisation, une meilleure latence et des modèles d’accès moins complexes sont possibles. Une sécurité appropriée en cas de fuites de tokens est obtenue en rendant les tokens d’accès aussi éphémères que possible et en y intégrant des contrôles supplémentaires (tels que des contrôles clients).

Les tokensde rafraîchissement, en raison de leur longévité, doivent être protégés contre les fuites. En cas de fuite, une liste noire peut être nécessaire dans le serveur (les tokens d’accès de courte durée forcent les tokens d’actualisation à être utilisés, protégeant ainsi la ressource après sa mise sur liste noire et tous les tokens d’accès expirés).

Notez bien que: les concepts de token d’accès et de token d’actualisation ont été introduits dans OAuth2. OAuth
1.0 et 1.0a utilisent le mot token différemment

JWT et OAuth2

Bien que OAuth2 ne mentionne pas le format de ses jetons (tokens), les JWT correspondent bien à ses exigences. Les JWT signés font de bons tokens d’accès, car ils peuvent encoder toutes les données nécessaires pour différencier les niveaux d’accès à une ressource, peuvent porter une date d’expiration et sont signés pour éviter les requêtes de validation sur le serveur d’autorisation. Plusieurs fournisseurs d’identité fédérés émettent des jetons d’accès au format JWT.

Les JWT peuvent également être utilisés pour les tokens d’actualisation. Cependant, il y a moins de raisons de les utiliser à cette fin. Comme les tokens d’actualisation nécessitent un accès au serveur d’autorisation, la plupart du temps, un simple UUID suffira, car il n’est pas nécessaire que le token transporte une charge utile (elle peut cependant être signée).

JWT et OpenID Connect

OpenID Connect est un effort de standardisation visant à faire apparaître les cas d’utilisation typiques d’OAuth2 sous une spécification commune et bien définie. Comme de nombreux détails derrière OAuth2 sont laissés au choix des implémenteurs, OpenID Connect tente de fournir des définitions appropriées pour les parties manquantes. Plus précisément, OpenID Connect définit une API et un format de données pour effectuer des flux d’autorisation OAuth2. En outre, il fournit une couche d’authentification construite au-dessus de ce flux. Le format de données choisi pour certaines de ses parties est JSON Web Token. En particulier, le token ID est un type spécial de jeton qui contient des informations sur l’utilisateur authentifié.

Flux OpenID Connect Et JWTs

OpenID Connect définit plusieurs flux qui renvoient des données de différentes manières. Certaines de ces données peuvent être au format JWT.

  • Flux d’autorisation: le client demande un code d’autorisation au point de terminaison d’autorisation (/ authorize). Ce code peut être utilisé contre le point de terminaison de token (/ token) pour demander un token d’identification (au format JWT), un token d’accès ou un token d’actualisation.
  • Flux implicite: le client demande des tokens directement à partir du point de terminaison d’autorisation (/ authorize). Les tokens sont spécifiés dans la requête. Si un token d’identification est demandé, il est renvoyé au format JWT.
  • Flux hybride: le client demande à la fois un code d’autorisation et certains tokens du point de terminaison d’autorisation (/ authorize). Si un token d’identification est demandé, il est renvoyé au format JWT. Si un token d’identification n’est pas demandé à cette étape, il peut ensuite être demandé directement à partir du point de terminaison de token (/ token).

Exemple

Pour cet exemple, nous utiliserons Auth0 comme serveur d’autorisation. Auth0 permet de définir dynamiquement des fournisseurs d’identité différents. En d’autres termes, chaque fois qu’un utilisateur tente de se connecter, les modifications apportées au serveur d’autorisation peuvent permettre aux utilisateurs de se connecter avec différents fournisseurs d’identité (tels que Twitter, Facebook, etc.). Les applications n’ont pas besoin de s’engager auprès de fournisseurs spécifiques une fois déployés. Donc, notre exemple peut être assez simple. Nous avons configuré l’écran de connexion Auth0 en utilisant la bibliothèque Auth0.js dans tous nos serveurs d’échantillons. Une fois qu’un utilisateur se connecte à un serveur, il aura également accès aux autres serveurs (même s’ils ne sont pas interconnectés).

JWT Auth0 en tant que serveur d'autorisation
Image: Auth0 en tant que serveur d’autorisation

La configuration de la bibliothèque Auth0 peut être effectuée comme suit. Nous utiliserons le même exemple que celui utilisé pour l’exemple des sessions sans état:

const auth0 = new window.auth0.WebAuth({
domain: domain,
clientID: clientId,
audience: 'app1.com/protected',
scope: 'openid profile purchase',
responseType: 'id_token token',
redirectUri: 'http://app1.com:3000/auth/',
responseMode: 'form_post'
});
// (...)
$('#login-button').on('click', function(event) {
auth0.authorize({
prompt: 'none'
});
});

Notez l’utilisation du paramètre prompt: ‘none‘ pour l’appel authorize. authorize call (L’appel authorize) redirige l’utilisateur vers le serveur d’autorisation. Avec le paramètre ‘none‘, si l’utilisateur a déjà donné l’autorisation à une application d’utiliser ses informations d’identification pour accéder à une ressource protégée, le serveur d’autorisation redirigera simplement vers l’application.

Dans notre exemple, il existe deux applications: app1.com et app2.com. Une fois qu’un utilisateur a autorisé les deux applications (ce qui n’arrive qu’une seule fois: la première fois que l’utilisateur se connecte), toute connexion ultérieure à l’une des deux applications permettra également à l’autre application de se connecter sans présenter d’écran de connexion.

Pour tester cela, consultez le fichier README de l’exemple situé dans le répertoire samples/single-sign-on-federated-identity pour configurer les deux applications et les exécuter. Une fois que les deux sont en cours d’exécution, accédez à app1.com:3000 et app2.com:3001 et connectez-vous. Puis déconnectez-vous des deux applications. Maintenant, essayez de vous connecter à l’un d’entre eux. Puis retournez à l’autre et connectez-vous. Vous remarquerez que l’écran de connexion sera absent dans les deux applications. Le serveur d’autorisation se souvient des connexions précédentes et peut émettre de nouveaux tokens d’accès à la demande de l’une de ces applications. Ainsi, tant que l’utilisateur a une session de serveur d’autorisation, il est déjà connecté aux deux applications.

La mise en œuvre des techniques d’atténuation CSRF est laissée en exercice pour le lecteur.

LAISSER UN COMMENTAIRE

Please enter your comment!
Please enter your name here