Calling the Office 365 Unified API from JavaScript using ADAL.js




The goal of this post is to provide very basic ‘hello world’ example of how to call the Office 365 Unified API (aka Graph API) using JavaScript and the ADAL.js library. This has recently become possible (May 2015) now that CORS is supported by the Office 365 APIs (most of the individual endpoints support it as well as the unified API).

The ADAL library simplifies the process of obtaining and caching the authentication tokens required to retrieve data from Office 365. It is possible to avoid the ADAL library and handle this yourself, although I would recommend doing so as a learning exercise only.

I failed to find a simple example of how to achieve this, my search results often filled with examples of calling the APIs from server-side code or else utilising the Angular.js framework. This example is based on a more complex example.

The following snippet will log to the browser console the results of a call the to files endpoint of the Office 365 unified API, which will return a JSON object containing information about the files in the current users’ OD4B.

Before it will work you must complete the following steps (as described in detail here):

  1. Register an Azure Active Directory App. Note that *every* Office 365 subscriptions comes with AAD and supports the creation of an app
  2. Associate the required ‘permissions to other services’, in this case ‘Read users files’ via the Office 365 Unified API
  3. Allow implicit flow

Not covered explicitly in the above article but also critical are the following steps:

  • Get the App’s Client ID and copy it into the snippet
The App Client ID
The App Client ID
  • Get the Azure Active Directory subscription ID and copy it into the snippet
The subscription ID in Azure Active Directory
The subscription ID in Azure Active Directory

Once the above steps have been completed, you can try out the snippet by embedding in a Script Editor web part, or you can run it externally to SharePoint as part of, say, a provider hosted app.

NOTE: I found that the call to files endpoint is failing for certain users. I am still unsure whether this is due to external vs internal users (is working for internal [.onmicrosoft.com] users) or whether it could be licencing issue. The /beta/me endpoint is working in all cases.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.0/js/adal.min.js"></script>
<script type="text/javascript">
(function () {
	"use strict";
  // Some samples will use the tenant name here like "tenant.onmicrosoft.com"
  // I prefer to user the subscription Id 
  var subscriptionId = "7ac27593-XXXX-4d98-81bf-XXXXXXXXXXXX";
  // Copy the client ID of your AAD app here once you have registered one, configured the required permissions, and
  // allowed implicit flow https://msdn.microsoft.com/en-us/office/office365/howto/get-started-with-office-365-unified-api
  var clientId = "c244a80a-XXXX-4262-b729-XXXXXXXX";
	
  window.config = {
    subscriptionId: subscriptionId,                 
    clientId: clientId,     
    postLogoutRedirectUri: window.location.origin,
    endpoints: {
      graphApiUri: 'https://graph.microsoft.com'
    },
    cacheLocation: 'localStorage' // enable this for IE, as sessionStorage does not work for localhost.
  };
  var authContext = new AuthenticationContext(config);	
  // Check For & Handle Redirect From AAD After Login
  var isCallback = authContext.isCallback(window.location.hash);
  authContext.handleWindowCallback();	
  if (isCallback && !authContext.getLoginError()) {
    window.location = authContext._getItem(authContext.CONSTANTS.STORAGE.LOGIN_REQUEST);
  }	
  // If not logged in force login
  var user = authContext.getCachedUser();
  if (user) {
    // Logged in already
  } 
  else {
    // NOTE: you may want to render the page for anonymous users and render
    // a login button which runs the login function upon click.
    authContext.login();
  }	
  // Acquire token for Files resource.
  authContext.acquireToken(config.endpoints.graphApiUri, function (error, token) {
    // Handle ADAL Errors.
    if (error || !token) {
      console.log('ADAL error occurred: ' + error);
      return;
    }
    // Execute GET request to Files API.
    //var currentUserApiBaseUri = graphApiUri + "/beta/" + config.subscriptionId + "/users/" + user.userName;
    //var filesUri = currentUserApiBaseUri + "/files";
    var filesUri = config.endpoints.graphApiUri + "/beta/me/files";
    $.ajax({
      type: "GET",
      url: filesUri,
      headers: {
        'Authorization': 'Bearer ' + token,
      }
    }).done(function (response) {
      console.log('Successfully fetched files from OneDrive.');
      console.log(response);
    }).fail(function () {
      console.log('Fetching files from OneDrive failed.');
    });
  });
})();
</script>

Paul.

GLOSSARY

CORS: Cross-Origin Resource Sharing
ADAL: Active Directly Authentication Library
OD4B: OneDrive 4 Business




7 thoughts on “Calling the Office 365 Unified API from JavaScript using ADAL.js”

  1. Hi, I am trying to do an OAuth from my phonegap app to SharePoint Online. Would the above code work?

    Both are on different domains. I have been unsuccessful so far. I would appreciate your help on it.

    Thanks

    1. Hi Hansen,
      I haven’t spent any time with phonegap but I don’t see why it wouldn’t work. Assuming that a user’s first point of contact with SharePoint Online is via the phonegap app, then the app will redirect to the Azure AD sign in page. Upon authorization the user will be redirected back to the app. Not sure how you manage http redirects when using phonegap. ADALjs supports CORS for cross-domain requests.

  2. I’m trying to use this inside of SharePoint but if I’m not the admin user it will send me to the login page but give me this error:

    This application requires application permissions to another application. Consent for application permissions can only be performed by an administrator. Sign out and sign in as an administrator or contact one of your organization’s administrators.

    I login in as an Admin, went to the page the API was being called, accepted the permissions. But when I login as a normal user, I get that error.

    If the app as been approved by the admin, what’s the problem?

    More details here: http://stackoverflow.com/questions/39731303/microsoft-graph-api-permissions-for-non-admins?noredirect=1#comment66762724_39731303

Leave a Reply

Your email address will not be published.