Série sur l'authentification (Partie 1) : Pratiques d'ingénierie d'application
March 8, 2024
Introduction
L'authentification des identités joue un rôle crucial dans la protection de l'accès aux données et de la vie privée des utilisateurs dans les applications internet, en particulier pour les applications internes des entreprises. Dans cette série d'articles, nous explorerons l'authentification des identités sous différents angles, en nous concentrant spécifiquement sur les pratiques d'authentification des identités dans l'ingénierie des applications dans cet article.
Dans diverses applications, l'authentification des identités utilise couramment les deux techniques suivantes :
-
Cookie & Session : Ce mécanisme d'authentification traditionnel est largement utilisé dans les applications web, principalement au sein des navigateurs. Il vérifie l'identité de l'utilisateur et maintient l'état de la session à l'aide de cookies et de sessions.
-
Bearer Token : Il s'agit d'un mécanisme d'authentification plus moderne qui élimine la dépendance aux cookies des navigateurs et utilise plutôt le protocole HTTP pour l'authentification. Il est particulièrement adapté aux scénarios d'API et peut être utilisé dans les applications mobiles.
Quelle que soit la méthode choisie, les développeurs doivent sélectionner l'approche d'authentification appropriée pour leurs produits afin de garantir la sécurité des données, la confidentialité des utilisateurs et une expérience utilisateur fluide.
Applications Web Traditionnelles
Dans le passé, nous utilisions Java JSP pour construire directement des applications web, en identifiant les utilisateurs à l'aide de JSESSIONID, un identifiant de session stocké dans un cookie sur le navigateur du client et transmis avec chaque requête.
Cependant, cette approche présentait certains problèmes. Étant donné que les cookies sont gérés et stockés sur l'appareil du client par le navigateur, des attaquants malveillants pouvaient voler l'identifiant de session stocké et usurper l'identité de l'utilisateur, ce qui posait un risque de sécurité. De plus, les développeurs avaient parfois du mal à définir des périodes d'expiration et des exigences de sécurité raisonnables pour les cookies et les sessions.
Lors du développement de ces applications, les développeurs devaient souvent implémenter l'authentification séparément pour chaque système, ce qui était indépendant et utilisait différents systèmes d'identité. Cela nécessitait un travail répétitif. Dans de tels cas, l'Authentification Unique (SSO) pouvait résoudre ces défis en utilisant un système d'authentification unifié, nécessitant un travail d'intégration minimal dans chaque application web individuelle pour réaliser la fonctionnalité d'authentification.
Ces dernières années, les technologies front-end et back-end ont fait des progrès rapides. Les développeurs ont commencé à migrer vers des piles technologiques plus modernes, laissant les applications alimentées par des technologies obsolètes comme des plateformes héritées. Cependant, il existe des cas où de nouvelles exigences de sécurité des identités surviennent, mais la modification de l'ancien code n'est pas réalisable. Dans de tels cas, une approche alternative consiste à utiliser un middleware fonctionnant comme un proxy inverse pour effectuer l'authentification. Avant que le client n'atteigne l'application, le middleware redirige l'utilisateur vers une interface d'authentification externe, où l'utilisateur se connecte. Le middleware obtient ensuite les informations d'identité de l'utilisateur et les attache à la requête avant de la transmettre à l'ancienne application. Cela permet aux développeurs d'ajouter de nouveaux mécanismes d'authentification aux anciennes applications sans modifier le code existant.
Évolution des Applications Web : Séparation du Front-End et du Back-End
Avec l'émergence de nouvelles technologies front-end telles que Vue et React, les interactions web ont été révolutionnées. Dans le passé, les utilisateurs devaient remplir et soumettre des formulaires sur les pages web, interagissant avec le back-end à l'aide de formulaires HTML et de boutons, ce qui ne fournissait pas une expérience utilisateur fluide. Désormais, les interactions sur la page sont en temps réel, et les développeurs utilisent des scripts JavaScript pour interagir avec les API back-end, offrant une expérience plus cohérente et continue. Les interactions des utilisateurs sont passées de requêtes HTTP directes à l'invocation de diverses API.
Il existe quelques différences dans les mécanismes d'authentification des identités entre les applications orientées page web et les applications orientées API. Bien que les anciens cookies puissent encore être utilisés, ils ne sont pas adaptés aux technologies front-end modernes. Les nouvelles technologies permettent aux développeurs d'écrire du code plus expressif, leur permettant d'effectuer plus d'opérations, y compris des scénarios où nous pourrions avoir besoin de changer de compte utilisateur sur le front-end. Cependant, la mise en œuvre directe de cela dans le front-end via des cookies est difficile (pour des raisons de sécurité, les cookies liés à l'identité de l'utilisateur sont souvent configurés comme httpOnly, empêchant les scripts JavaScript de les lire et de les manipuler).
Typiquement, les applications front-end modernes gèrent elles-mêmes les sessions des utilisateurs. Une fois qu'un utilisateur s'est connecté avec succès, le front-end gère le token généré par le back-end et l'ajoute à l'en-tête de la requête lors des appels d'API pour que le back-end identifie l'identité de l'utilisateur. Les API utilisent des tokens pour identifier les informations de l'utilisateur. Il existe divers moyens techniques disponibles, tels que la mise en œuvre manuelle de mécanismes de token à l'aide de JSON Web Tokens (JWT). La charge utile du JWT stocke des informations d'identification telles que l'ID de l'utilisateur, qui est ensuite signée pour permettre au back-end de vérifier le token et de récupérer les informations d'identité de l'utilisateur.
Cependant, JWT présente également quelques inconvénients, tels que :
-
Le temps d'expiration du JWT est fixe et ne peut pas être modifié une fois la signature terminée. Comme il n'est généralement pas stocké par le back-end et ne subit qu'une vérification de signature, il n'est pas possible de révoquer le token, ce qui pose un risque de vol de token.
-
Les données de la charge utile sont stockées en texte clair et peuvent être analysées par le client, ce qui les rend inadaptées au stockage d'informations confidentielles.
Heureusement, il existe désormais de nouvelles spécifications JWT pour remédier à ces lacunes. La charge utile du JWT peut inclure un champ appelé "jti" pour stocker un identifiant unique pour le JWT, qui peut être stocké dans le cache du back-end pour contrôler le cycle de vie du JWT. De plus, la spécification JSON Web Encryption (JWE) définit une extension de JWT chiffré qui combine les avantages du chiffrement asymétrique et symétrique, garantissant que la charge utile est transmise sous forme de texte chiffré pour éviter les fuites.
En outre, il existe d'autres technologies basées sur JWT qui fournissent des solutions plus matures, telles que OpenID Connect. Il est important de noter que OpenID Connect ne dépend pas de JWT, mais ils peuvent être utilisés ensemble. OpenID Connect standardise les mécanismes pour les tokens d'accès et les tokens de rafraîchissement, permettant aux développeurs d'utiliser des tokens à court terme pour atténuer le risque de vol de token. L'écosystème d'OpenID Connect est également florissant, avec de nombreuses implémentations de serveurs et de clients disponibles pour aider les développeurs à construire des systèmes d'authentification des identités basés sur le protocole OpenID Connect. De plus, des solutions open-source d'authentification des identités comme Keycloak peuvent aider les développeurs à mettre en œuvre des services d'authentification des identités sécurisés.
Les nouvelles pratiques technologiques front-end, telles que Next.js, introduisent progressivement des techniques de rendu côté serveur dans le domaine du front-end. Cela représente une nouvelle évolution de l'ancien paradigme de développement web, combinant React avec des programmes back-end pour améliorer encore l'expérience utilisateur. Il existe désormais plus de bibliothèques, telles que NextAuth, qui peuvent aider les développeurs à implémenter l'authentification des identités en utilisant ce mécanisme, rendant le processus d'authentification plus convivial pour les développeurs.
Passerelles API et Authentification des Identités
Considérons comment nos applications mobiles interagissent avec les données. Utilisent-elles également des API ? Dans les applications mobiles, il n'y a pas de mécanisme de cookie comme dans les navigateurs pour stocker les sessions des utilisateurs, elles utilisent donc principalement des tokens pour transmettre des informations via les en-têtes de requête HTTP.
Qu'en est-il des services API ? Un back-end d'application réussi est généralement composé de nombreux systèmes API complexes qui nécessitent un mécanisme d'authentification des identités unifié. Sinon, les développeurs devraient implémenter le même mécanisme d'authentification pour chaque service, ce qui serait fastidieux.
Les passerelles API peuvent nous aider à résoudre ce problème en gérant les tâches d'authentification et d'analyse similaires aux cookies ou aux tokens, et en transmettant directement les informations d'identité analysées aux services back-end, réduisant ainsi la duplication du travail. Apache APISIX et API7 Enterprise prennent également en charge la fonctionnalité d'authentification OpenID Connect prête à l'emploi, aidant les utilisateurs à intégrer directement les services d'authentification des identités. De plus, les passerelles API prennent en charge la mise en œuvre de tout mécanisme d'authentification via des scripts, donc même avec des mécanismes d'authentification des identités personnalisés, ils peuvent être intégrés sur la passerelle API, simplifiant ainsi le développement des applications.
Résumé
Le développement des méthodes d'interaction utilisateur a entraîné des avancées dans l'authentification des identités. L'approche centrée sur les API devient une tendance dominante, et les API peuvent être fournies par des architectures de microservices, nécessitant un mécanisme d'authentification des identités unifié pour réduire le développement redondant. Par conséquent, nous devrions choisir des mécanismes plus modernes tels qu'OpenID Connect et JWT, et l'utilisation d'une passerelle API peut fournir des fonctionnalités supplémentaires pour le développement d'API.