Sur ce post, je partage un moyen d’obtenir un jeton JWT sur Entra en utilisant un certificat SSL client au lieu d’un secret stocké au niveau d’Entra.
Entra (anciennement Azure AD), offre une palette de fonctionnalités complète pour mettre en place des scénarios d’authentification Oauth 2.0. Vous pouvez consulter mes différentes publications à ce sujet :
Bien entendu, il est possible de combiner l’obtention du jeton JWT à l’aide d’un client/secret, et une authentification SSL mutuelle auprès de l’API ciblée (autrement dit, le service backend). Mais, il est également possible de se passer du secret pour obtenir le jeton d’accès, en utilisant le certificat pour s’authentifier auprès d’Entra.
Il est nécessaire de déclarer une App Registration client sur Entra. Il faut lui associer votre certificat SSL sur l’onglet « Certificats et secrets ». Le plus simple est de le réaliser via les écrans d’Entra au niveau du portail Azure. Evidemment, seule la clé publique doit être partagée avec Entra.
Assurez-vous que le certificat est destiné à la signature électronique. Dès lors que le certificat est associé au compte, il est possible de demander un jeton JWT.
J’ai configuré le flux OAuth 2.0 Client_Credentials et j’ai ajouté quelques autorisations sur l’API Graph pour ce client. Pour obtenir le jeton d’accès qui me liste mes autorisations sur l’API Graph, il est nécessaire de consommer le endpoint /token avec le corps suivant :
grant_type=client_credentials&client_id=<clientId>&scope=<scope>&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion=<client_assertion>
Les paramètres de la requête sont :
Il n’est pas nécessaire (et d’ailleurs pas possible) de présenter votre certificat client pour obtenir votre jeton ! Vous devez, au lieu de cela, générer une assertion JWT (assertion client), et la signer avec votre certificat. Cette assertion se compose :
Et se présente comme suit :
{ "alg": "RS256", "typ": "JWT", "x5t": "hOBcHZi846VCHSJbFAs26Go9VTQ" } . { "aud": "https: //login.microsoftonline.com/contoso.onmicrosoft.com/oauth2/v2.0/token", "exp": 1484593341, "iss": "<clientId>", "jti": "22b3bb26-e046-42df-9c96-65dbd72c1c81", "nbf": 1484592741, "sub": "97e0a5b7-d745-40b6-94fe-5f77d35c6e05" } . "Gh95kHCOEGq5{a lot of characters here}KKJDg"
Note : Le point qui sépare chaque partie est nécessaire.
Le header se compose des champs suivants :
Dès lors que vous avez généré votre entête et corps, vous devez le signer avec votre certificat. Bien entendu, il faut utiliser la clé privée de votre certificat pour réaliser cette opération. La signature résultant, garantira que votre assertion est conforme à ce que vous avez générée et n’a pas été altéré durant le transfert vers votre API cible.
Finalement, il est nécessaire de convertir votre message en assertion JWT.
Pour tester l’appel à Entra, j’utilise Postman. L’appel au endpoint /token avec les éléments énumérés précédemment me permettent d’obtenir un jeton d’accès avec un certificat au lieu d’un secret client.
Je vous conseille d’utiliser une ou plusieurs librairies qui génère automatiquement l’assertion à partir de vos éléments, par exemple MSAL.Net.