Tutorial: Inviting an Azure Active Directory guest user with Microsoft Graph

One of the most time-consuming tasks we are faced with in my current assignment is inviting users to our Azure Active Directory tenant. Particularly since we are doing that manually in de Azure Portal at present. We use Azure Active Directory B2B, in which external users are invited as guests. To automate this process, we make use of Microsoft Graph. There are various matters you have to take into account when implementing it. You will find a quick manual below.

By the way, I do cut some corners in this article. When making Views and Controller actions for the web app, for example. It's a conscious decision since I want this manual to concentrate on invoking the Microsoft Graph. And because I assume you know how to make a View or Controller action.😉


What are we going to make?

We're creating a web app that uses Application Permissions to invite users to an Azure Active Directory tenant with the help of Microsoft Graph. We use Application Permissions because we want to make the feature available to different types of users. It's possible that not all users have administrator rights on the AAD tenant. This way, the application itself has the right to invite users, meaning that the users need not have administrator rights. To keep this manual relatively simple and focused on the relevant task, we'll skip registration with the web app.


Azure Active Directory endpoints

At present, there are two Azure Active Directory endpoints: V1 and V2. We've known the V1 endpoint for some time. V2 has extra functionality, the biggest difference being:

The v2.0 endpoint allows developers to write apps that accept sign-in from both Microsoft Accounts and Azure AD accounts, using a single auth endpoint. This gives you the ability to write your app completely account-agnostic; it can be ignorant of the type of account that the user signs in with. Of course, you can make your app aware of the type of account being used in a particular session, but you don’t have to.

Source: What’s different about the v2.0 endpoint?

In addition, app registrations for the V2 endpoint are not made in the Azure Portal but in the separate Application Registration Portal. For this manual, we're using the Azure Active Directory V1 endpoint and an app registration in the Azure Portal.


The manual

These are the steps needed to make this simple sample application.


1. Make an app registration in the Azure Portal


  • Open Azure Active Directory in the portal
  • Go to App Registrations and click on New Application Registration
  • Give the new app registration a Name, select Web app/API as application type and give it a (fake) Sign-on URL 
  • Click on Create
  • Once the application registration has been completed, click on Settings
  • Go to Required Permissions, click on Add, and then on Select and API
Tutorial Inviting An Azure Active Directory Invite Guest User App Registration Betabit
  • Select Microsoft Graph and click on Select
  • Under Application Permissions*, check the Invite users to the organisation box
  • As an extra, you can select Read all users' full profiles, which allows you to see the users in the web app
  • Click on Select to select the rights and then on Done, to end adding API access.
Tutorial Inviting An Azure Active Directory Invite Guest User Grant Permission Betabit

Important!
These authorisations must be granted by an administrator. Click on the Grant Permissions button to actually grant the authorisations for the application. All the changes you make in the enabled authorisations require that you explicitly grant the permission again by clicking on the button.

  • Go to Keys
  • Under Passwords, enter a Key description, select a Duration and click on Save

Important: copy the value of the Key after you save it because you won't be able to retrieve it after you close the Blade.


*Application Permissions and delegated authorisations

I just told you explicitly to enable the permission for the application under Application Permissions. And there's a good reason for that. Use Delegated Permissions if you want the application to invoke the API as the registered user. When the application invokes Microsoft Graph as itself, you use Application Permissions. Since we want everyone who uses the app to have the opportunity of inviting users, we use Application Permissions.


2. Make and implement the web app

Make an ASP.NET web application I've made a NET Core 2.0 web app, but you're free to decide what your preference is.

  • Add the Microsoft.Graph NuGet package
  • Add the NuGet package Active Directory Authentication Library (Microsoft.IdentityModel.Clients.ActiveDirectory)
  • Create something like an InviteUserModel, views, and action for the controller
  • Make a ClientCredential with:
    • The ID of the application you made in Step 1
    • The password for this application
  • Make an AuthenticationContext for your AAD tenant (something like https://login.microsoftonline.com/<JOUW_AAD_TENANT>.onmicrosoft.com)
  • Collect a token for Microsoft Graph by invoking AcquireToken in the AuthenticationContext
  • Create a DelegateAuthProvider that adds the resulting token to the header of each request

Altogether, it should now look something like this:

var clientCredential = new ClientCredential(_appId, _appSecret);
var authenticationContext = new AuthenticationContext($"https://login.microsoftonline.com/{_tenant}");
var authenticationResult = authenticationContext.AcquireTokenAsync("https://graph.microsoft.com", clientCredential).Result;

var delegateAuthProvider = new DelegateAuthenticationProvider((requestMessage) =>
{
    requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", authenticationResult.AccessToken);
    return Task.FromResult(0);
});

return new GraphServiceClient(delegateAuthProvider);

3. Using Microsoft Graph

The example made contains a GraphServiceClientHelper, which makes it look like this:

var graphServiceClient = GraphServiceClientHelper.CreateGraphServiceClient();
var invitation = await graphServiceClient.Invitations.Request().AddAsync(new Invitation
{
    InviteRedirectUrl = "http://localhost:xxx",
    InvitedUserDisplayName = inviteUserModel.DisplayName,
    InvitedUserEmailAddress = inviteUserModel.EmailAddress,
    InvitedUserMessageInfo = new InvitedUserMessageInfo
    {
        CustomizedMessageBody = inviteUserModel.InviteMessage
    },
    SendInvitationMessage = inviteUserModel.SendInviteMessage
});

Important!
The InviteRedirectURL is a required parameter. It must contain the URL to which the invited user will be directed after accepting the invitation.


Gotcha!

Bear in mind that there are some differences between the API V1.0 Graph and the beta version. One example: the beta version offers no support when collecting more than 100 items at the same time. On the other hand, V1.0 offers no support for 'expanding' MemberOf, while the beta version does.

To invoke the beta version, use the constructor for GraphServiceClient. This requires two parameters: baseURL and AuthenticationProvider. You don't have to change the URL of the resource for which you collect a token, since tokens for Microsoft Graph (https://graph.microsoft.com) work for both V1.0 and the beta version.

Initiating the GraphServiceClient for the beta version goes like this:

var client = new GraphServiceClient("https://graph.microsoft.com/beta", delegateAuthProvider);

Source code

I hosted this example (extremely simple) on GitHub. You'll find it here: rickvdbosch/MicrosoftGraphExample. If you have any problems implementing this manual, please don't hesitate to get in touch with us.


Inviting an AAD guest user with Microsoft Graph
Like to find out more about Microsoft Graph? Rick is happy to tell you all about it

Contact