My good friend Fabian tweeted about a problem he was having with SharePoint 2013 workflows.
It was an interesting problem that I have never seen anyone tackle before so the fact he was having a error wasn't surprising. It did however peak my interest about the problem, so I asked him to send me his workflow.
He exported his workflow as a template (solution file) and sent it over. First issue I had was importing the workflow as a sandboxed or farm solution. It would give me this crazy error:
svr-spwfe01 : Failed to load receiver assembly "Microsoft.SharePoint.WorkflowServices, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" for feature "GetItemsFromSPOListInstances" (ID: eb5838ef-cda9-42b2-9ea8-624f060d554c).: System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.SharePoint.WorkflowServices, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' or one of its dependencies. The system cannot find the file specified.
File name: 'Microsoft.SharePoint.WorkflowServices, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark&
So I abandoned that idea and looked to import the XAML file like I did in 2010. I created a 2013 workflow but alas, no xaml files are to be found in the "All Files" view. Where do they go? Well, there is a hidden list called "wfsvc". It has no views on it so simply unhiding it won't allow you to browse the files inside it. Attempting to create a view is also futile. So I turned to Windows PowerShell, navigated to the SPFile that represented the workflow xaml file and replaced it with Fabian's. Refresh of SharePoint Designer and bingo…I had all his info. Sweet.
The main issue of Fabian's was that when he made the Web Service call he would pass a pre-created FedAuth token (yeah I told him he would have to figure out how to generate this in the future) which established a context for him. This context was as his SharePoint admin account, but the actual running account (the "actor") was the Workflow service. Of course the SP Admin account can do whatever it wants, but the workflow service cannot. This workflow service account is NOT the account that the actual workflow manager backend window service is running under. It is the Application principal account that is created for the workflow service. If you browse to the database, you can see there are two database tables:
- AppPrincipalPerms
- AppPrincipals
If you browse the AppPrincipals table, you will find one or more principles. Consider these to simply be user just like any other user, yet they are applications and as such, do not have a password. You can find the ID of the AppPrincipal for workflow by taking the second index of the NameID for the item with title "Workflow" (NOTE: This id is different in EVERY farm, which is a bummer):
- i:0i.t|ms.sp.ext|78cf7810-a2c9-497e-bffe-8c25368c8bc0@fcd171b6-20f6-443e-8aea-474a4b529e6e
This is the identity that will run the workflow. If you review the permission mask in the AppPrinicpalPerms table for this appprincipal, you will see that it is set to "3" by default. The enumerations for the masks are:
- None
- Guest
- Read
- Write
- Manage
- FullControl
"3" means "Write". Which allows the workflow service to write out list items, but not to create lists. This would require level 4 or higher. You can elevate the permission mask with the following Windows PowerShell:
$web = get-spweb http://teams.contoso.com
$appworkflow = Get-SPAppPrincipal -site http://teams.contoso.com -nameidentifier 78cf7810-a2c9-497e-bffe-8c25368c8bc0@fcd171b6-20f6-443e-8aea-474a4b529e6e
Set-SPAppPrincipalPermission -AppPrincipal $appworkflow -site $web -right fullcontrol -scope site
Your workflow service app principal can now create lists!
Fabian will be researching how to add these app permissions in O365, of which he did here:
Enjoy!
Chris