Using Microsoft Graph .NET Client Library in Azure Functions

I use this code sample as a demo in my conference session “Building serverless applications with Microsoft Graph and Azure Functions” which I presented at several conferences in 2018. Slides can be found on my SlideShare profile.

Azure Functions bindings for Microsoft Graph provide functionality for accessing Microsoft Graph from Azure Functions. One of bindings is auth token binding, which gets an Azure AD bearer token that is in turn used for authentication of subsequent calls to Microsoft Graph.

If we create function from “Microsoft Graph profile photo API” template, the function will retrieve profile photo for current user by making REST call which is authenticated by passing authentication token in the call header. Sufficient permissions will be configured when function is created.

image

We will use this function as a starting point, and re-configure it to enable usage of Microsoft Graph .NET Client Library.

When auth token extension is installed it will also install DLLs for  .NET SDK for Microsoft Graph, because those DLLs are prerequisites for auth token extension. We can verify that by checking if SDK DLLs exist in BIN folder for Azure Function app:

image

Now we can modify code of the function created by template:

  1. We need to reference both Microsoft.Graph and Microsoft.Graph.Core DLLs.
    These two lines should be added on top of the run.csx, above 'using' statements

#r "Microsoft.Graph"

    #r "d:\home\site\wwwroot\bin\Microsoft.Graph.Core.dll"
  1. It is also mandatory to add using statement for Microsoft.Graph DLL

using Microsoft.Graph;

  1. Inside the Run metod, we have to initialize GraphServiceClient object that will be used for building and sending request

GraphServiceClient graphClient = new GraphServiceClient( "https://graph.microsoft.com/v1.0", new DelegateAuthenticationProvider( async (requestMessage) => { requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", graphToken); } ) );

  1. Now we can use instance of GraphServiceClient to retrieve profile photo of current user as follows:

var photo = await graphClient.Me.Photo.Content.Request().GetAsync();

  1. Finally, to mirror initial functionality of the function created by the template, we can return retrieved photo to the function caller:

HttpResponseMessage response = new HttpResponseMessage(); response.Content = new StreamContent(photo); return response;

NOTE:
To ensure that you have valid access token, you can re-consent the function app before you call the function. You can re-consent the application by visiting following URL:
https://<-- FUNCTIONAPPNAME -->.azurewebsites.net/.auth/login/aad?prompt=consent If your access token is expired, you would receive HTTP 500 error as response to the function call.

For reference, full code of the function is displayed below:
#r "Microsoft.Graph" #r "d:\home\site\wwwroot\bin\Microsoft.Graph.Core.dll" using System.Net; using System.Net.Http; using System.Net.Http.Headers; using Microsoft.Graph; public static async Task Run(HttpRequestMessage req, string graphToken, ILogger log) { //Set up Graph client GraphServiceClient graphClient = new GraphServiceClient( "https://graph.microsoft.com/v1.0", new DelegateAuthenticationProvider( async (requestMessage) => { requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", graphToken); } ) ); // use Graph client to retrieve profile photo for current user var photo = await graphClient.Me.Photo.Content.Request().GetAsync(); //compose response HttpResponseMessage response = new HttpResponseMessage(); response.Content = new StreamContent(photo); return response; }