Featured image of post Accéder à vos données Sharepoint avec un principal de service

Accéder à vos données Sharepoint avec un principal de service

Utiliser un principal de service pour accéder aux données stockées dans votre SharePoint en toute sécurité.

Contexte

Votre SharePoint contient certainement un grand nombre de données que vous souhaitez pouvoir utiliser avec vos programmes. Dans cet article je me propose de vous présenter un exemple de bout en bout pour autoriser un principal de service à accéder à un site SharePoint puis utiliser cet accès via un programme en Python.

Pour rappel, un site SharePoint est créé automatiquement pour toutes équipes Teams, l’exemple présenter ici est donc adressable pour les documents d’une équipe Teams, stockés dans le site SharePoint sous-jacent.

Pré requis

Pour plus d’information sur les comptes principaux de service, lisez mon article Principal de service.

Je suppose que vous avez créé préalablement un principal de service avec un secret.

Le principal de service doit avoir l’autorisation d’API Sites.Selected pour l’API Microsoft Graph. Cette autorisation permet de donner des droits à ce principal de service site par site et non de manière globale.
Nous restons donc dans une logique de moindre privilège.

Vous devez aussi créer les 3 variables d’environnement suivantes :

  • SHAREPOINT_SERVICE_PRINCIPAL_APPLICATION_ID : Contiens la valeur ID d’application (client) de votre principal de service.
  • SHAREPOINT_SERVICE_PRINCIPAL_SECRET : Contiens la valeur du secret du vôtre principal de service.
  • SHAREPOINT_SERVICE_PRINCIPAL_TENANT_ID : Contiens la valeur ID de l’annuaire (locataire) de votre principal de service. Il s’agit de l’id de votre tenant Entra ID.

Vous pouvez initialiser ces variables d’environnement via les commandes PowerShell suivantes :

1
2
3
$env:SHAREPOINT_SERVICE_PRINCIPAL_APPLICATION_ID = "VOTRE_VALEUR_APPLICATION_ID"
$env:SHAREPOINT_SERVICE_PRINCIPAL_SECRET = "VOTRE_VALEUR_SECRET"
$env:SHAREPOINT_SERVICE_PRINCIPAL_TENANT_ID = "VOTRE_VALEUR_TENANT_ID"

Autorisation

Par défaut vous ne pouvez des droits d’ accès à un site SharePoint qu’à des comptes utilisateurs. Il n’existe aucun moyen via l’interface web pour donner des droits à un compte de type principal de service.

Pour donner les autorisations, nous allons passer par l’API Microsoft Graph.

⚠ La personne exécutant le script doit avoir le droit propriétaire sur le site SharePoint et avoir le droit Sites.FullControl.All au niveau de Microsoft Graph (typiquement un administrateur). Une fois la procédure d’autorisation réalisée, vous pouvez enlever le droit propriétaire à cette personne.

Pour utiliser Microsoft Graph avec PowerShell, vous devrez installer le SDK. Toutes les informations concernant ce SDK sont sur la page Install the Microsoft Graph PowerShell SDK

Ouvrez une fenêtre en PowerShell Core (version 7) et installez le module Microsoft Graph si ce n’est pas déjà fait.

1
Install-Module Microsoft.Graph -Scope CurrentUser

Connectez-vous avec la ligne de code suivante :

1
Connect-MgGraph -Scopes "Sites.FullControl.All"

Modifiez le script puis exécutez-le.

 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
$ClientId = $env:SHAREPOINT_SERVICE_PRINCIPAL_APPLICATION_ID
$SPDomaine = "REMPLACER PAR VOTRE DOMAINE SHAREPOINT"
$MSGraphURL = "https://graph.microsoft.com"


$SPSiteName = "REMPLACER PAR LE NOM DU SITE"
# Get Site information for site Id
$URL = $MSGraphURL + "/v1.0/sites/$SPDomaine.sharepoint.com:/sites/$SPSiteName"
$SPSite = Invoke-MgGraphRequest -Uri $URL

# Put permission on Site
$URL = $MSGraphURL + "/v1.0/sites/$($SPSite.id)/permissions"
$Body = @{ 
    roles               = @("read")
    grantedToIdentities = @(
        @{
            application = @{
                id = $ClientId
                displayName = "Droit ajouté par script le $(Get-Date -AsUTC -Format o)"
            }
        }
    )
} | ConvertTo-Json -Depth 100

$r = Invoke-MgGraphRequest -Uri $URL -Body $Body -Method POST

Explication du script ci-dessus :

  • La variable $SPDomaine dois contenir votre domaine SharePoint, c’est la valeur entre https:// et .sharepoint.com/ dans l’URL de votre site SharePoint (visible en haut dans votre navigateur Internet).
  • La variable $SPSite doit contenir le nom de votre site SharePoint, c’est la valeur entre /sites/ et le / suivant dans l’URL de votre site SharePoint.
  • Le script créer un JSON qui autorise le principal de service à lire les données du site SharePoint puis l’envoi à l’API Graph pour valider l’ordre.

