SharePoint Realm - Should it always be a GUID or can it be any string?

SharePoint Realm is one of those things that is not discussed a lot in the SharePoint world, at least not until you are discussing oAuth and trust. In majority of cases, we are content with the default Realm ID that is set when we install SharePoint.

What if some SharePoint administrator thought that it was perhaps cool to change the realm from GUID to any random string? Don't think its possible? Of course it is, just look closely at the Set-SPAuthenticationRealm cmdlet.
Set-SPAuthenticationRealm
   [-AssignmentCollection <SPAssignmentCollection>]
   [-Confirm]
   [-Realm <String>]
   [-ServiceContext <SPServiceContextPipeBind>]
   [-WhatIf]
   [<CommonParameters>]

Attribute Realm is a string and it allows an administrator to choose any string of his liking to be the new Realm ID.

I just finished troubleshooting for a customer where the customer was unable to run any of the full-trust add-ins that they had on a new farm they had setup. The add-ins worked perfectly in their old farm, but the moment they were setup in the new farm, they started getting HTTP 401 accessing data from the host web. Never at the start of it did I realize that the realm would play such an important part in the investigation. Read on to know the details.

Investigation

Starting with the usual suspects, we matched the Issuer Id from the Trusted Provider with that provided in the web.config. The ClientId was matched between the Add-in Manifest and the web.config. Everything was a match.

Next we looked at the ULS logs. The ULS log was showing up an error when validating the Audience URI.

SPAudienceValidator: Audience uri '00000003-0000-0ff1-ce00-000000000000/test.spdev.local@ is not valid for the context.
What is audience?
Audience is  the principal the token is intended for. The format is <client ID>/<target URL authority>@<target realm>. Based on this information, you can determine the client ID for your add-in and the realm.  In an on-premise environment, there is typically just one realm, and its identifier matches your farm ID.  For Office 365, this is your tenant ID.

When inspecting this message, I noticed that the realm was missing from the audience. Fiddler to the rescue and out came the JWT. Decoding the JWT, I saw that the realm was indeed missing in audience of the token.

The focus now completely shifted to the token and thus TokenHelper.cs and one specific function 'GetRealmFromTargetUrl'


But before I go any further, it is time to reveal what the Realm was in the farm I was investigating. The administrator had chosen to set the realm based on the DTAP environments, e.g. a-spdev-local, p-spdev-local, etc. For that matter, he could have chosen any possible string.

This change caused the function to falter at 2 places:
  1. The realm is extracted as a substring from the Bearer Response Header and it expects it to be 36 characters long i.e. a GUID
  2. The extracted string is then parsed as a GUID to ensure its validity

The Fix

Once the cause was identified, it was only a matter of setting the configuration right again.

I performed the following steps:
  1. Generate a new GUID. I used the 'Create GUID' tool in Visual Studio
  2. Set the Realm using 'Set-SPAuthenticationRealm'
  3. Delete the old Trusted Token Issuer that was created with the old Realm
  4. IISRESET on all servers
  5. Create a new Trusted Token Issuer. This is now created with the new Realm
  6. IISRESET on all servers. Without the IISRSET, it might take more than 24 hrs before the Trusted Token Issuer is available.
After these steps were completed and the add-in re-launched, VOILA!!! The add-in was working again.

Conclusion

For arguments sake, we can say that Enterprise developers can alter the TokenHelper.cs to meet their organization standards. But that is a luxury for Enterprise developers only I suppose. But there too, a new SharePoint Administrator might prefer a different standard. Therefore, re-adjust TokenHelper.cs and re-deploy. And if you are ever going to setup a hybrid environment, you will end up with the SPO Realm and that is a GUID anyway.
For ISVs, it is obvious that sticking to the standard is the way to go.

My recommendation is to stay away from any changes to the realm format. Stick to a GUID to ensure that everything works as expected.

Comments

Popular posts from this blog

Automate Import of Functions/WebAPI in Azure API Management as backend and using OpenAPI definition and Terraform

Transcripts with Microsoft Bot Framework v4

Managing built-in cache in Azure API Management