Unique Identifier for O365

Multi-tenant apps are a very common scenario in real world. Whenever we create an app, we mostly target it to multiple tenants for wider reach. There are some cases in which we want to save our app data in custom database instead of app web or host web. These scenarios are very frequent and at that time we need a unique identifier to differentiate among tenants. So my search started for a pre-existing identifier of O365 and ended right at TokenHelper.cs file.
Yes, Microsoft has already provided a code for it, I just didn’t realize it’s a unique identifier. 🙂

In TokenHelper.cs there is a public method GetRealmFromTargetUrl(Uri targetApplicationUri) that takes URI of the target sharepoint site as its parameter. This method actually return a string representation of the realm GUID. According to msdn,

 Realm is unique to each tenant in Office 365 or to each SharePoint farm on-premises. It is possible to discover the realm at run time. So, it is not necessary to cache this information between requests, but it will cost you an extra round trip to SharePoint each time you want to look it up. If you use code similar toTokenHelper.GetRealmFromTargetUrl with the site URL, and cache the result per site (or even per site and per user), you can use this later without making the extra call.

For more details, visit this link.

Therefore, above method return a unique id for tenant. You can pass host web uri in it. This id can be saved in database for further use and can even be cached.

Source code for this method is given below. This is copy pasted from TokenHelper.cs class which Visual Studio auto-generates on creating provider hosted app.

 


public static string GetRealmFromTargetUrl(Uri targetApplicationUri)
{
WebRequest request = WebRequest.Create(targetApplicationUri + "/_vti_bin/client.svc");
request.Headers.Add("Authorization: Bearer ");

try
{
using (request.GetResponse())
{
}
}
catch (WebException e)
{
if (e.Response == null)
{
return null;
}

string bearerResponseHeader = e.Response.Headers["WWW-Authenticate"];
if (string.IsNullOrEmpty(bearerResponseHeader))
{
return null;
}

const string bearer = "Bearer realm=\"";
int bearerIndex = bearerResponseHeader.IndexOf(bearer, StringComparison.Ordinal);
if (bearerIndex < 0)
{
return null;
}

int realmIndex = bearerIndex + bearer.Length;

if (bearerResponseHeader.Length >= realmIndex + 36)
{
string targetRealm = bearerResponseHeader.Substring(realmIndex, 36);

Guid realmGuid;

if (Guid.TryParse(targetRealm, out realmGuid))
{
return targetRealm;
}
}
}
return null;
}

 

Hope this helps. 🙂

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s