Hello all!
On October 31st Microsoft announced the public preview of the Azure B2B Invitation API. Prior to the introduction of the API, the only way to leverage the B2B feature was through the GUI. Given that B2B is Microsoft’s solution to collaboration with trusted partners in Office 365, the lack of the capability to programmatically interact with the feature was very limiting. The feature is now exposed through Azure’s Graph API as documented here.
A friend challenged me to write a script or small application that would leverage the API (Yes we are that nerdy.) Over the past year I’ve written a number of PowerShell scripts that query for information from OneDrive and Azure AD so I felt I would challenge myself by writing a small .NET Forms application. Now I have not done anything significant in the programming realm since freshman year of college so I thought this would be painful. Thankfully I have a copy of Visual Studio that comes with my MSDN subscription. All I can say is wow, development solutions have evolved since the 90s.
I won’t bore you with the amount of Googling and reading on MSDN I did over the weekend. Suffice to say it was a lot. Very tedious but an awesome learning experience. I can see a ton of re-use of the code I came up with for future experiments (even though I’m sure any real developer would point and laugh).
Before I jump into the detail, I want to mention how incredibly helpful Fiddler was in getting this all working and getting a deep dive understanding of how this all works. If you’re interesting in learning the magic of how all this “modern” stuff works, a tool like Fiddler is a must.
First off we need to register the application in Azure AD as a Native App to obtain a Client ID per this article. Next we need to grant the application the delegated right to read and write directory data as described in the MS article introducing the API. Once the application is registered and the rights have been granted, we can hammer out the code.
Before I jump into the code and the Fiddler traces, one thing that caught my eye in the returned json object was an attribute named invitedToGroups. If you’re familiar with the Azure B2B functionality, you’ll recall that as part of the B2B provisioning process, you can add the user object to a group. This is very useful in saving you time from having to do this after the user accepts the invitation and their user objects populates in the Azure AD. What’s odd about this is this attribute isn’t documented in the Microsoft blog I linked above. Digging into the github documentation, it looks like the information about it was removed. Either way, I decided to play around it with, but regardless of whether or not I followed the schema mentioned in the removed Github documentation, I couldn’t get it to take. I am fairly sure I got the schema of the attribute/value pair correctly, so we’ll have to chalk this up to MS playing with feature while the functionality is in public preview.
So let’s take a look at the code of this simple Windows form application, shall we?
In this first section of code, I’m simply pulling some information from the input fields within the forms application.
// Pull data from user input fields
string tenantid = tenant.Text;
string emailaddress = email.Text;
string redirectsite = redirect.Text;
string group = GroupID.Text;
In this new section of code, I’m leveraging functions from the ADAL library to redirect the user to authenticate against Azure AD, obtain an authorization code for the graph API, and submit that code for an access token for the Graph API.
// Authenticate user and obtain access token
AuthenticationContext authcontext = new AuthenticationContext("https://login.microsoftonline.com/" + tenantid);
AuthenticationResult token = authcontext.AcquireToken("https://graph.microsoft.com", clientid, redirectURI, PromptBehavior.Always);
In this section of code I build an instance of the httpclient class that will be used to submit my web request. You’ll notice I’m attaching the bearer access token I obtained in the early step.
// Deliver the access token to the B2B endpoint along with the posting the JWT with the invite information
string URL = "https://graph.microsoft.com/beta/";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(URL);
client.DefaultRequestHeaders.Authorization = new
System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token.AccessToken);
Client.DefaultRequestHeaders.Accept.Add(new
System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
Here I issue my HTTP request to post to the invitation endpoint and include json object with the necessary information to create an invitation.
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post,
"invitations");
request.Content = new StringContent("{"invitedUserEmailAddress":"" + emailaddress + "","inviteRedirectUrl":"" + redirectsite + "","sendInvitationMessage":true,"invitedToGroups":[{"group":"" + group + ""}]}", Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.SendAsync(request);
Finally I parse the json object (using the Newtonsoft library) that is returned by the endpoint to check to see whether or not the operation was completed.
string content = await response.Content.ReadAsStringAsync();
Newtonsoft.Json.Linq.JToken json = Newtonsoft.Json.Linq.JObject.Parse(content);
string myresult = json.Value("status");
MessageBox.Show(myresult);
Quite simple right? It had to be for someone as terrible as developing as I am. Imagine the opportunities for an API like this in the hands of a good developer? The API could be leveraged to automate this whole process in an enterprise identity management tool allowing for self-service for company users who need to collaborate with trusted partners. Crazy cool.
This is the stuff I applaud Microsoft for. They’ve take a cumbersome process, leveraged modern authentication and authorization protocols, provided a very solid collection of libraries, and setup a simple to use API that leverages industry standard methodologies and data formats. Given the scale of cloud and the requirement for automation, simple and robust APIs based upon industry standards are hugely important to the success of a public cloud provider.
This whole process was an amazing learning experience where I had an opportunity to do something I’ve never done before and mess with technologies that are very much cutting edge. Opportunities like this to challenge myself and problem solve out of my comfort zone are exactly why I love IT.
I hope the above post has been helpful and I can’t wait to see how this feature pans out when it goes GA!
Feel free to reach out if you’re interested in a copy of my terrible app.
Thanks!