I’ve been using the Azure AD Graph API in SharePoint/Office Apps for some time now and the changing releases of the different Microsoft products definitely makes it very confusing for newcomers. The documentation has a long way to go, it is quite tricky with the very few examples that use old API’s. I hear that people find it frustrating to get going with the Graph API.
This blog post describes how you can make use of Azure AD in Office/SharePoint Apps, what API’s to use and how to authenticate your App. I have been using a technique for a while now and it is still not widely popular, most likely because it is not documented anywhere. I have been presenting on it for a while now:
- Microsoft InTouch conference 2014
- EUSPC 2014 in Barcelona
- SharePoint Days 2014 in Slovenia
- JSNext 2014 in Bulgaria
- You are building a SharePoint App that needs to read user data that does not exist in the User Profiles in SharePoint Online
- You need to get a list of members in a group in Azure Active Directory in a provider-hosted SharePoint App that will run in Office 365
- You need to reach to other directory objects in Azure AD like Roles, Conference Rooms, Computers, etc.
- You DON’T have an Azure subscription (you don’t need one!)
The first key point to understand: every Office 365 tenant has an Azure Active Directory instance in the background. This was never well-known and it took some time in the industry before the mass population got a grasp of that fact. DirSync helped, but terminology definitely changed, and so did the Azure landscape.
One of first and best posts out there that highlighted this was by fellow MVP Chris O’Brien: http://www.sharepointnutsandbolts.com/2014/04/using-azure-instance-behind-your-office-365-tenant.html His does a great job to show you how you can fiddle with your Office 365 users with a trial Azure subscription.
The second key point: SharePoint Apps get “registered” as Applications (Service Principals) in Azure AD. I will show you how to see that further below.
And the third point: You *don’t need* an Azure subscription to work with Azure AD, you can use PowerShell. You will miss out on the awesome web portal, but you can still do your job. Many blog posts show how to do it through the Azure portal, but most don’t have an Azure subscription.
Azure Active Directory – a few words
For those not so familiar with Azure AD, it is just a directory in the cloud J There are tons of examples of how Azure AD delivers significant value, but here we focus on what is different from Active Directory on-premises that is relevant to Apps.
Instead of using LDAP to communicate with AD, when using Azure AD we use HTTP-based authentication standards and packet flow: SAML-P, OAuth 2.0, WS-Federation. That’s all you need to know for now.
Again, all Office 365 (Multi-tenant) tenants have an instance of Azure AD in the background, so if you are doing anything with Office 365 development, you will eventually come across this.
The Graph API
So no LDAP, no DirectorySearcher, no old ways to interrogate the directory. The Azure AD team has built what is called the Graph API.
The terminology is confusing, but if you’ve been in the SharePoint/Office world that has always been the case. I am sometimes confused myself:
Azure AD Graph API – This is the interface to Azure Active Directory. You use it to get information about directory objects and even update the AD schema. There is a neat client library used to wrap all actions to the API, called the Azure Active Directory Graph Client Library.
- Lots of information could be found on the Azure Active Directory Graph Team blog here: http://blogs.msdn.com/b/aadgraphteam/
- It is interfaced through here: https://graph.windows.net
- The client library and API have been going through various changes, including name and namespace changes
Office Graph – I don’t know exactly how to define it, but it is an extension to the SharePoint Search infrastructure, most likely serving data from the Azure AD Graph API. You throw queries at the SharePoint Search API called “GQL” (Graph Query Language) and it gives you results about directory objects. More information here: https://msdn.microsoft.com/en-us/office/office365/howto/query-Office-graph-using-gql-with-search-rest-api
- You query the “Office Graph” with the following REST path: https://<tenant_address>/_api/search/query?Querytext=’*’&Properties=’GraphQuery:ACTOR(ME)’
- It is something part of SharePoint & Office 365, not Azure
- The “Office Graph” is described here, albeit quite poorly from a technical perspective and hardly mentioned: http://blogs.office.com/2014/03/11/introducing-codename-oslo-and-the-office-graph/
This blog post is specifically about the Azure AD Graph API and how you can use it in SharePoint Apps.
So, why would you care about all this?
As we’re moving from On-premises to more and more development in Office 365, you will eventually hit the need to get information from Active Directory that is not in neither the User Profiles, nor attainable through the Office Graph GQL search interface. You will need to do stuff in AD that you just can’t do through other API’s, for example getting a user’s country or Office 365 license information through the User Profiles CSOM API.
Steps to give SharePoint Apps permission to Azure AD
So now with the background out of the way, let’s dig into it. As I mentioned previously, you don’t need an Azure subscription to read Azure Active Directory data – your Office 365 tenant gives you everything you need.
- Register a SharePoint App with your tenant -> get a ClientId and ClientSecret
- Give permissions to the App to call Active Directory using the Graph API
- Show some code
Registering a SharePoint App with a tenant
I use this technique with our clients when we develop something that is a one-off case, and mainly when we build console applications or windows services that do periodic work on SharePoint Online tenants. I use AppRegNew.aspx and you could read more about it here: https://msdn.microsoft.com/en-us/library/office/jj687469(v=office.15).aspx
You can also find more samples where I use this technique in OfficeDev Patterns & Practices: Core.UserProfiles.Sync
Governance.EnforceContentTypeRetention and a few others
- Open https://[tenantname].sharepoint.com/_layouts/15/appregnew.aspx
- Generate your ClientId and ClientSecret, and fill in the other fields:
If you are just building a console app with no user interaction, the AppDomain & Redirect URI could be just “localhost” & “https://localhost“.
Confirm and copy your ClientId and ClientSecret. You could also use AppInv.aspx to give your app permissions to SharePoint data. See one of the OfficeDev PnP samples for more info on that.
Give your App access to Active Directory
This is where the real fun begins.
After you used AppRegNew.aspx, you might wonder where that App configuration goes… Let’s have a look.
- To use PowerShell with Azure Active Directory you need to get the Azure AD modules: (also described here: Core.UserProfiles.Sync )
http://msdn.microsoft.com/en-us/library/azure/jj151815.aspx is the official MSDN page.
- First install the Microsoft Online Services Sign-In Assistant for IT Professionals RTW.
- Then install the Azure Active Directory Module for Windows PowerShell (64-bit version). The 32-bit version has been discontinued.
Open the Windows Azure Active Directory PowerShell module (or you can just import the modules):
- Connect to your tenant:
Connect-SPOService -Url https://onebitsoftware-admin.sharepoint.com -Credential firstname.lastname@example.org
- Purely for academic purposes, poke around:
To prove that SharePoint Apps get registered as Azure Active Directory service principals, run this command:
## Set the app Client Id, aka AppPrincipalId, in a variable
## get the App Service Principal
You will get this:
Notice “AppPrincipalId” -> this is the ClientId, there is just a huge element of bad and misaligned terminology.
But the point is made, AppRegNew.aspx registers a SharePoint App as an Azure AD service principal. The Service Principal Names are taken from the AppDomain property and the client Id. The Display Name is what you put in the AppRegNew.aspx form.
NOTE: SharePoint Apps will not appear in the Azure web portal, there are reasons for this and it is normal. See this: Application Objects and Service Principal Objects https://msdn.microsoft.com/en-us/library/azure/dn132633.aspx
- Give your App access
Again, for academic purposes, run Get-MsolRole:
This is a list of all roles in AD that you could assign. In our case the “Directory Readers” role is what we need. So let’s give that role to our App:
## Set the app Client Id, aka AppPrincipalId, in a variable
## get the App Service Principal
## Get the Directory Readers Role
##get the role you want to set
##Give the app the Directory Reader role
$directoryReaderRole.ObjectId -RoleMemberObjectId $appPrincipal.ObjectId
You are DONE!
To validate, run this:
##Confirm that the role has our app
And you will see:
Notice Yammer?? That’s how Yammer gets data from Azure AD J This gives you significant info on how things work in AD.
Test access and get going with some code
So, now you need to test, then write the actual code for the SharePoint App.
First, some reading:
To test your app authentication, use the Graph Explorer: https://graphexplorer.cloudapp.net/
Type in your tenant UPN followed by /Users to get all users:
When you click Get you will get a login prompt:
Principal Id is the same as “ClientId” and “AppPrincipalId” (bad terms!)
“Symmetric Key” is “ClientSecret”.
Click log in and you will get your results J Beware of caching issues!!
Add the Graph Client Library to a project
Now that your authentication is set up, grab the Graph Client Library through Nuget:
That is pretty much all you need! You should keep your assemblies fresh, however beware of the changes, “GraphClient” & “GraphConnection” are old API’s, “ActiveDirectoryClient” is the object in 2.0.
There’s not a hell of a lot of code samples out there, but there are a few to help you get going. I put together an update to the OfficeDev PnP sample “AzureAd.GroupMembership” so check it out:
Core.UserProfiles.Sync – https://github.com/OfficeDev/PnP/tree/dev/Solutions/Core.UserProfiles.Sync – this example gets the Country from Azure AD and syncs it to SPO User Profiles, where that field is unavailable.
(no need for me to paste the code here)
The Azure AD Graph Team have good samples too:
That should be enough to get you going, good luck J Please feel free to reach out to me and ask questions, I would be glad to help. You might find me junking in the Yammer OfficeDev Patterns & Practices group.