Introduction à l’API Graph de Microsoft
Microsoft Graph permet de se connecter à de nombreuses ressources liées à Office 365 (utilisateurs, discussions, calendriers, groupes, etc.)
La dénomination « Graph » vient du fait que toutes ces ressources sont interconnectées, formant un réseau d’objets.
Par exemple, pour un utilisateur donné, Graph permet d’accéder à ses messages, son calendrier, ses fichiers, mais également aux groupes auxquels il appartient. Cet utilisateur est également associé à un manager, à un ou plusieurs appareils (PC, téléphone, etc.), et d’autres choses encore…
Ces interconnexions permettent d’imaginer beaucoup de scénarii d’utilisation. Voici un exemple de représentation d’interconnexion entre les différentes zones :
À partir du principal point de terminaison (https://graph.microsoft.com), nous pouvons appeler n’importe quelle ressource disponible dont vous avez les autorisations. Cette URL se décompose en deux parties:
- Version de la méthode
- Nom de la Methode
Dans le tableau suivant, vous trouverez quelques exemples de points de terminaison :
Opération | Points de terminaison |
---|---|
Tous les utilisateurs de l’organisation | https://graph.microsoft.com/v1.0/users |
Répertorier les salles de conférences | https://graph.microsoft.com/beta/me/findRooms |
Tous les Groupes de mon organisation | https://graph.microsoft.com/v1.0/groups |
Membre du groupe | https://graph.microsoft.com/v1.0/groups/02bd9fd6-8f93-4758-87c3-1fb73740a315/members |
Mes contacts | https://graph.microsoft.com/v1.0/me/contacts |
Sachez que sur son site, Microsoft fournit toute une liste d’exemples permettant d’illustrer le potentiel de Graph, vous pouvez trouver plus d’information concernant ces utilisations à l’adresse suivante : https://developer.microsoft.com/en-us/graph/docs/concepts
Authentification
OAuth
OAuth est un protocole libre qui permet d’autoriser une application client à utiliser l’API sécurisée d’une autre application pour le compte d’un utilisateur.
L’intérêt majeur d’OAuth vient du fait que l’utilisateur n’a plus besoin de fournir ses informations d’identification à une application tierce, car la connexion se passe sur l’application de l’API.
Pour cette recette nous utiliserons OAuth pour fournir une authentification à notre Script/Module Powershell afin de pouvoir exécuter différentes actions d’administrations.
Ci-dessous un résumé des flux du protocole OAuth, ce qui vous permettra de mieux comprendre le scénario d’authentification & d’utilisation :
Pour plus d’information, je vous redirige vers la documentation officiel : https://oauth.net/getting-started
Application
Pour pouvoir mettre en oeuvre la suite de cette recette nous allons devoir effectuer la création d’une application Azure Active Directory, ce qui permettra à nos scripts d’être authentifiés via OAuth sur notre Tenant Office365.
Se connecter en tant qu’administrateur de son abonnement Azure (ou un compte avec des privilèges suffisants sur l’Azure Active Directory) sur le portail de gestion : https://portal.azure.com
La suite des opérations va consister à créer des credentials, c’est-à-dire les informations nécessaires à l’application OAuth2 pour s’authentifier auprès d’un abonnement Azure et y faire des opérations.
Cela nécessite de créer une application dans Azure Active Directory pour générer le client-id et le client-secret.
Aller dans la partie Azure Active Directory, sélectionner l’Azure Active Directory concerné et cliquer sur App registrations
Puis cliquer sur Endpoints.
Sur la ligne OAUTH 2.0 AUTHORIZATION ENDPOINT, récupérer le GUID dans l’URL proposée. Cette valeur sera le Tenant-id.
Fermer la lame et cliquer sur Add… pour enregistrer une nouvelle application auprès d’Azure Active Directory.
Donner un nom et une URL de Callback quelconque (car non utile dans notre situation) et sélectionner Web app / API dans la zone Application Type, enfin cliquer sur Create.
Cliquer ensuite sur l’application qui vient d’être enregistrée, sur cette interface sera affichée votre application ID correspondant à la valeur client-id.
La suite des opérations consiste à créer une nouvelle clé pour cette application.
Saisir une description et choisir une expiration (1 an, 2 ans ou pas d’expiration).
Cliquer sur Save.
L’interface va alors dévoiler un secret qui ne sera exposé qu’une seule fois (penser à faire un copier-coller avant de fermer la lame). Ce secret est la valeur client-secret.
!!! danger Attention, après avoir fermé la lame, la valeur de la clé ne sera pas récupérable. En cas de perte vous devrez donc recréer une nouvelle clef 😓
La définition des autorisations se fait à l’aide du menu Required permissions dans les propriétés de votre application. Pour connaitre les permissions à accorder je vous invite à vous référer à la documentation de la méthode que vous souhaiter exécuter.
Dans l’exemple ci-dessus, j’ai fourni bien trop d’autorisations a mon application, je vous recommande vivement de fournir uniquement les accès que vous avez besoin.
Exemple de script
Token
Cette simple fonction Powershell vous permettra d’effectuer une demande d’authentification auprès du Graph API, ce qui vous permettra par la suite de pouvoir exécuter des requêtes authentifiées.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function Get-OauthToken()
{
Param(
[String]$ClientID,
[String]$ClientSecret,
[String]$TenantID,
[String]$Scope="https://graph.microsoft.com/.default",
[String]$LoginURL="https://login.microsoftonline.com"
)
Try {
# Get an Oauth2 access token based on client id, secret and tenant domain
$body = @{grant_type="client_credentials";client_id=$ClientID;client_secret=$ClientSecret;scope=$Scope}
$oauth = Invoke-RestMethod -Method Post -Uri "$LoginURL/$TenantID/oauth2/v2.0/token" -Body $body
if ($oauth.access_token -ne $null) {
return $oauth
} else {
Throw [System.NotImplementedException]::New("Unable to find token : $oauth")
}
} Catch {
Throw [System.NotImplementedException]::New("Unable to get token : $_")
}
}
$Params = @{
ClientID = "0a658d35-XXXX-XXXX-XXXX-91b2679a8e7f"
ClientSecret = "VnA4URRcZGZZr6GrFvmz1xIwIHSOP/DUBBU="
TenantID = "d6eaade4-XXXX-XXXX-XXXX-f000827455bb"
}
$Token = Get-OauthToken @Params
Utilisateurs
La fonction suivante vous permettra de récupérer tous les utilisateurs de votre tenant Office365.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function Get-PGUsers {
Param (
[Object]$Token
)
Try {
if($Token.access_token -ne $null) {
# Get User Calandars
$headerParams = @{'Authorization'="$($Token.token_type) $($Token.access_token)"}
$url = "https://graph.microsoft.com/v1.0/users"
$request = Invoke-WebRequest -UseBasicParsing -Headers $headerParams -Uri $url -Method Get
$calendars = ($request | ConvertFrom-Json).value
return $calendars
} else {
return $false
}
} Catch {
Throw [System.NotImplementedException]::New("Unable to user calandars : $_")
}
}
Get-PGUsers -Token $token
Templatisation
C’est bien sympa de faire des fonctions monolithiques, mais c’est ce n’est pas très évolutif 😅, je vous propose donc une alternative dynamique :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
function Get-PGRow {
Param (
[String]$Version,
[String]$Method,
[Object]$Token
)
Try {
if($Token.access_token -ne $null) {
$headerParams = @{'Authorization'="$($Token.token_type) $($Token.access_token)"}
$url = "https://graph.microsoft.com/$Version/$Method"
$request = Invoke-WebRequest -UseBasicParsing -Headers $headerParams -Uri $url -Method Get
$responce = ($request | ConvertFrom-Json).value
return $responce
} else {
return $false
}
} Catch {
Throw [System.NotImplementedException]::New("Unable to $Method : $_")
}
}
# Get Users
$Params = @{
Version = "V1.0"
Method = "users"
Token = $Token
}
$Users = Get-PGRow @Params
# Get my mail
$Params = @{
Version = "V1.0"
Method = "/users/[email protected]/messages"
Token = $Token
}
$MyMessage = Get-PGRow @Params
Vous remarquerez rapidement qu’avec l’exemple ci-dessus nous ne pouvons pas récupérer tous les mails du compte. Il vous faudra donc utiliser une autre fonction pour prendre en charge les requêtes comportant plusieurs pages.
Voici donc la fonction qui vous permettra de résoudre cette problématique :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
function Get-PGAll {
Param (
[String]$Version,
[String]$Method,
[Object]$Token
)
Try {
# Params
$headerParams = @{'Authorization'="$($Token.token_type) $($Token.access_token)"}
$url = "https://graph.microsoft.com/$Version/$Method"
$ReturnObject = @()
# loop through each query page (1 through n)
Do{
# display each url on the console window
Write-debug "Fetching data using Uri: $url"
# Request to API Graph
$Request = (Invoke-WebRequest -UseBasicParsing -Headers $headerParams -Uri $url -Method Get | ConvertFrom-Json)
$ReturnObject += $Request.value
$url = $Request.'@odata.nextLink'
} while(-not([string]::IsNullOrEmpty($url)))
# Return Object
return $ReturnObject
} Catch {
Throw [System.NotImplementedException]::New("Unable to get API : $_")
}
}
# Get users delta
$Params = @{
Version = "V1.0"
Method = "/users/delta"
Token = $Token
}
$UsersDelta = Get-PGAll @Params
Vous connaissez désormais les bases de Microsoft Graph. L’API étant perpétuellement en mouvement, de nouveaux scénarii d’utilisation apparaîtront probablement dans un futur proche pour exploiter pleinement le potentiel d’Office 365.
Note du Chef
Microsoft vous propose une plateforme permettant d’explorer les APIs graph sans trop de prise de tête, disponible à l’adresse suivante : https://developer.microsoft.com/en-us/graph/graph-explorer
Je vous souhaite maintenant une bonne exploration de l’univers des APIs Microsoft.