After finishing my recent article on Programming with the Office 365 APIs General Availability Release, I received a few queries asking how to use the Office 365 APIs within a SharePoint app. In this article, I’ll show you the current approach for using the Office 365 APIs within a SharePoint app. More importantly, however, I’ll discuss the current state of developing across SharePoint and Office 365 and give you a glimpse into the future. You’ll see that there are definitely challenges with the current state of affairs, but hope is on the horizon.
For the example in this article, I’ll create an app part that reads the current user’s appointments from Exchange and displays them on a page in SharePoint (Figure 1). Because app parts run in an IFRAME, some of the key security challenges will become painfully obvious – but more on that as I build the sample. You can download the complete code for the example here.
Figure 1, The app part built in this article
Understanding security challenges
In order to get started, I’ll create a provider-hosted app project using a SharePoint site in my Office 365 tenancy as the host. After I’ve created my project, I can open the web.config file in the remote web project and see that my app has an assigned ClientId and ClientSecret (Figure 2). One of the key aspects of SharePoint apps is that they are first-class security principals, and the ClientId/ClientSecret combination is effectively the assigned username and password for the app. This is, of course, a normal and expected outcome that doesn’t have any direct relationship to the Office 365 APIs; I’m simply calling it out here because it will be important later.
Figure 2, Provider-hosted app ClientId and ClientSecret
As with any SharePoint app, I can also assign permissions through the AppManifest.xml file located in the app project. Again, there is nothing special here with regards to the Office 365 APIs. You can simply assign any required permissions such as the ability to read items in the host web (Figure 3). Just like the security principal information, however, this will become important momentarily.
Figure 3, Assigning app permissions
Once the base project is created, I can easily add Office 365 API functionality in the normal way. I’ll simply right-click the remote web project and select Add/Connected Service. This brings up the Services Manager dialog (Figure 4) where I can register my app and grant permissions. For this example, I’ll grant Read permissions to the user’s calendar. Clicking OK adds the required support for the Office 365 APIs to my SharePoint provider-hosted app.
Figure 4, Granting Office 365 permissions
After adding Office 365 API support, I can open the web.config file for the remote web project and see that I now have additional security principal entries. Along with the ClientId and ClientSecret, I can also see ida:ClientID and ida:Password entries (Figure 5). This is because adding Office 365 API support to my SharePoint app caused the creation of a second security principal – and this is where things get messy.
Figure 5, Office 365 ClientID and Password entries
Along with the second security principal, the app also gained permissions to read the current user’s calendar. However, this permission is not granted through the AppManifest.xml file like a normal SharePoint app. Instead, it is granted in Azure Active Directory.
In order to see these permissions, you must add the Azure Active Directory associated with your Office 365 tenant to your Azure subscription. This is done within the Azure portal by adding a new Active Directory instance and then opting to add an existing instance. Subsequently, you can look at the associated applications where you can examine the configuration for the registered app. You will see the same permissions here that are displayed in the Visual Studio tooling.
Figure 6, App permissions in Azure Active Directory
The implications of adding Office 365 API support to a SharePoint app is that your app now uses two separate security principals and must manage permissions in two separate places. This is a significant consequence because you effectively have two separate apps running as one. Additionally, the tokens used to access SharePoint resources are different from the tokens used to access Office 365 resources; they cannot be used interchangeably and must be managed separately in code. Worst of all, the app will prompt twice for consent: once during the initial app installation, and once when the app asks for user consent to access Exchange. This is certainly not an ideal situation.
The good news is that Microsoft is working hard to solve this problem. Within the next few months, I expect that a single security principal will be supported across SharePoint provider-hosted apps and Office 365. Sometime after that, I expect that there will be a unified way for registering apps and managing permissions. For now, however, this is the only way to combine SharePoint apps and Office 365 APIs in a single project. So, you should try to architect the app to minimize the number of prompts and round trips to the authorization server.
Programming the app
Once the Office 365 API support is in place, you can continue developing. For this app, I am going to add an app part to the remote web. I’ll do this is the usual way by right clicking the app project and selecting Add/New item. In the Add New Item dialog, I’ll select Client Web Part and then choose to add a new controller and view to my MVC5 remote web project.
At this point, I need to spend some time thinking about the authorization flow. I know that the current user will be prompted to give consent the first time they run the app. However, app parts run in an IFRAME, and the authorization flow doesn’t allow showing the required pages in an IFRAME. So, I am left with little choice other than to authorize the current user in the full-page app experience and cache the calendar events for display later. Listing 1 shows the code for retrieving and caching the events.
Listing 1, Retrieve and cache events
//Create an Outlook client
OutlookServicesClient outlookClient =
new OutlookServicesClient(eventsDisco.ServiceEndpointUri, async () =>
var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
//Get the events for the next 8 hours
var eventResults = await (from i in outlookClient.Me.Events
where i.End >= DateTimeOffset.UtcNow && i.End <= DateTimeOffset.UtcNow.AddHours(8)
var events = eventResults.CurrentPage.OrderBy(e => e.Start);
foreach (var e in events)
Id = e.Id,
Body = e.Body == null ? string.Empty : e.Body.Content,
End = e.End,
Location = e.Location == null ? string.Empty : e.Location.DisplayName,
Start = e.Start,
Subject = e.Subject == null ? string.Empty : e.Subject
//cache the events
Once the events are cached, the app part can simply read the data from the cache. If the data is not in the cache, then the user is redirected to the app’s full page experience to authorize. Alternatively, the web part could call AuthenticationContext.AcquireTokenByRefreshTokenAsync in order to get the freshest data on each display of the web part. Listing 2 shows the app part code.
Listing 2, App part code
List<MyEvent> eventList = GetFromCache("Events") as List<MyEvent>;
if (eventList == null)
//Redirect to app web for authentication
As I noted earlier in the article, the app will prompt for consent twice. The first time is when the app is installed by the site owner (Figure 7). The second is when the user is prompted for consent to allow reading the calendar (Figure 8).
Figure 7, Consent during installation
Figure 8, Consent during execution
In this article, I built an app part in a provider-hosted app that utilized the Office 365 APIs to read and display calendar events. Based on the development, some important conclusions can be made:
- Integrating the Office 365 APIs with a SharePoint app is done in the “normal” way by simply adding a connected service.
- Adding Office 365 API support requires the app to be registered with both SharePoint and Azure Active Directory resulting in two separate, unrelated security principals.
- Adding Office 365 API support means that app permissions will be managed in both SharePoint and Azure Active Directory.
- Adding Office 365 API support means that an app will prompt for consent both during initial installation and when run by the end user.
- The tokens used by SharePoint and Azure Active Directory are not interchangeable and must be managed separately.
While the current situation is challenging, Microsoft plans on simplifying this story in the near future. So, if you are planning on utilizing Office 365 APIs in your SharePoint apps today, be careful to create them in a way that can be upgraded when the story changes.