I'm updating an Excel complement I made 2-3 years ago with C#. The goal is to get some files that are stored on a SharePoint site, copy them locally and then open them. I have permission to access the SharePoint site, but I have no admin right over the setting of the SharePoint (it is run by our IT service and the company Security is tight regarding data protection). We use MFA to log in to our Windows session and after that we can access the SharePoint and other services without need to input our password again. Until now I have used the code below, and it still work perfectly:
using Microsoft.SharePoint.Client;
using OfficeDevPnP.Core;
string tempFileName = System.IO.Path.GetTempPath() "filename.xlsx";
AuthenticationManager mgr = new AuthenticationManager();
ClientContext context = mgr.GetWebLoginClientContext("https://xxx.sharepoint.com/teams/mypage");
FileInformation fileinfo = File.OpenBinaryDirect(context, "ServerRealtivePath");
context.ExecuteQuery();
System.IO.FileStream fStream = new System.IO.FileStream(tempFileName, System.IO.FileMode.Create);
await fileinfo.Stream.CopyToAsync(fStream);
fStream.Close();
fileinfo.Stream.Close();
So why try to fix something that is not broken… yet? The NuGet package SharePointPnPCoreOnline containing the OfficeDevPnP NameSpace is now marked as being retired and it is recommended to use PnPFramework instead. But the PnPFramework do not contained the AuthenticationManager.GetWebLoginClientContext() method. With the ever-growing need for data protection and new technology, I’m expecting the current method will stop working at some point. Do you have an equivalent method to connect to a sharepoint using a more modern way?
I don’t have any permission to register the app with Azure and I’m guessing it will be a big No from our IT service. I don’t mind asking the user to input his login at some point if needed. I never used REST or GRAPH API but if it can help, I can look into it. I want the right to access the files base on the current user permission. If the user doesn’t have permission to access the specified file, I don’t want the app to be able to download it.
I’m open to suggestions, Thanks
CodePudding user response:
For my tool, I've just reworked the code from the GetWebLoginClientContext
, it's neither big nor complicated. Here is also a newer version of it. So, what's inside: a simple form with a web browser control (that is based on Internet Explorer). When the browser control authenticates the user, the code gets the authentication cookies from the browser control using the platform web browser API, and uses that in the subsequent calls to SharePoint.
What can break here: Internet Explorer (and thus, the browser control) is deprecated, and the support for it ended last year. If the authentication window stops working when opened from a browser control, that would be a problem. I've "fixed" that for myself by using the WebView2 instead of the browser control, and since it's evergreen, it should be fine. It also provides API to get cookies that we need to call the SharePoint.
I don't think the approach with cookie authentication is a problem by itself, but they may change cookies some day and then the app may need to be updated correspondingly then if that happens.
A more "robust" approach would be to register an application anyway in Azure AD (actually you don't absolutely have to ask your admins to register the app, you can register one for yourself without asking anyone, in your own "organization").
With this approach, the user must consent to use the app (to allow the app to access the data in the organization). The admin consent may be required, but it depends on organization settings (by default it's not required, user consent is good enough).
Please note that connecting using an "app" is actually more secure because when you grant access to an app, you only give it specific permissions (i.e. you get an intersection of the user permissions and the permissions that were granted to the app). When connecting as a user (i.e. using the "cookies" approach above), you get full access (i.e. you can do anything the user can).
Another point, for the app you don't really have to build anything on the web (no website is actually needed); the "callback url" to get the access token can be hosted in the application itself (localhost), or the app can be configured to use device code.