Friday, April 7, 2017

SharePoint 2013 High Trust Apps - 401 Unauthorized Error When Calling User Profile Service

When you call the User Profile Service in SharePoint 2013 from a High Trust App (or a SharePoint Add-In, as they're calling them now) some interesting things happen.  Consider the following scenario:


- You have an App that shows some data for a user via a CSOM call.  It's essentially a search of data that everyone at your company can see. 
- You also have, in the same App, a tab that shows information specific to that user, filtered by the user's location attribute in the User Profile Service. 


When the page loads, the first tab loads fine, since there are no calls.  The second tab, however, doesn't load anything.  You'll also get something like this in the Event log of your App Hosted server:


Source: System; Error: The remote server returned an error: (401) Unauthorized.; Stack Trace: at System.Net.HttpWebRequest.GetResponse()

at Microsoft.SharePoint.Client.SPWebRequestExecutor.Execute()

at Microsoft.SharePoint.Client.ClientRequest.ExecuteQueryToServer(ChunkStringBuilder sb)


This is the App Hosted server saying "Hey, I tried to talk to the User Profile Service, but I was denied."


There are a...LOT....of reasons why the User Profile Service might deny a request.  It could be the Application Pool account of the request doesn't have access to query the User Profile service application.  It could be SQL database permissions. 


One of the ways we found to help troubleshooting was to isolate the User Profile service to a Web Front End.  That is - we started the service on a web front end, and stopped it everywhere else.  (NOTE:  This is NOT the User Profile Synchronization Service.  Touch that not, else your life will suck in new, interesting ways).


Once the UPS was running on a web front end, we were able to see the request, and the reply in the same ULS log.  With that, we saw this:


SPJsonWebSecurityBaseTokenHandler: Issuer name in token '5924ce70-6ed4-4d21-913d-23b43664342d@1dd693ac-dfc1-434b-8eba-8758c2922b8e' doesn't match any of the registered issuer names for trusted sts 'SharePoint High-Trust App Tenant UAT'.

What does that mean?  It means the sts 'SharePoint High-Trust App Tenant' for UAT don't know nothin' about any app using an IssuerId of 5924ce70-6ed4-4d21-913d-23b43664342d.


We went to our App Hosted server, checked our web.config file for the App in question, and sure enough, the IssuerId in our <appSettings> section was wrong.  The settings looked like this:

<add key="IssuerId" value="5924ce70-6ed4-4d21-913d-23b43664342d" />


We checked a different App in the same farm, and saw this for its settings:


<add key="IssuerId" value="df6429b9-e397-4fb8-b0d2-0429a82d68a1" />


Once we swapped to the correct IssuerId, everything worked.


But why?  The why here is the High Trust Tenant is what enabled the App Hosted Servers, which are essentially just IIS servers, to be trusted by SharePoint.  If the Tenant doesn't have an IssuerId that matches what the App is saying its IssuerId is, it'll get blocked.


So in this case, User Profile was fine.  Application Pools were fine.  The App Model was fine. 


The lesson is:  Don't let a developer have access to your UAT farm - else he might decide his new App needs a brand new IssuerId, and set the entire farm's config for his lone App.  And you might not notice it until your App does something that requires elevated permissions. 

No comments:

Post a Comment