Running Application with Office 365 Graph API in App-only Mode

This is a cross-posting of Implementing Application with Office 365 Graph API in App-only Mode at Kloud.

Microsoft has recently release Microsoft Graph to easily integrate Office 365 resources with applications. Graph API basically provides one single endpoint to call bunch of Web APIs to get access Office 365 resources.

In order to use Graph API from another application, the application must be registered in Azure Active Directory (AAD) first. When the application is registered, we can choose how the application is permitted to use resources – application permissions or delegate permissions. The latter one typically requires users to provide user credentials like username and password to get a proper access token. However, there must be requirements that the application doesn’t require users credentials but should directly access to Office 365 resources, which is called app-only mode. For example, a back-end Web API application doesn’t require user credentials to communicate with Graph API. There are many articles on the Internet dealing with user credentials but not many articles coping with this app-only mode. In this post, I will walk through how to register an application as app-only mode and consume Graph API through the registered application.

The sample code used here can be found here. This sample application is built-in ASP.NET 5 and ASP.NET MVC 6. Therefore, in order to get the best development experience, I would recommend using Visual Studio 2015.

Registering Application

OK. First thing goes first. As the sample application is using AAD and Graph API, it’s a mandatory to register this app on your AAD first. Please follow the steps below.

Create User Account on AAD

You can skip this step, if you have already got a user account on AAD.
NOTE: Microsoft Account won’t work with this sample app.

Create a user account on AAD tenant. Once created, the user account should be a co-administrator of the Azure subscription that is currently being used.

Register Application to AAD

  • Create a new application.

  • Choose the Add an application my organization is developing option.

  • Enter the application name like Graph API App-only Sample and select the Web Application and/or Web API option.

  • Enter https://(tenant-name)/GraphApiAppOnlySample for both fields. (tenant-name) should look like contoso.onmicrosoft.com. Please note that both won’t be used at all.

Now the app has been registered.

Configure Application

  • Once the app is registered, click the configure tab.

  • Get the Client ID.

  • Get the secret key. Note that the key is only displayed once after click the Save button at the bottom.

  • Add another application called Microsoft Graph

  • Give “Read directory data” permission to Microsoft Graph, as this permission is only necessary to run the sample app.

ATTENTION: In the production environment, appropriate number of application permissions MUST be given to avoid any security breach.

The app has been configured.

Update Settings in Sample Application

As the app has been registered and configured, the sample Web API app should be setup with appropriate settings. Firstly, open appsettings.json

https://gist.github.com/justinyoo/6cf1a84889c954bf84bd

Then change values:

  • Tenant: contoso.onmicrosoft.com to your tenant name.
  • ClientId: Client ID from the app.
  • ClientSecret: Secret key from the app.
  • AppId: contoso.onmicrosoft.com to your tenant name.

Trust IIS or IIS Express with a Self-signed Certificate

  • You can skip this step, if you intend to publish this app to Azure.
  • You can skip this step, if you already have a self-signed certificate on your root certificate storage.

All communications with AAD and Graph API are performed through a secure channel (SSL/TLS), this sample app MUST be signed with a root certificate. However, this is a developer’s local environment, so a self-signed certificate should be issued and stored as a root certificate. If you don’t store the self-signed certificate, you’ll see the following message popped up when you run VS2015.

The following steps show how to register self-signed certificate to the root certificate store using PowerShell.

Check Self-signed Certificate

First, Check if you have a self-signed certificate in your personal certificate store.

https://gist.github.com/justinyoo/d05587bd30807df09925

If there’s no certificate with name of CN=localhost, you should create the one using makecert.exe. The easiest way to execute makecert.exe is to run Developer Command Prompt for VS2015.

https://gist.github.com/justinyoo/98646323b78c729ed359

  • -r: Create a self signed certificate.
  • -pe: Mark generated private key as exportable.
  • -n: Certificate subject X509 name. eg) -n "CN=localhost"
  • -b: Start of the validity period in mm/dd/yyyy format; default to now.
  • -e: End of validity period in mm/dd/yyyy format; defaults to 2039.
  • -ss: Subject’s certificate store name that stores the output certificate. eg) -ss My
  • -len: Generated Key Length (Bits). Default to 2048 for ‘RSA’ and 512 for ‘DSS’.

Store Self-signed Certificate to Root Store

Second, store the self-signed certificate to the root store.

https://gist.github.com/justinyoo/2d04aa42e5d28d6a7bc6

Finally, you can verify the self-signed certificate has been stored into the root store.

https://gist.github.com/justinyoo/47c8e1b42defa37f08eb

Build and Run Sample Web API Application

All setup has been completed! Now, build the solution in Visual Studio 2015 and punch F5 key to get into the Debug mode. Then you’ll get a JSON response of your tenant organisation details. How does it work? Let’s look into the code.

Get Access Token from AAD Using ADAL

In order to get an access token from AAD, we need to setup AuthenticationContext instance and call a method to get one. The code snippet below is an extract from the sample application.

https://gist.github.com/justinyoo/40b18d2a61aef293db81

The graphApp instance is created from appsettings.json and injected to the controller. With this instance, both AuthenticationContext instance and ClientCredential instance have been created. Note that the ClientCredential instance only uses clientId and clientSecret, not user credentials. In other words, this sample application won’t require any user to login and provide their login details. Let’s see the actual Get() method.

https://gist.github.com/justinyoo/52c28375b1867b24f650

This is the part to get access token. The AuthenticationContext instance sends a request for Graph API with the ClientCredential instance only containing clientId and clientSecret. When the authentication fails, the Get() action will return the exception details as a JSON format. The authResult instance now contains access token.

Call Graph API with Access Token

Now, we have the access token. In the same action method, let’s see how it is consumed to call Graph API.

https://gist.github.com/justinyoo/913586550283cb6519fb

The access token is set to the request header. In this sample code, we call organization details through Graph API. If you use Fiddler, send a request to the application and you will see the full response details.

So far, we have had a brief look how to implement a simple Web API application as app-only mode to consume Graph API. As stated above, this sample application is not for production use unless proper permissions are given. Once all appropriate permissions are setup, you can easily customise this app for your integration purpose. Hope this will help your development.