Suite à cela votre principal de service a accès en lecture à la totalité de ce site SharePoint.

Accéder à vos données

Maintenant que vous avez autorisé le principal de service à accéder au site SharePoint, nous allons lire un fichier depuis ce site.
Pour cela nous allons procéder en 2 étapes :

  1. L’authentification nous permettant de nous identifier auprès d’Entra ID et de recevoir un token nous permettant d’accéder à des ressources.
  2. L’accès à un fichier dans notre SharePoint en fournissant le token obtenu à l’étape 1.

Authentification

Nous allons installer le paquet azure-identity qui gère l’authentification

1
pip install azure-identity

Le script Python suivant permet de réaliser l’authentification et de préparer la variable headers qui sera ensuite utilisée pour interroger SharePoint.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import os
from azure.identity import ClientSecretCredential

# Create a credential object. Used to authenticate requests
credential = ClientSecretCredential(
    tenant_id=os.getenv("SHAREPOINT_SERVICE_PRINCIPAL_TENANT_ID"),
    client_id=os.getenv("SHAREPOINT_SERVICE_PRINCIPAL_APPLICATION_ID"),
    client_secret=os.getenv("SHAREPOINT_SERVICE_PRINCIPAL_SECRET")
)
scopes = 'https://graph.microsoft.com/.default'
headers = {"Authorization": "bearer {token}".format(token=credential.get_token(scopes).token)}

Lecture d’un fichier

Pour le test vous allez créer un fichier texte, pour pouvoir afficher simplement le contenu, dans votre site SharePoint.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import requests

graph_URL ='https://graph.microsoft.com'
sp_domaine = 'REMPLACER PAR VOTRE DOMAINE SHAREPOINT'
sp_site_name = 'REMPLACER PAR LE NOM DU SITE'
sp_file_path = 'REMPLACER PAR LE CHEMIN DU FICHIER TEXTE'
# On obtient l'id du site SharePoint
URL=f'{graph_URL}/v1.0/sites/{sp_domaine}.sharepoint.com:/sites/{sp_site_name}'
response = requests.get(URL, headers = headers)
site_id = response.json()["id"]
# On obtient l'id du fichier dans le site SharePoint
URL=f'{graph_URL}/v1.0/sites/{site_id}/drive/root:/{sp_file_path}'
response = requests.get(URL, headers = headers)
item_id = response.json()["id"]
# On obtient le contenu du fichier
URL=f'{graph_URL}/v1.0/sites/{site_id}/drive/items/{item_id}/content'
response = requests.get(URL, headers = headers)
# On affiche le contenu du fichier
print(response.content)

Explication du script ci-dessus :

  • La variable sp_domaine doit contenir votre domaine SharePoint, c’est la valeur entre https:// et .sharepoint.com/ dans l’URL de votre site SharePoint (visible en haut dans votre navigateur Internet).
  • La variable sp_site_name doit contenir le nom de votre site SharePoint, c’est la valeur entre /sites/ et le / suivant dans l’URL de votre site SharePoint.
  • La variable sp_file_path doit contenir le chemin relatif du fichier texte de test, extension incluse. Vous pouvez mettre le fichier dans un dossier bien entendu.

Le script complet est donc le suivant :

 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
import requests
import os
from azure.identity import ClientSecretCredential

sp_domaine = 'REMPLACER PAR VOTRE DOMAINE SHAREPOINT'
sp_site_name = 'REMPLACER PAR LE NOM DU SITE'
sp_file_path = 'REMPLACER PAR LE CHEMIN DU FICHIER TEXTE'

# Create a credential object. Used to authenticate requests
credential = ClientSecretCredential(
    tenant_id=os.getenv("SHAREPOINT_SERVICE_PRINCIPAL_TENANT_ID"),
    client_id=os.getenv("SHAREPOINT_SERVICE_PRINCIPAL_APPLICATION_ID"),
    client_secret=os.getenv("SHAREPOINT_SERVICE_PRINCIPAL_SECRET")
)
scopes = 'https://graph.microsoft.com/.default'
headers = {"Authorization": "bearer {token}".format(token=credential.get_token(scopes).token)}

graph_URL ='https://graph.microsoft.com'
# On obtient l'id du site SharePoint
URL=f'{graph_URL}/v1.0/sites/{sp_domaine}.sharepoint.com:/sites/{sp_site_name}'
response = requests.get(URL, headers = headers)
site_id = response.json()["id"]
# On obtient l'id du fichier dans le site SharePoint
URL=f'{graph_URL}/v1.0/sites/{site_id}/drive/root:/{sp_file_path}'
response = requests.get(URL, headers = headers)
item_id = response.json()["id"]
# On obtient le contenu du fichier
URL=f'{graph_URL}/v1.0/sites/{site_id}/drive/items/{item_id}/content'
response = requests.get(URL, headers = headers)
# On affiche le contenu du fichier
print(response.content)

Vous pouvez maintenant exploiter les fichiers contenus dans vos sites SharePoint avec un principal de service.

Merci de votre attention.

comments powered by Disqus
Généré avec Hugo
Thème Stack conçu par Jimmy