MSGraph API – Monitor Certificats et Secrets d’AzureAD avec Powershell

Avec l’augmentation des migrations des solutions de SSO telle qu’ADFS vers les Applications AzureAD, je suis de plus en plus confronté à la nécessité de monitorer l’expiration des certificats ou des secrets dans AzureAD.

Excepté l’envoie d’un mail quelque temps avant l’expiration de ceux-ci, je n’ai pas encore trouvé de solution de monitoring au sein de la suite M365.

Il est toujours possible d’obtenir ce type d’information par le biais en utilisant Powershell et le module AzureAD. Mais ces méthodes nécessites une authentification utilisateur.

D’après les annonces de Microsoft, l’authentification de type “basic” devrait s’arrèter d’ici le second semestre 2121.

Il est donc temps de commencer à utiliser dans nos scripts d’industrialisation, monitoring une authentification moderne et d’utilier l’API Microsoft.

Dans ce post, nous allons créer une application AzureAD, accorder l’accès à cette application à l’API MS Graph et interroger l’API via Powershell. 

Nous allons utiliser l’authentification par secret, qui selon moi se prête le mieux dans ce contexte. Un script de monitoring lancé de manière récurrente par un service sans action utilisateur.

Dans le cas d’un script lancer manuellement par un utilisateur, le choix de la méthode d’authentification est différente.

Sommaire

Création d'une application AzureAD

Dans cette partie, nous allons nous concentrer sur AzureAD. Nous allons voir ensemble la création de l’application, configurer l’accès à l’API puis comment générer un secret pour la connexion depuis un script.

Création de l'application

Pour commencer, se connecter sur l’environnement d’AzureAD :

https://aad.portal.azure.com/

Et se rendre dans la section “App registrations”.

App registrations

Enregister une nouvelle application en cliquant sur “New registration”.

New registration

Dans le menu d’enregistrement de nouvelle application, renseigner le nom de celle-ci, le type de compte supporté et l’URL de redirection.

Dans mon cas :

  • Name : Monitoring-AAD
  • Supported account type : Single tenant
  • Redirect URI : https://localhost

Puis pour finir, cliquer sur “Register”.

App infos

Notre application est désormais créée, place à la configurer de celle-ci.

Configuration des l'accès sur l'API Graph

Dans cette partie, nous allons autoriser l’application à accéder à une partie des informations disponible dans l’API Microsoft Graph.

Plus précisément, un accès en lecture seule (read) sur les applications enregistrées dans AzureAD.

Pour se faire se rendre dans la section “API permissions”.

API permissions

Puis cliquer sur “Add a permission” et sélectionner “Microsoft Graph”.

Add permissions --> Microsoft Graph

Comme expliquer au début, l’accès est réalisé par un script Powershell lancé depuis un outil de monitoring. L’accès est de type application. Sélectionner “Application permissions“.

Dans la liste des permissions, cocher “Application.Read.All”. Ce qui se résume à un accès aux informations des applications en lecture seule.

Un outil Microsoft “Graph API Explorer” permet de parcourir l’ensemble de l’API afin d’identifier les données donc vous avez besoin et tester vos requêtes.

Add permissions --> Microsoft Graph

Pour finir la configuration des accès à l’API, il est nécessaire d’obtroyer le consentement de l’aministrateur sur les droits donnés. Cliquer sur “Grant admin consent…” en haut de la page, puis valider.

Grant admin consent
Consent OK

L’accès en lecture sur les informations des application AzureAD est octroyées à notre application.

Création du secret pour l'authentification

Nous allons maintenant créer un secret qui permettra l’authentification à notre application.

Se rendre dans “Certificates & secrets” et créer un nouveau secret “New client secret”.

New client secret

Choisir la durée de vie du certificat (ici 1 an) et une description.

D’experience, il est préférable de créer un nouveau secret pour chaque script ou service nécessitant l’accès à l’application et d’utiliser une description permettant l’identification du composant qui utilise ce secret. Le renouvellement en sera facilité lors de l’expiration de celui-ci.

Dès lors que le secret est créé, récupérer immédiatement la valeur de celui-ci. Par la suite celle-ci ne sera plus consultable.

Récupération des informations nécessaire pour la suite

Avant de continuer et passer au code Powershell, nous allons récupérer les informations AzureAD donc nous aurons besoin pour générer les token d’autehntification.

Celle-ci sont :

  • Le Tenant ID

Le tenant ID est accessible à la racine de votre domaine AzureAD :

  • L’application ID ou Cilent ID

Cette valeur est soit noée ApplicationID soit ClientID, il s’agit de l’ID de l’application qui est accessible dans les informationd e votre application AzureAD :

  • Le secret

Celui-ca a été récupéré lors de ça création. Il n’est plus consultable par la suite.

Si vous avez perdu la valeur de celui-ci, supprimez le (si pas utilisé) et en créez un nouveau secret.

Accès à l'API via Powershell

Les scripts Powershell ci-dessous utilisent Graph API.

L’accès à l’API est réalisée par l’application AzureAD que nous avons créée précédemment.

Dans les cas ci-dessous, nous n’utiliseront que des méthodes “GET” pour de l’intérogation.

Les droits d’accès de l’application sur l’API ont été limité à de la lecture uniquement sur les applications.

Le choix que j’ai fait est de créer deux scripts distincts, le premier pour le monitoring des secrets /certificats de connexion aux applications, un second pour le monitoring des certificats SAML.

Comme expliqué précédemment, je préfère pour des raisons de maintenance utiliser un secret différents par scripts.

La constructions de ces deux scripts sont identique, à savoir :

  1. Création du token OAuth
  2. Interrogation de l’API
  3. Traitement de la donnée
