Wednesday, August 16, 2017

Running a SharePoint framework web part with elevated privileges – Focus on Azure Functions – Part 2

In the previous post we looked at the following steps:
  1. Create an Azure account
  2. Create an Azure Function App
  3. Create the Azure Function
  4. Configure the Azure Function
    1. Support continuous deployment
    2. Enable CORS

In this post, I will continue with steps "Configure access to SharePoint" and "Install NuGet packages" which belongs to Configure the Azure Function. Then, "Develop the code to read site collection administrators" and "Calling the Azure Function from your SPFx web part".

4.3. Configure access to SharePoint:


4.3.1 Register your function in SharePoint:


If you have developed provider-hosted SharePoint Add-ins in the past, you know this step since I will use the same approach in registering the Azure Function with the Azure Access Control Service (ACS) and the SharePoint App Management Service of the tenant. It allows the Azure Function to execute requests in SharePoint with the app-only context.

To register the Azure Function as an Add-in, navigate to "http://<your tenant>.sharepoint.com/_layouts/15/AppRegNew.aspx" and enter the required information. Generate a new client id and client secret. The Add-in title can be your function’s name. Use your function’s URL to configure App Domain and Redirect URI. Here my configuration:


After clicking Create, you will see this message "The app identifier has been successfully created.". Now copy the client id and client secret, since we will need these values later.

If you want to understand more about the registering process, check out this article.

4.3.2. Grant permissions for function:


Since we have finished the registration step, it is time to grant the function permissions to execute requests in SharePoint.

Navigate to "http://<your tenant>.sharepoint.com/_layouts/15/AppInv.aspx" and look up the Add-in you have just created using its client id. Then, enter the following code in the Permissions field to give the function full control of the site collection you are configuring it for.


As you're granting full control to an Add-in, the client secret is as important as the password for your SharePoint administration account!

Here my configuration:


After clicking Create, you will be requested to trust the Add-in. It is similar to installing an app on your cell phone!


4.3.3. Configure App Settings in the function:


Using the client id and client secret from the step above, it is possible to authenticate to SharePoint and run our code with elevated privilege. Therefore, we need to configure the function’s application settings to use these values in the function’s code.

First, open the Application settings:


Then, add the client id and the client secret of your newly registered Add-in to the App settings:


After clicking Save, you have the essential information to run the function with the app-only context which give us the RunWithElevatedPrivileges effect.

4.4. Install NuGet packages:


Instead of having to upload DLLs using FTP or KUDU to your function’s directory, the Azure Function offers support to NuGet packages, which makes our lives much easier. Once configured, the NuGet packages will automatically be downloaded and installed to the function’s directory. It happens the first time the code runs! To use the types defined in the NuGet packages, you just need to add using statements to your run.csx file.

To communicate with SharePoint, I used the PnP core components which are much more convenient than directly working with the managed CSOM for authentication etc. Therefore, I’ve described below how to configure the usage of NuGet packages in your function.

The project.json file is the location to manage the NuGet packages. Add this file to the function’s directory and add a reference to SharePointPnPCoreOnline version 2.16.1706.0 to it.

Here’s how it looks in Visual Studio Code after committing and pushing the changes. Since I configured continuous deployment, I always need to execute this step.


Alright, the preparation steps are finished, but there is still work to be done. It never ends! J It is finally time to develop the code to retrieve the site collection administrators.

5. Develop the code to read site collection administrators:


Let’s start developing the logic J The code below is very simple. The program requires a site collection URL to retrieve the administrators. Then, it fetches client id and client secret from the app settings and use it to authentication in SharePoint. Finally, it reads the site collection administrators using the GetAdministrators method, which is available through the PnP library. Then, it’ll return the site administrators’ display names. That’s it! I added a couple of comments to the code, so it is easier to understand.

For instance, if you change the app permission to read, you won’t get any site collection administrators. There is also no error indicating that you don’t have enough permissions.

Before using the function in the SPFx web part, I tried the function using the integrated test area in Azure. It’s only about entering a JSON object with the properties required by the function and running it.


6. Calling the Azure Function from your SPFx web part:


The SPFx web part is also very simple. It builds on top of the "hello world" sample from Microsoft, which is what you get after running the yeoman SharePoint generator. If you have never created a SPFx web part before and want to try it, I recommend you use the SPFx tutorial about building your first SharePoint client-side web part.

The first thing we need is the function’s URL. You will find it in the Azure Portal:


Please note that the function URL already contains the function key as a query string parameter (code). If it is not provided, you must pass it using a x-functions-key header when calling the Azure Function.

Now it is time to call the function from the web part. The private method _retrieveAdministrators contains the logic to communicate with the Azure function. Since I’m using the HttpClient object to call the Azure function, there are a few things to consider when executing POST calls. First, I configured the Headers object. Then I configured the IHttpClientOptions passing the Headers object and the body which contains the current site collection URL as a JSON object. This is the more relevant part of the code! I also handled possible errors using resp.ok for checking the function’s success (HTTP response status code 200). I shared the main part of the code through GitHub.


Finally, the web part is able to call the Azure function which returns the site collection administrators. Since I only granted the function access to a specific site collection, the function will return an error message when the web part is used in another site collection different from the one I configured. Here you can see the possible outputs:

Calling the function from the configured site collection:


Calling the function from any other site collection:


Summary:


After a few configurations, the Azure Function is ready to use and you can put your focus on more important things like the development of the code instead of programming a web service and hosting it somewhere. Since the focus of this post relies on the Azure Function, I spent less time on the development of the web part. But it is enough to understand the idea of elevating user’s privileges. Depending on the permissions you configure in your Add-in, you can have access to a site collection or even full control in the entire tenant. The combination of the app-only context and the Azure Function gives you sight beyond sight (enhanced vision) in SharePoint. In other words, with the correct configurations you can do whatever you want from your SPFx web part in SharePoint!

Links:

No comments:

Post a Comment