====== Configurer une application enregistrée dans Entra ID pour gérer une équipe Sharepoint ====== ===== Inscription d'une application ===== Une inscription d’application dans Entra se fait : * depuis le **portail Azure**, * en **CLI/script** avec l'**API Microsoft Graph** par exemple en utilisant **Powershell**. ===== Installer le module Microsoft.Graph de Powershell===== ==== Installer Powershell 7 ==== ==== Installer Microsoft.Graph de Powershell ==== * prérequis : * permissions API (Microsoft Graph) : Sites.Selected (Application) * ouvrir une session Powershell en tant, qu'administrateur Install-Module Microsoft.Graph Import-Module Microsoft.Graph ===== Préparation Azure AD (OAuth2) ===== ==== Depuis l'interface d'administration du portail Azure ==== * création d'une **Inscription d'applications** Entra ID : * Portail Azure => Entra ID * Inscription d'applications => Nouvelle inscription * Nom : app * Locataire unique seulement * S'incrire * Récupérer : * Tenant ID * Client ID * l'ajout du certificat se fera ultérieurement (dans Certificates & Secrets) * Ajouter la permission Microsoft Graph : * Autorisations d'application (et non Autorisations déléguées) : * Sites.Selected La permission **Sites.Selected** restreint l'accès au site explicitement autorisé via Graph. Une autorisation d'application ne nécessite pas de compte utilisateur : * L'application agit en autonomie (service, script, automatisation). * Nécessite un consentement administrateur. * Demander le consentement de l'administrateur. ==== En CLI ==== * Connexion avec les droits nécessaires sur le tenant Entra ID Connect-MgGraph -Scopes "Application.ReadWrite.All","AppRoleAssignment.ReadWrite.All" Welcome to Microsoft Graph! Connected via delegated access using 14d82eec-204b-4c2f-b7e8-296a70dab67e Readme: https://aka.ms/graph/sdk/powershell SDK Docs: https://aka.ms/graph/sdk/powershell/docs API Docs: https://aka.ms/graph/docs NOTE: You can use the -NoWelcome parameter to suppress this message. * Création d'une nouvelle application $app = New-MgApplication -DisplayName "Application" * Création du Principal de service associé $sp = New-MgServicePrincipal -AppId $app.AppId ===== Autoriser l'app enregistrée à mettre à jour les dossiers de l'équipe Teams ===== Cela ne peut pas se faire depuis l'interface d'administration Entra ID mais en utilisant Powershell. ==== Utilisation d'un certificat ==== * Création d'un certificat $cert = New-SelfSignedCertificate ` -Subject "CN=applicaton" ` -CertStoreLocation "Cert:\CurrentUSer\My" ` -KeySpec Signature ` -KeyUsage DigitalSignature ` -KeyExportPolicy Exportable ` -HashAlgorithm SHA256 ` -KeyLength 2048 ` -NotAfter (Get-Date).AddYears(4) $cert.Thumbprint * Notez l'empreinte du certficat $cert.Thumbprint * Vérifier que le certificat est BIEN présent au BON endroit dans Cert:\CurrentUser\My Get-Item "Cert:\CurrentUSer\My\" * Vérifier que la CLÉ PRIVÉE est présente dans le certificat $cert = Get-Item "Cert:\CurrentUSer\My\" $cert.HasPrivateKey $cert.HasPrivateKey doit renvoyer True * Export du certificat PUBLIC à importer dans Entra ID Export-Certificate ` -Cert "Cert:\CurrentUSer\My\$($cert.Thumbprint)" ` -FilePath "application.cer" * importer le certificat dans l'application à partir du portail Azure * Test avec PowerShell (certificat local) Connect-MgGraph ` -TenantId "" ` -ClientId "" ` -CertificateThumbprint "" => Résultat attendu Plain TextWelcome To Microsoft Graph! * Puis : Get-MgContext => on doit voir : ClientId : TenantId : Scopes : {Sites.Selected} AuthType : AppOnly TokenCredentialType : ClientCertificate CertificateThumbprint : ==== Donner accès à l'application sur le site Sharepoint==== * l'administrateur doit donner l'accès au site voulu # deconnexion Disconnect-MgGraph # Connexion admin Connect-MgGraph -Scopes "Sites.FullControl.All" # Récupérer le site $site = Get-MgSite -SiteId "mondomaine.sharepoint.com:/sites/MonSite" # Donner accès controle total à l'application (fullcontrol / read / write) New-MgSitePermission ` -SiteId $site.Id ` -Roles "fullcontrol" ` -GrantedToIdentities @{ Application = @{ Id = "ID application" DisplayName = "application" } } * Se reconnecter en AppOnly : Connect-MgGraph ` -TenantId "1ae69c2d-61b2-4de4-84c7-2a4dd0de7330" ` -ClientId "5c82fc87-6e0c-413f-ac12-6d784af9a249" ` -CertificateThumbprint "97F825CFD5C0371D28E1D691140A084B9C2C4386" * Puis Tester l’accès au site précis: Get-MgSite -SiteId "mondomaine.sharepoint.com:/sites/MonSite" ==== Créer un dossier dans le site SharePoint ==== * Identifier le site SharePoint en itilisant le chemin direct : $site = Get-MgSite -SiteId "mondomaine.sharepoint.com:/sites/MonSite" $site.Id => Afficher le GUID du site du type : xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx * Récupérer le drive du site (Documents) : chaque site a une document library principale. $drive = Get-MgSiteDrive -SiteId $site.Id $drive.Id => Affiche un DriveId Type : documentLibrary * Créer un dossier À LA RACINE (test simple). New-MgDriveRootChild ` -DriveId $drive.Id ` -AdditionalProperties @{ "name" = "Test-Dossier" "folder" = @{} "@microsoft.graph.conflictBehavior" = "rename" } => Résultat attendu Id : 01ABCDEF.... Name : Test-Dossier => Dossier créé avec succès à vérifier dans SharePoint * lister les dossier à la racine $items = Get-MgDriveRootChild -DriveId $drive.Id * Récupérer le dossier General $parent = $items | Where-Object { $_.Name -eq "General" } $parent.Id * création du sous-dossier New-MgDriveItemChild ` -DriveId $drive.Id ` -DriveItemId $parent.Id ` -AdditionalProperties @{ "name" = "Test-SousDossier" "folder" = @{} "@microsoft.graph.conflictBehavior" = "rename" } ==== Installer le module module PnP.PowerShell ==== PnP.PowerShell supporte : * L’authentification Graph App-only * La commande Grant-PnPAzureADAppSitePermission * Les opérations moderne de gestion des Sites.Selected Install-Module PnP.PowerShell -Scope CurrentUser ==== Se connecter ==== * génération d'un certificat autosigné $cert = New-SelfSignedCertificate ` -Subject "CN=MinioS3Sync" ` -KeyAlgorithm RSA ` -KeyLength 2048 ` -CertStoreLocation "Cert:\CurrentUser\My" ` -NotAfter (Get-Date).AddYears(3) * Exporter le certificat .CER (public) Export-Certificate ` -Cert $cert ` -FilePath "./minio-s3.cer" * Exporter la clé privée .PFX $password = Read-Host "Mot de passe du certificat" -AsSecureString Export-PfxCertificate ` -Cert $cert ` -FilePath "./minio-s3.pfx" ` -Password $password `` * Uploader le fichier minio‑s3.cer dans Entra ID * Entra ID → App Registration → Ton App → Certificates & secrets → Upload certificate → sélectionne minio-s3.cer * se connecter Connect-PnPOnline ` -Url "https://educvaladonlimogesfr-admin.sharepoint.com" ` -ClientId "ad39ff78-4116-43d6-86cf-3dfa8f120aa3" ` -Tenant "educvaladonlimogesfr.onmicrosoft.com" ` -CertificatePath "./minio-s3.pfx" ` -CertificatePassword $password ==== Donner l'autorisation ==== Grant-PnPAzureADAppSitePermission ` -AppId "ad39ff78-4116-43d6-86cf-3dfa8f120aa3" ` -DisplayName "Minio-S3c" ` -Site "https://educvaladonlimogesfr.sharepoint.com/sites/Signaturenumrique" ` -Permissions Write ==== Tester la commande ==== Connect-PnPOnline -Url "https://-admin.sharepoint.com" -ClientId "" -ClientSecret "" ==== Script bash pour configurer l'accès à l'équipe Sharepoint associée à l'équipe Teams ==== Le script : * génère un token OAuth2 (client_credentials) * Récupère automatiquement le {site-id} via Graph API * Récupère automatiquement le {drive-id} (bibliothèque SharePoint) * Assigne les permissions Sites.Selected (write)` à l'application inscrite * Teste l’accès via rclone (liste des fichiers) * Prérequis : apt install jq #!/usr/bin/env bash ### --------------------------------------------------------------------------- ### CONFIGURATION À RENSEIGNER ### --------------------------------------------------------------------------- TENANT_ID="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" CLIENT_ID="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" CLIENT_SECRET="YOUR_APP_SECRET" HOSTNAME="contoso.sharepoint.com" # domaine SharePoint SITE_PATH="DocumensoSite" # nom du site SharePoint DRIVE_NAME="Documents" # nom de la bibliothèque (ex: "Documents") RCLONE_REMOTE="sharepoint" # nom du remote rclone RCLONE_MINIO="s3minio:documenso" # bucket minio RCLONE_SHAREPOINT="${RCLONE_REMOTE}:${DRIVE_NAME}" ### --------------------------------------------------------------------------- echo "1. Obtention du token OAuth2..." ACCESS_TOKEN=$( curl -s -X POST \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "client_id=$CLIENT_ID" \ -d "scope=https://graph.microsoft.com/.default" \ -d "client_secret=$CLIENT_SECRET" \ -d "grant_type=client_credentials" \ "https://login.microsoftonline.com/$TENANT_ID/oauth2/v2.0/token" \ | jq -r .access_token ) if [[ "$ACCESS_TOKEN" == "null" || -z "$ACCESS_TOKEN" ]]; then echo "❌ Impossible de générer un token ! Vérifie ton CLIENT_ID / SECRET." exit 1 fi echo " Token obtenu." ### --------------------------------------------------------------------------- echo "2. Récupération automatique du site-id..." SITE_INFO=$(curl -s -X GET \ -H "Authorization: Bearer $ACCESS_TOKEN" \ "https://graph.microsoft.com/v1.0/sites/$HOSTNAME:/sites/$SITE_PATH?$select=id,webUrl") SITE_ID=$(echo "$SITE_INFO" | jq -r '.id') if [[ "$SITE_ID" == "null" || -z "$SITE_ID" ]]; then echo "❌ Impossible de récupérer le site-id !" echo "Réponse brute:" echo "$SITE_INFO" exit 1 fi echo " SITE_ID trouvé : $SITE_ID" ### --------------------------------------------------------------------------- echo "3. Récupération automatique du drive-id de la bibliothèque $DRIVE_NAME..." DRIVES_LIST=$(curl -s -X GET \ -H "Authorization: Bearer $ACCESS_TOKEN" \ "https://graph.microsoft.com/v1.0/sites/$SITE_ID/drives") DRIVE_ID=$(echo "$DRIVES_LIST" | jq -r ".value[] | select(.name==\"$DRIVE_NAME\") | .id") if [[ -z "$DRIVE_ID" ]]; then echo "❌ Impossible de trouver la bibliothèque '$DRIVE_NAME'" echo "Réponse brute:" echo "$DRIVES_LIST" exit 1 fi echo "DRIVE_ID trouvé : $DRIVE_ID" ### --------------------------------------------------------------------------- echo "4. Attribution de la permission Sites.Selected (write) à l'application..." ASSIGN_RESPONSE=$(curl -s -X POST \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d "{ \"roles\": [\"write\"], \"grantedToIdentities\": [ { \"application\": { \"id\": \"$CLIENT_ID\" } } ] }" \ "https://graph.microsoft.com/v1.0/sites/$SITE_ID/permissions") echo " Permission appliquée." echo "Réponse API :" echo "$ASSIGN_RESPONSE" ### --------------------------------------------------------------------------- echo "5. Test d'accès SharePoint avec rclone..." docker exec -it rclone-sync rclone lsd "$RCLONE_SHAREPOINT" echo " Configuration terminée avec succès !" echo "SITE_ID = $SITE_ID" echo "DRIVE_ID = $DRIVE_ID" * exécuter le script bash setup_sharepoint_access.sh