-
Notifications
You must be signed in to change notification settings - Fork 259
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Hands-on feasibility analysis calling M365 REST APIs directly without Powershell dependency modules #1359
Comments
Thank youI wanted to thank the authors of the following blog post and GitHub repo for inspiration and code reference which was invaluable for the development of the source code associated with this issue.
|
Prototype for directly calling Sharepoint REST APIs with the Microsoft MSAL library (certificate authentication)This prototype relies on the Microsoft Authentication Library (MSAL) which is Microsoft's modern library that enables application developers to acquire tokens in order to call web APIs. Specifically the Powershell code relies on the Microsoft.Identity.Client Namespace for .NET. The assemblies are Microsoft.Identity.Client and Microsoft.IdentityModel.Abstractions. DependenciesI took care of the installation by downloading recent versions of Microsoft.Identity.Client.dll and Microsoft.IdentityModel.Abstractions.dll and embedding them in the source code folder. I got them from the official Nuget repository. If ScubaGear were to use these assemblies we would need to write code in our setup routines to download the package and then load the version of the dll files that match the .NET version on the system ScubaGear is running on. SharepointAPIWithCertificate.ps1 (demo script)This script calls the .NET MSAL AcquireTokenForClient method to authenticate and acquire a token using client certificate authentication. You need to have an Entra Id registered application like the Scuba Functional Test Orchestrator created in the tenant and your client certificate configured as a credential in the application. Your client certificate must be in the cert:\CurrentUser\My section in the Windows certificate registry on the system you are running on. Once the authentication token is acquired, the script passes the token to an API call against a Sharepoint REST method. The script then outputs a JSON document to the console that contains the Sharepoint tenant configuration settings received from the REST API. PermissionsThe registered Entra Id application that you use must have the API permission shown in the screenshot below to be able to get data from Sharepoint Online. Example usage:This example assumes you have a M365 tenant with the domain your365tenant.onmicrosoft.com
SampleSharepointTenantConfig.jsonThis is a sample Sharepoint tenant configuration settings output file generated by the script above. |
Study ResultsOverall my experience with the MSAL libraries via Powershell was positive. Loading the respective MSAL dll dependencies and minting a token via a call to the authentication endpoint is about 10 lines of code. Getting that 10 lines working right was tricky and took a little time. Once I got it working I was able to call a Sharepoint REST endpoint to retrieve the tenant settings and identify that the endpoint provides fields that are missing from the Microsoft.Online.SharePoint.PowerShell cmdlets. I was also able to mint tokens and call MS Graph endpoints using the same foundational authentication code, which proves that directly accessing the MSAL library may help Scuba authenticate to disparate services across M365 with a uniform code base (today ScubaGear uses a hodge podge of different authentication cmdlets from the Powershell modules). Benefits
ChallengesThe toughest part with integrating this code is going to be managing the .NET dependency packages. ScubaGear would need to download a specific (known working version) of the .NET MSAL packages from the NuGet repo and then reference the files from ScubaGear. Since the NuGet packages each contain different dll files based on the .NET version you are running, our code would need to detect what system it was running on (and the Powershell version) in order to dynamically load the correct dll. Although this is not an overly challenging requirement, it can make the ScubaGear dependency management a little more complex versus what we do today which is simply installing Powershell modules (no dynamic linking needed in our code). LimitationsThe limitations below were due to a decision that I made on how much time to spend on the prototype to get a benefit out of it.
|
Code SnippetThis code sample was taken from the script that authenticates via a service principal and then leverages the token to call a Sharepoint REST API. The most important lines are the following:
|
💡 Summary
This is a feasibility analysis via hands-on prototyping.
Ultimately ScubaGear is limited to whatever configuration fields the underlying Powershell modules offer. In some cases we have found that the fields we need are available in a back-end REST API even though we cannot get them via modules such as Sharepoint.Powershell. Therefore we investigated to see:
This work is an extension of previous work that was performed to call Sharepoint Online REST APIs directly without going through the PnP.Powershell or Sharepoint.Powershell modules that ScubaGear currently relies on. ScubaGear currently cannot get all of the configuration fields necessary to perform a full audit of the M365 tenant either because the underlying module does not include the fields (Sharepoint.Powershell) or we cannot use the latest version of the module (PnP.Powershell) because it requires Powershell 7.
Some of the previous related issues are:
#958 which proved that calling the Sharepoint REST API directly can acquire numerous fields that are currently missing from ScubaGear.
#957 which provides a proof of concept code branch that demonstrates how to call .NET MSAL authentication APIs to perform interactive user authentication and get a token that can be used to directly call Sharepoint REST APIs.
Lack of cmdlet support regarding interactive authentication to call Sharepoint REST APIs: The PnP.Powershell module offers an Invoke-PnPSPRestMethod cmdlet which can be used to make REST API calls directly to Sharepoint sites with a certificate without the need for custom MSAL authentication logic, but there is no equivalent in the Sharepoint.Powershell module for interactive authentication. We cannot use PnP.Powershell with interactive authentication since it requires either an existing PnP multi-tenant app that is overpermissioned or the user must create a custom app in their tenant which is not currently required for ScubaGear users with interactive authentication. We examined cmdlets outside of PnP.Powershell for interactive authentication such as Connect-MgGraph, but there does not seem to be a way to call Connect-MgGraph with Sharepoint as the target application for the token and subsequently call a Sharepoint REST API.
Precedence for direct REST API calls: There is precedence in ScubaGear for calling REST APIs directly. In Entra Id, earlier this year, ScubaGear was modified to directly call REST APIs instead of going through the MS Graph cmdlets due to performance problems with the cmdlets. We made these modifications for a subset of the Graph cmdlets that the Entra Id baseline was using. For Entra Id, we didn't need to worry about writing custom code to acquire authentication tokens and pass them to a Powershell function that makes REST API calls because that was handled by Connect-MgGraph (which handles the magic of getting the tokens) and Invoke-MgGraphRequest (which calls the REST API and uses the underlying token).
Note: If the Scuba team decided to implement a solution to directly call Sharepoint APIs then ScubaGear would no longer need the PnP.Powershell and Sharepoint.Powershell dependencies and there would be a single code path in the Sharepoint export provider.
Implementation notes
The text was updated successfully, but these errors were encountered: