SharePoint Online, PowerShell et Authentification Moderne

SharePoint Online, PowerShell et Authentification Moderne

3 décembre 2019 Non Par Stefan Plizga

Par défaut, y compris encore à l’heure actuelle lorsqu’un nouveau tenant Office 365 est créé, l’authentification « legacy » pour SharePoint Online est activée.

Il existe plein d’articles sur comment désactiver l’authentification « legacy » pour ne laisser place qu’à l’authentification moderne, en résumé les méthodes sont :

  • Depuis SharePoint Admin Center, dans Access Control: « Apps that don’t use modern authentication »
  • En PowerShell, avec le module Microsoft.Online.SharePoint.PowerShell, avec les commandes suivantes:

PS C:\>Connect-SPOService -Url https://<tenant>-admin.sharepoint.com
PS C:\>Set-SPOTenant -LegacyAuthProtocolsEnabled $False

En fonction des moyens d’accès à SharePoint Online, et en particulier en PowerShell en exécution de tâches planifiées (donc en mode non-intéractif), il peut y avoir des problèmes une fois cette configuration effectuée. Je résume ici les principaux points de blocage et leur solution.

Module Microsoft.Online.SharePoint.PowerShell

Ce module est installable directement via la commande Install-Module Microsoft.Online.SharePoint.PowerShell et contient notamment la commande Connect-SPOService. Après avoir désactivé l’authentification « legacy », l’utilisation de la commande Connect-SPOService en passant des credentials en paramètre ne fonctionnera plus, il y aura un message similaire à celui-ci :

PS C:\>Connect-SPOService -Url https://<tenant>-admin.sharepoint.com -Credential $O365Credentials

Connect-SPOService : Cannot contact web site 'https://<tenant>.sharepoint.com/' or the web site does not support SharePoint Online credentials. The response status code is 'Unauthorized'. The response headers are 'X-SharePointHealthScore=0, X-MSDAVEXT_Error=917656; Access+denied.+Before+opening+files+in+this+location%2c+you+must+first+browse+to+the+web+site+and+select+the+option+to+login+automatically.

Le message est trompeur, ouvrir le site dans un navigateur n’arrangera rien. Le problème vient du module PowerShell qui tente par défaut une authentification « legacy » lorsqu’on passe les credentials en paramètre et se retrouve donc bloqué. La solution est documentée ici : Cannot force Modern Authentication when using Connect-SPOService cmdlet in SharePoint Online Management Shell, il suffit de créer cette clé de registre dans HKCU:

[HKEY_CURRENT_USER\Software\Microsoft\SPO\CMDLETS]
"ForceOAuth" = dword:00000001

Après cela, la connexion fonctionne correctement.

Module SharePointPnPPowerShellOnline

Ce module est installable directement via la commande Install-Module SharePointPnPPowerShellOnline et contient notamment la commande Connect-PnpOnline. Après avoir désactivé l’authentification « legacy », l’utilisation de la commande Connect-PnpOnline en passant des credentials en paramètre continue à fonctionner, sauf si le mot de passe contient le caractère « + » ! Dans ce cas, l’erreur est la suivante et pas du tout parlante :

PS C:>Connect-PnPOnline -Url https://<tenant>.sharepoint.com/ -Credentials $O365Credentials

Connect-PnPOnline : Exception has been thrown by the target of an invocation.

Ce problème ne se pose pas avec l’authentification « legacy ». En faisant quelques tests, les caractères ci-dessous ne posent aucun problème, cela semble limité au signe « + » :

@"X:=$#|`?^;!\',

La solution est donc de changer le mot de passe du compte.

SharePoint CSOM

Dans le cas de scripts PowerShell qui utilisent les extensions CSOM (Client Side Object Model) de SharePoint, ce type d’initialisation ne fonctionne plus, on obtient un message similaire au cas de Connect-SPOService :

$ctx=New-Object Microsoft.SharePoint.Client.ClientContext($SiteName)
$creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($SPOAdminAccount, $SPOSecurePassword)
$ctx.Credentials = $creds
$ctx.Load($ctx.Web)

$ctx.ExecuteQuery()

Exception calling "ExecuteQuery" with "0" argument(s): "Cannot contact web site 'https://<tenant>.sharepoint.com/' or the web site does not support SharePoint Online credentials. The response status code is 'Unauthorized'. The response headers are 'X-SharePointHealthScore=1, X-MSDAVEXT_Error=917656; Access+denied.+Before+opening+files+in+this+location%2c+you+must+first+browse+to+the+web+site+and+select+the+option+to+login+automatically.

Pour résoudre ce cas, il faut se connecter avec Connect-PnPOnline et récupérer le contexte qui servira par la suite. Voici un exemple :

Connect-PnPOnline -Url $SiteName -Credentials $O365Credentials
$Context = Get-PnPContext
$Web = $Context.Web
$Context.Load($Web)
Invoke-PnPQuery

De cette manière, la gestion de l’authentification moderne en CSOM est possible.

A ne pas oublier

Il est important de maintenir à jour les modules PowerShell utilisés car ils sont régulièrement améliorés. De plus, les solutions proposées ci-dessus pour se connecter à SharePoint Online dans des scripts en PowerShell fonctionnent même lorsque du Conditional Access est utilisé pour par exemple bloquer l’accès depuis des IP qui ne sont pas les IP publiques de l’entreprise). Il est d’ailleurs recommandé de restreindre l’utilisation de ce type de compte aux IP de l’entreprise.

— Stefan