Création du Token OAuth

Pour commencer, nous allons demander un token d’authentification auprès de Microsoft.

#Connection informations:
$ClientID = 'fab3490e-e922-46ee-bfe2-3825f9b01f37'
$ClientSecret = '6gGm~8~WH--1rIm-2U2n-7KB_yo-Y8sA7n'
$TenantID = '97c77cf4-XXXX-XXXX-XXXX-XXXXXXXXXXXXX'

$ReqTokenBody = @{
Grant_Type = 'client_credentials'
Scope = 'https://graph.microsoft.com/.default'
client_Id = $ClientID
Client_Secret = $ClientSecret
}

$TokenOAuth = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token" -Method POST -Body $ReqTokenBody

$TokenOAuth | FL
OAUTH Token

Voici ci-dessous la fonction constitué du code précédent afin d’être réutilisable simplement.

Function Get-OAuthGraphAPITocken{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)][string]$Resource,
[Parameter(Mandatory=$true)][string]$ClientID,
[Parameter(Mandatory=$true)][string]$ClientSecret,
[Parameter(Mandatory=$true)][string]$TenantID
)

$ReqTokenBody = @{
Grant_Type = 'client_credentials'
Scope = 'https://graph.microsoft.com/.default'
client_Id = $clientID
Client_Secret = $clientSecret
}

$TokenOAuth = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token" -Method POST -Body $ReqTokenBody

return $TokenOAuth
}

#Teddycorp
$cstClientID = 'fab3490e-e922-46ee-bfe2-3825f9b01f37'
$cstClientSecret = '6gGm~8~WH--1rIm-2U2n-7KB_yo-Y8sA7n'
$cstTenantID = '97c77cf4-XXXX-XXXX-XXXX-XXXXXXXXXXXXX'

$TokenOAuth = Get-OAuthGraphAPITocken -Resource $cstResource -ClientID $cstClientID -ClientSecret $cstClientSecret -TenantID $cstTenantID
Get-OAuthGraphAPITocken

Grace à cette fonction nous sommes en mesure de demander un token d’authentification pour accéder à notre application AzureAD.

Et par la même occasion de stocker ce token dans une variable afin de pouvoir l’utliser.

Interrogation de l'API

Depuis l’interface Graph API Explorer, il est possible de parcourir les données accessible via l’API et créer /tester les query.

Dans notre cas, les requêtes sont:

Liste des applications enregistrées “App regestration” :

https://graph.microsoft.com/v1.0/applications

Liste des application d’entreprise “Enterprise applications”

https://graph.microsoft.com/v1.0/servicePrincipals

Il est donc possible avant d’utiliser nos requêtes dans nos scripts de jouer nos requêtes afin de valider leurs bon fonctionnement et d’avoir leurs format de sortie.

Graph Explorer

Cette même requête depuis Powershell :

Powershell

Dans le retour, sont présent plusieurs champs donc deux particulièrement intéressants :

  • value : le résultat de la requête.
  • @odata.nextLink : qui correspond à l’URL contenant le reste des données demandés.

Par défaut le nombre de résultats est limité à 100, il est possible de modifier cette valeur à l’aide du paramètre $top dans la requête avec un max à 999. Ce qui signifie que lors d’une automatisation, il est systématiquement nécessaire de vérifier la valeur de la clef “@odata.nextLink” pour obtenir l’ensebles des données demandés. 

Ci-dessous deux liens vers la documentation Microsoft :

Pour en revenir à notre Powershell, l’intérogationn à l’API est réalisée à l’aide de la commande “Invoke-RestMethod”.

Voici un exemple :

Invoke-RestMethod -Headers @{Authorization = "$($TokenOAuth.token_type) $($TokenOAuth.access_token)"} -Uri 'https://graph.microsoft.com/v1.0/servicePrincipals' -Method Get

Comme je vous l’expliquais, il est parfois nécessaire d’intéroger plusieurs fois l’API pour avoir l’intégralitée des données (@odata.nextLink).

nous allons utiliser une fonction récursive afin de collecter l’ensemble de données :

Function Get-GraphAPIQuery{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]$TokenOAuth,
[Parameter(Mandatory=$true)][string]$apiUrlQuery
)

$Data = @()

$resQuery = Invoke-RestMethod -Headers @{Authorization = "$($TokenOAuth.token_type) $($TokenOAuth.access_token)"} -Uri $apiUrlQuery -Method Get
$Data += $resQuery.Value

while($resquery."@odata.nextLink"){
$resQuery = Invoke-RestMethod -Headers @{Authorization = "$($TokenOAuth.token_type) $($TokenOAuth.access_token)"} -Uri $resquery."@odata.nextLink" -Method Get
$Data += $resQuery.Value
}

return $Data
}

$strQueryURLAPI = "https://graph.microsoft.com/v1.0/applications"
Get-GraphAPIQuery -TokenOAuth $TokenOAuth -apiUrlQuery $strQueryURLAPI
Function Get-GraphAPIQuery

A l’aide de cette fonction et du token d’authenification, nous sommes désormais en mesure de nous connecter et obtenir les information depuis ‘API Graph.

Traitement de la donnée

Maintenant que nous avons l’ensemble de la donnée retournée par nos requêtes, nous allons pouvoir manipuler celle-ci à notre guise à l’aide de commandes Powershell traditionnelles (foreach et arrays).

Je vous laisses consulter le détail des scripts pour voir la méthode employée.

Les scripts

Voici les liens des scripts :

  • Audit secrets et certificats des application AAD :

https://github.com/BenoitNgs/GraphAPIMonitorSecretAAD

Secrets & certificats
SAML Certificats