Thursday, March 6, 2014

SharePoint 2013 Workflow App Step won't work, gets suspended

Situation: SharePoint 2013, Workflow Manager 1.0 + the two CUs for Service Bus and Workflow Manager, List with workflow that has an app step (to allow it to read/write to other lists to which the user does not have access). Workflow App Step can't seem to do anything at all! Tried process of elimination and it seems like it cannot look up any field in my current item. When I look at the workflow right after it starts, the status says "Starting" with this message in the little "i" symbol:

Retrying last request. Next attempt scheduled in less than one minute. Details of last request: HTTP NotFound to https://MYSERVER/_vti_bin/client.svc/web/lists/getbyid('SOME_GUID_GOES_HERE')/Items(IdOfYourItem)?%24select=SOMETHING

After that, it gets a status of "Suspended" with detail in that little "i" icon of something awful like this (which is a web service result from that client.svc mentioned up there):
Details: An unhandled exception occurred during the execution of the workflow instance. Exception details: System.ApplicationException: HTTP 404 {"error":{"code":"-1, System.ArgumentException","message":{"lang":"en-US","value":"Item does not exist. It may have been deleted by another user."}}} {"Transfer-Encoding":["chunked"],"X-SharePointHealthScore":["0"],"SPClientServiceRequestDuration":["18"],"SPRequestGuid":["c38c92af-563c-073b-8950-19e9ab5d00ce"],"request-id":["c38c92af-563c-073b-8950-19e9ab5d00ce"],"X-FRAME-OPTIONS":["SAMEORIGIN"],"MicrosoftSharePointTeamServices":[""],"X-Content-Type-Options":["nosniff"],"X-MS-InvokeApp":["1; RequireReadOnly"],"Cache-Control":["max-age=0, private"],"Date":["Thu, 06 Mar 2014 22:07:22 GMT"],"Server":["Microsoft-IIS\/7.5"],"X-AspNet-Version":["4.0.30319"],"X-Powered-By":["ASP.NET"]} at Microsoft.Activities.Hosting.Runtime.Subroutine`1.SubroutineChild.Execute(CodeActivityContext context) at System.Activities.CodeActivity.InternalExecute(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager) at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation)

Resolution: Turns out, the App Step can't get past those pesky list advanced settings where you set "item-level permissions" to "Read only their own". Yea, for that the workflow "app" would need to have higher or elevated permissions. Seems like the only way to do this is to A) Have an app catalog and B) Set the workflow "app" as having full control using a hidden app permissions page. You can find the step by step here (Microsoft) or here (Fabian Williams...the better one if you ask me). This applies to any action that might require full control or design-like permissions like creating lists, creating sites, etc. and applies to SharePoint 365 as well.

SharePoint 2013 List Not Shared With You

Situation: SharePoint 2013, claims-based authentication using Windows NTLM claims (aka your Windows PC passes your username and password to SharePoint's claims security service to log you in), site uses AD group membership to control access, and finally a web part on the homepage to show some items in this list.

Other users could load this just fine, my user would get no items and, when I clicked on the list itself, would get "Sorry, this site has not been shared with you" (nevermind that it was a list, not a site, the error still said 'site'). Checked permissions on the item, list, site, site collection, masterpage library, themes libraries, web parts, image library, custom javascript library pages, etc. Checked server logs and SharePoint logs that show all sorts of nasty detail on every thing in SharePoint, nothing.

I also noticed that AD group membership changes didn't sync - even after telling the User Profile Service to do a full sync!

I remember stumbling on something about AD group memberships in SharePoint 2013 (though this applies to 2010 as well with ADFS) regarding claims-based authentication and an expiration or cache of some kind. Using two articles (here and here) with MS documentation (here, herehere, and here), I found the fix: update the Security Token Service timeout to a shorter time and update the Windows and Forms token timeouts to a shorter time as well.

Be aware - the following powershell (that you have to run from the SharePoint 2013 Management Shell) tells the STS (Security Token Service) to reduce the amount of time a user token is valid (as far as the STS cares) and then lowers the expiration timeframe for claims token handed out by the STS. This would increase network traffic (refer to articles up there for more detailed explanations) and could make your SharePoint a bit unstable if your timeouts aren't in this pattern of TokenTimeout > Windows/FormsTokenLifetimes > LogonTokenCacheExpirationWindow:

$cs = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$cs.TokenTimeout = (New-TimeSpan -hours 4)
$sts = Get-SPSecurityTokenServiceConfig
$sts.FormsTokenLifetime = (New-TimeSpan -hours 2)
$sts.WindowsTokenLifetime = (New-TimeSpan -hours 2)
$sts.LogonTokenCacheExpirationWindow = (New-TimeSpan -minutes 30)
You can play with the times to be much shorter if you are just trying to fix an issue immediately but the ContentService's TokenTimeout HAS to be greater than the TokenLifetimes which HAVE to be greater than the CacheExpirationWindow. I'm playing with these settings for now and will update later if I end up changing them.