Using Microsoft Graph .NET Client Library in Azure Functions

Tags: Microsoft Graph, Azure Functions, Code, Presentations

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"
  2. It is also mandatory to add using statement for Microsoft.Graph DLL
    using Microsoft.Graph;
  3. 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);
            }
        )
    );
  4. 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();
  5. 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;

}

No Comments

Add a Comment