Autorisation des utilisateurs et considérations de planification connexes pour votre mise en œuvre de B2B IAM.
Commençons par prendre un peu de recul pour parler du contrôle d’accès. Il n’existe pas de définition unique et parfaitement tranchée du contrôle d’accès dans l’industrie, mais si vous prenez le temps de faire quelques recherches, vous constaterez que la plupart des sources faisant autorité s’entendent pour dire qu’il s’agit du concept global qui regroupe l’authentification, l’autorisation, le consentement et l’application des politiques afin de garantir que seules les bonnes personnes et les bons services ont accès à vos applications et à vos API.Examinons maintenant de plus près les distinctions entre l’authentification, l’autorisation, le consentement et l’application des politiques. Votre tenant Auth0 (votre ) est généralement responsable de l’authentification et du consentement, ainsi que d’une partie ou de la totalité de l’autorisation et de l’application des politiques. De plus, une Application ou une API est presque toujours le principal mécanisme d’application des politiques, surtout lorsqu’un accès contextuel est requis :
Authentification : le processus qui consiste à déterminer si un principal (un utilisateur ou une application) est bien celui ou celle qu’il ou elle prétend être.
Autorisation : le processus qui consiste à déterminer ce qui est permis, en fonction du principal, des permissions qui lui ont été accordées et/ou de l’ensemble des critères d’accès propres au contexte.
Consentement : les permissions que l’utilisateur () a accordées à une application pour agir en son nom. Il s’agit généralement d’une exigence de l’autorisation déléguée. L’utilisateur doit autoriser le client à accéder à ses données dans un autre système.
Application des politiques : l’application des politiques de l’application ou de l’API, qui consiste à refuser ou à autoriser l’accès en fonction des renseignements d’authentification et/ou d’autorisation d’un utilisateur.
En règle générale, nous regroupons les différents types de contrôle d’accès en trois catégories distinctes afin de mieux comprendre a) quel acteur est responsable du stockage de l’information, b) quel acteur est responsable de la prise de décisions, et c) lequel est responsable de l’application des restrictions.
La première catégorie correspond aux cas où l’accès à une application ou à une API, dans son ensemble, est soit accordé, soit refusé. Les données nécessaires à cette application ainsi que le processus d’application lui-même sont généralement définis dans le contexte du serveur d’autorisation. Par exemple, en utilisant app_metadata associé à un utilisateur et une Action définie dans votre tenant Auth0.
La deuxième catégorie correspond aux cas où l’accès à un sous-ensemble précis des fonctionnalités d’une application ou d’une API est soit accordé, soit refusé. Les données nécessaires à cette application sont généralement stockées dans le serveur d’autorisation. Par exemple, en utilisant app_metadata pour un utilisateur dans votre tenant Auth0, tandis que l’application des politiques est assurée par l’application ou l’API elle-même. Dans ce scénario, les données sont généralement transmises sous forme d’une ou de plusieurs claims personnalisées dans un jeton id ou access.
La troisième catégorie correspond aux cas où l’accès est soit accordé, soit refusé selon ce sur quoi le principal (subject) peut agir dans le contexte d’une application ou d’une API. Les données nécessaires à cette application, de même que le processus d’application lui-même, sont généralement définis dans le contexte de l’application ou de l’API. Dans ce scénario, les données transmises sous forme d’une ou de plusieurs claims personnalisées dans un jeton id ou access peuvent être utilisées avec ou sans données provenant d’une source externe autre qu’Auth0.
De plus, les mécanismes de contrôle d’accès basé sur les rôles (RBAC) et de contrôle d’accès basé sur les attributs (ABAC) peuvent être appliqués dans n’importe laquelle des catégories de contrôle d’accès décrites ci-dessus. Quel que soit votre cas d’utilisation, vous devrez tenir compte d’un certain nombre d’éléments lorsque vous évaluerez les fonctionnalités et le workflow dont vous avez besoin :
Existe-t-il des scénarios où l’accès à une application entière ou à une API devrait être rejeté ?
Allez-vous fournir des API auxquelles des applications tierces pourront accéder ?
Vos API seront-elles aussi accessibles par vos propres applications (first-party) ?
Votre application appellera-t-elle une API tierce ?
Vos applications et/ou API devraient-elles appliquer le contrôle d’accès en fonction des claims de l’utilisateur ?
Que faire si j’ai besoin de savoir à quelle organisation un ou un est associé ?
Auth0 prend en charge la restriction d’accès aux applications ou aux API selon certaines conditions. Dans certains cas, vous pourriez vouloir créer une Action qui retourne une UnauthorizedError lorsque, par exemple, un utilisateur tente d’accéder à une application ou à une API au mauvais moment (comme décrit dans cet exemple) — ou si l’utilisateur n’a pas le ou les bons claims dans son app_metadata. Pour une application qui utilise OpenID Connect (OIDC), cela empêcherait l’émission du jeton d’identité servant à autoriser l’accès. De même, pour une API, l’émission de tout jeton d’accès OAuth2 (utilisé lors d’une requête à l’API) pourrait être empêchée, comme décrit dans cet exemple.
De façon générale, nous avons constaté qu’OIDC est le protocole standard de l’industrie le plus couramment utilisé par les clients d’Auth0 pour l’authentification dans leurs applications. Nous avons aussi constaté que, même si OAuth2 a été créé comme protocole de délégation, il est couramment utilisé dans les applications first-party lorsqu’il existe une API qui ne partage pas de session avec l’application.
Auth0 peut aussi fournir les informations nécessaires pour qu’une application puisse appliquer des restrictions. Pour l’intégration au niveau de l’application, Auth0 vous permet d’ajouter des claims personnalisés à un jeton d’identité, que votre application peut ensuite vérifier et utiliser pour l’application des politiques. Dans ce cas, vous devrez déterminer de quelles informations votre application a besoin pour prendre ces décisions. Si vous devez prendre des décisions au niveau d’une API plutôt que dans votre application, vous devrez probablement utiliser un jeton d’accès plutôt qu’un jeton d’identité. Poursuivez votre lecture pour en savoir plus.
Lorsque vous décidez quelles données inclure dans votre jeton d’identité et/ou votre jeton d’accès, tenez compte de la taille du jeton, surtout si vous le transmettez dans l’URL. Même si vous ne transmettez pas de jeton dans l’URL, vous devrez aussi tenir compte du risque d’exposer des PII (renseignements personnels identifiables) sensibles. Les informations contenues dans un jeton ne sont pas chiffrées ; ainsi, même si la divulgation d’un jeton d’identité ne constitue généralement pas un problème de sécurité, cela peut devenir un enjeu de confidentialité selon les données incluses dans le jeton.
Pour l’intégration au niveau de l’API, Auth0 prend en charge à la fois les claims personnalisés et la reconfiguration des scopes, tous deux dans le contexte d’un jeton d’accès. Encore une fois, vous devrez déterminer quelles informations seront nécessaires pour que votre API puisse prendre des décisions d’accès, et votre API devra les appliquer en validant le contenu du jeton d’accès.
Lorsque vous évaluez si vous devriez utiliser des permissions au moyen de claims personnalisés ou de scopes, vous devez vous assurer de bien comprendre la nature et l’objectif des scopes. Il existe un excellent article de blogue à ce sujet : il est facile à lire et aide à clarifier la question.
Dans les scénarios impliquant plusieurs organisations, il peut souvent être important de savoir à quelle organisation un jeton d’accès (ou même un jeton d’identité) s’applique. En prenant soin de suivre les bonnes pratiques, vous pouvez économiser temps et efforts.
Dans ce scénario, votre tenant Auth0 fournit un jeton comme preuve d’accès autorisé à une application. Pour les applications qui utilisent OpenID Connect (OIDC), le protocole standard de l’industrie que nous observons généralement le plus souvent dans les applications destinées aux clients, il s’agirait d’un jeton d’identité présenté sous forme de JWT.
Grâce à la fonctionnalité Actions, Auth0 vous permet d’ajouter facilement des claims personnalisées à un jeton d’identité en fonction, par exemple, du contenu des métadonnées d’un utilisateur. Votre application peut ensuite vérifier que l’jeton d’identité contient les claims nécessaires, puis autoriser ou refuser l’accès à certaines fonctionnalités, selon le cas. Notez que, même si le processus d’ajout de claims personnalisées au moyen d’Actions est simplifié, la fonctionnalité Actions est souple et vous permet d’écrire du code personnalisé qui peut avoir des effets indésirables.
Si vous envisagez d’ajouter des claims personnalisées, nous vous recommandons de stocker dans les app_metadata de l’utilisateur toutes les données de contrôle d’accès que vous pourriez devoir inclure dans ces claims. D’abord, cela vous évite d’avoir à effectuer une requête vers une API externe pour récupérer ces données, ce qui peut nuire aux performances et à l’évolutivité de la séquence de connexion. Ensuite, les app_metadatane peuvent pas être modifiées par un utilisateur; celui-ci ne peut donc pas contourner directement les restrictions de contrôle d’accès en modifiant ses propres métadonnées. N’oubliez pas non plus de consulter nos conseils sur les bonnes pratiques relatives aux métadonnées.
Si vous créez différentes instances de votre application pour les organisations de vos clients, une pratique courante consiste à créer une claim personnalisée dans votre jeton d’identité pour représenter l’organisation de l’utilisateur. Par exemple :
Les scopes OIDC sont généralement utilisés par une application pour obtenir le consentement permettant d’accéder aux renseignements d’un utilisateur pendant l’authentification. Chacun des scopes prédéfinis renvoie l’ensemble des claims standard, lorsqu’ils sont définis, comme décrit dans la spécification OIDC. Les scopes qu’une application demande dépendent des attributs utilisateur dont elle a besoin. Une fois les scopes demandés autorisés par l’utilisateur, les claims sont renvoyés dans le jeton d’identité et sont également accessibles par l’endpoint /userinfo.
Dans ce scénario, votre tenant Auth0 peut fournir un OAuth2 jeton d’accès, généralement présenté sous la forme d’un JWT, que votre API peut utiliser pour restreindre l’accès à certaines parties. De plus, Auth0 offre un soutien pour ce qu’on décrit généralement comme des applications propriétaires et des applications tierces.En agissant comme serveur d’autorisation, et avec le consentement de l’utilisateur (le propriétaire de la ressource), votre tenant Auth0 peut fournir un jeton d’accès — généralement présenté sous la forme d’un JWT — à une application (client) afin qu’elle puisse accéder à des ressources protégées hébergées par un au nom du propriétaire de la ressource. Le jeton d’accès émis est généralement transmis comme jeton Bearer dans l’en-tête HTTP Authorization envoyé à une API.Que vous ayez une seule API ou une suite d’API de microservices logiquement liées, vous pouvez tirer parti des jetons d’accès qu’Auth0 fournit afin de sécuriser l’accès à votre ou vos services. Bien qu’il soit relativement facile de configurer cela dans le Auth0 Dashboard ou par l’entremise de l’Auth0 Management API, il est important d’examiner les différents scénarios d’application et architectures d’API afin de déterminer la meilleure architecture pour votre système.
Les jetons d’accès OAuth2 sont principalement conçus pour sécuriser les API exposées au public ; lorsqu’il est présenté sous la forme d’un JWT, un jeton d’accès est une entité autonome qui peut être vérifiée sans qu’il soit nécessaire d’effectuer un appel d’API tiers supplémentaire. Si vos API n’entrent pas dans cette catégorie — c.-à-d. qu’elles font partie de l’application elle-même (autrement dit, qu’elles sont appelées uniquement par cette application) ou qu’elles se trouvent derrière votre pare-feu — alors les protéger avec des jetons pourrait fort bien être excessif, et votre flux de travail actuel basé sur des cookies (entre autres) pourrait très bien suffire.
OAuth2 a été conçu spécifiquement en tenant compte de l’accès par des tiers. Par exemple, il se peut qu’un utilisateur (propriétaire de la ressource) veuille utiliser une application (un client) qui n’appartient pas à la même organisation que le service qui fournit les données de l’utilisateur (le serveur de ressources). Dans ce cas, lorsque l’application doit accéder à des données appartenant à l’utilisateur, elle redirige vers l’organisation où résident les données de l’utilisateur, qui authentifie alors l’utilisateur puis l’invite à autoriser l’application à accéder à ses données. Cette demande d’autorisation est appelée consentement et constitue une grande partie de ce qu’implique le soutien des applications tierces. Si vous prévoyez intégrer des applications tierces, il est important de les marquer comme tierces dès le départ afin qu’Auth0 gère l’invite de consentement de l’utilisateur.D’un autre côté, si votre organisation est propriétaire de la ou des applications, des données utilisateur elles-mêmes et de la ou des API par lesquelles ces données sont accessibles, alors le consentement n’est généralement pas requis, puisque les interactions sont toutes propriétaires. Si vous créez uniquement des applications propriétaires, vous pouvez alors vous assurer de ne pas présenter à vos utilisateurs d’écran(s) de consentement inutile(s) en autorisant l’omission du consentement de l’utilisateur dans le cadre de toute définition de serveur de ressources.
Bien que vous puissiez configurer vos applications comme propriétaires et configurer ensuite vos API pour permettre aux clients propriétaires d’ignorer le consentement, si vous utilisez localhost, Auth0 ne peut pas vérifier que l’application est réellement une application propriétaire, de sorte que vos utilisateurs seront quand même invités à donner leur consentement. Pour contourner cette contrainte, lorsque vous testez sur votre machine locale pendant le développement, créez un faux nom d’hôte local et utilisez-le à la place.
Comme pour les ID Tokens, vous pouvez ajouter des claims personnalisés aux jetons d’accès à l’aide de la fonctionnalité d’extensibilité Auth0 Actions. Une fois ajoutés, votre API peut vérifier si un jeton d’accès contient les claims requis et autoriser ou refuser l’accès à certaines fonctionnalités, selon le besoin.
Si vous envisagez d’ajouter des claims personnalisés, nous vous recommandons de stocker dans le app_metadata de l’utilisateur toutes les données de contrôle d’accès que vous pourriez devoir inclure dans les claims. D’abord, cela évite d’avoir à effectuer une requête vers une API externe pour récupérer ces données, ce qui peut nuire aux performances et à l’évolutivité. Ensuite, app_metadatane peut pas être modifié par l’utilisateur; celui-ci ne peut donc pas contourner directement les restrictions de contrôle d’accès en modifiant ses propres métadonnées. N’oubliez pas non plus de consulter nos bonnes pratiques relatives aux métadonnées.
Les scopes OAuth2 servent généralement de mécanisme permettant à une API de déterminer quelles actions peuvent être effectuées au nom d’un utilisateur. Des scopes peuvent être ajoutés pour chaque API afin de définir des permissions d’accès précises dans le ou au moyen de l’Auth0 ). Les scopes peuvent aussi être modifiées au moyen de l’extensibilité Auth0 (p. ex. à l’aide d’une Action, comme dans cet exemple). Les scopes qu’une application demande pour accéder à une API devraient dépendre des fonctionnalités pour lesquelles l’utilisateur doit autoriser l’application. Une fois les scopes demandées autorisées, elles seront renvoyées dans le jeton d’accès, qui pourra ensuite être validé par l’API en question. Un bon exemple est lorsque vous vous connectez à une application qui utilise un fournisseur social pour la connexion : l’API du fournisseur social exige que l’application précise si l’utilisateur veut l’autoriser à publier du contenu en son nom. Cela permet à l’utilisateur d’accepter ou de rejeter cette requête. Cet exemple montre comment l’utilisateur délègue une permission à l’application — ce qui diffère d’une API qui restreint l’accès selon le rôle d’un utilisateur et devrait être géré différemment.
Même si vous pouvez manipuler entièrement les scopes du jeton d’accès au moyen de l’extensibilité Auth0, par souci de sécurité, vous ne devriez supprimer que les scopes non autorisées et vous abstenir d’ajouter des scopes qui n’ont pas été demandées.
Bien que les scopes soient souvent utilisées pour appliquer des permissions d’accès à un utilisateur, il existe des situations où cela peut devenir délicat lorsqu’on les utilise de cette façon. Nous recommandons donc d’utiliser les scopes aux fins prévues (c.-à-d. déléguer une permission à une application) et d’utiliser des custom claims pour vos scénarios fondés sur les rôles ou d’autres scénarios de contrôle d’accès.
L’autorisation fine vous permet d’accorder à des utilisateurs un accès à une ressource ou à un objet précis en fonction de :
du rôle de l’utilisateur au sein d’une organisation, comme editor ou admin
d’un attribut de l’utilisateur ou de l’objet, comme manager pour un utilisateur ou marketing pour un objet
d’une relation entre un utilisateur et un objet; par exemple, un utilisateur ayant un accès en consultation à un dossier parent a aussi un accès en consultation au dossier enfant
Avec , vous pouvez créer un modèle d’autorisation pour définir la relation à utiliser afin de déterminer l’accès des utilisateurs.
Auth0 offre une prise en charge intégrée du contrôle d’accès basé sur les rôles (RBAC). Le RBAC consiste à attribuer des permissions aux utilisateurs en fonction de leur rôle au sein d’une organisation et simplifie le contrôle d’accès en proposant une approche plus facile à gérer et moins sujette aux erreurs.La fonctionnalité RBAC de base peut être utilisée dans de nombreux scénarios impliquant plusieurs organisations. Consultez Données d’organisation dans un jeton d’accès pour en savoir plus sur la façon de vous assurer que votre configuration peut répondre à vos besoins en matière de RBAC.
De nombreux scénarios exigent qu’une application, sans aucune session utilisateur interactive, obtienne un jeton d’accès pour effectuer une requête à une API. Dans ce type de scénario, vous devez authentifier le client plutôt que l’utilisateur, et 2 fournit le type d’octroi client credentials, ce qui simplifie grandement la tâche. Voici quelques exemples courants où cela s’applique :
Une tâche cron ou un autre service qui doit communiquer avec votre API (p. ex. lorsqu’un rapport quotidien doit être généré et envoyé par courriel à un administrateur).
Une API distincte qui prend en charge un accès privilégié (p. ex. l’API n’est pas exposée directement aux utilisateurs, mais uniquement à un backend).
Dans certaines architectures de microservices, où certaines couches d’API doivent communiquer avec d’autres couches d’API sans intervention d’un utilisateur, ou après l’expiration du jeton d’un utilisateur.
Une API privilégiée qui peut devoir être appelée avant qu’un utilisateur soit authentifié (c.-à-d. à partir d’une Action ou d’un script de base de données personnalisé dans votre tenant Auth0)
Traditionnellement, on créait un « compte de service » spécial pour ce type de scénario : un utilisateur doté d’un nom d’utilisateur et d’un mot de passe, configuré pour des services prenant en charge des cas d’utilisation non interactifs. Cette approche n’est toutefois plus recommandée pour plusieurs raisons, et la bonne pratique actuelle consiste à utiliser l’octroi OAuth 2.0 Client Credentials Grant dans ces situations.
Si, dans votre système, vous avez une API distincte de votre application qui prend en charge votre application multi-organisation, il est important de limiter les opérations uniquement à l’organisation pour laquelle le jeton a été généré. Pour ce faire, le jeton d’accès doit contenir une forme d’information indiquant à l’API pour quelle organisation il a été émis. Cela peut se faire de différentes façons, selon les réponses à quelques questions simples :
Les utilisateurs finaux de cette organisation pourraient-ils appartenir à plus d’une organisation, ou chaque utilisateur final est-il limité à une organisation précise ?
Allez-vous autoriser un accès machine à machine (M2M) à votre API ?
Si vous autorisez un accès machine à machine (M2M) à votre API, aurez-vous des développeurs qui ont besoin d’un seul Client ID et secret pour accéder à plusieurs organisations (mais pas à toutes les organisations) ?
Allez-vous autoriser la création d’applications tierces nécessitant un consentement ?
Si les utilisateurs finaux sont limités à une seule organisation et que vous n’autoriserez pas l’accès M2M à votre API, ou que vous aurez un /secret distinct pour chaque organisation qui a besoin d’un accès et que vous n’autoriserez pas les applications tierces nécessitant un consentement, l’approche la plus simple consiste à créer un custom claim dans le jeton d’accès à l’aide d’Actions pour les jetons basés sur l’utilisateur et à l’aide du hook client credentials pour les requêtes M2M. Vous pouvez stocker le nom de l’organisation dans les client metadata et l’extraire à partir d’Actions ou de hooks afin de l’inclure dans access_token comme custom claim. RBAC fonctionnera également d’emblée avec cette approche, tant que chaque utilisateur final ne peut appartenir qu’à une seule organisation.Si les utilisateurs finaux peuvent appartenir à plus d’une organisation ou si vous pourriez donner à un même développeur un Client ID et un secret pour des requêtes M2M vers plus d’une organisation, la meilleure approche consiste à créer une distincte (une instance d’API distincte dans votre tenant Auth0) pour chaque organisation. Cela vous donne quelques avantages intéressants :
D’abord, cela vous permet de transmettre l’audience à Auth0 comme paramètre de premier ordre, sans avoir à créer un paramètre personnalisé. L’avantage, c’est qu’Auth0 vous aidera à en assurer la présence et la transmettra à vos Actions. Cela garantit aussi qu’un refresh token émis ne fonctionnera que pour l’audience précise pour laquelle il a été émis au départ.
Cela vous permet de restreindre les client grants à des organisations précises, sans configuration supplémentaire. L’autre possibilité consiste à créer un hook client credentials plus complexe pour tenter de récupérer les restrictions ailleurs, tout en exigeant aussi un moyen beaucoup plus complexe et potentiellement problématique d’indiquer à la requête client credentials pour quelle organisation émettre le jeton d’accès.
Cela vous permet aussi d’utiliser la fonctionnalité RBAC de base avec Auth0 et de vous assurer que les utilisateurs finaux qui ont accès à plus d’une organisation peuvent avoir un rôle différent pour chaque organisation.
Nous offrons un guide de planification en format PDF que vous pouvez télécharger et consulter pour en savoir plus sur nos stratégies recommandées.Guide de planification de projet B2B IAM
Architecture à organisations multiples (multilocataire)
De nombreuses plateformes B2B mettent en œuvre une forme d’isolation et/ou d’image de marque pour l’organisation de leurs clients, ce qui peut complexifier tout système de gestion des identités et des accès (IAM). Si c’est votre cas, nous vous recommandons de prendre le temps de consulter nos lignes directrices et nos conseils sur les pratiques exemplaires pour ce type d’environnement.Architecture à organisations multiples