SharePoint Designer 2007 Workflows, System Account, and Declarative Starts

I want to clarify the well known WSS SP1 declarative workflow issue that’s found in abundance on the web. We ran into this recently when attempting to use the Start Another Workflow activity that comes with the Useful SharePoint Designer Custom Workflow activities codeplex solution. Actually, if you read through the comments on codeplex, others are having the same problem with nothing really identified as the fix. This post will outline our solution, along with some guidance on the recommended Microsoft route.

This issue is outlined in detail here: http://support.microsoft.com/kb/947284.

Directly from MS: After you install Windows SharePoint Services 3.0 SP1, declarative workflows do not start automatically if the following conditions are true:

  • The Windows SharePoint Services Web application runs under a user’s domain account.
  • The user logs in by using this domain account.
  • The site displays the user name as System Account.

So typically, when we install SharePoint 2007, we have a domain admin account that we do the installation under, or even a local administrator, and we specify a service account during installation that’s responsible for running our services and app pools. You’ll notice that when you log into SharePoint using this service account, regardless of the name of that service account, it will display System Account. This is important to understand.

What Microsoft is asking us to do is change the application pool, so it runs under someone other than what you’ve specified for the service account. So, if for example our service account upon installation was domainwss_service, our app pool will run under domainwss_service. You’ll need to change that to domainnew_account.

Ok so none of that was really new information, but I do want to shed some light on the issues that users are experiencing with the Start Another Workflow activity that was the original motivation behind this post. Basically, if you look through the codebase, Start Another Workflow uses elevation to do what it needs to do, to trigger the requested workflow. Elevation always runs under the credentials of the account specified to run the application pool. Read this post and it’s comment entirely to understand this process: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spsecurity.runwithelevatedprivileges.aspx.

Because we’re trying to trigger another workflow (that’s the whole point of this activity) and we’re doing it while elevated, thus running as the app pool account, IF this account also happens to be the System Account, you will receive the declarative workflow error. So, again, you either change that app pool account, or you can do something like this:

// even when taking the elevation out of this code, the workflow would still
// trigger as System Account. In theory, users may not have Start Workflow permissions
// on a given list, so it makes sense to impersonate and leverage a workflow_svc account
SPUser user = web.SiteUsers[@"domain\new_account"];
// we could use: __Context.Web.CurrentUser.UserToken
// but what if user does not have access, so we use user instead
SPSite site2 = new SPSite(site.ID, user.UserToken);
SPWeb web2 = site2.OpenWeb();
 
// using the debugging information below, we are able to see the following output:
// user running under: Joe User
// site user: Sytem Account
// context user: Joe User
// so the web objected instantiated above is using the System Account context
string userString = "user running under:" + __Context.Web.CurrentUser.Name;
string siteUser = "site user:" + web.CurrentUser.Name;
string contextUser = "context user:" + web2.CurrentUser.Name;
 
Common.AddCommentWorkflowHistory(userString, executionContext, this.WorkflowInstanceId);
Common.AddCommentWorkflowHistory(siteUser, executionContext, this.WorkflowInstanceId);
Common.AddCommentWorkflowHistory(contextUser, executionContext, this.WorkflowInstanceId);
 
// so when we create our SPList object below, we have to use web2, not web
// so that we can make sure our workflow runs under the user context not System Account
// why don't we want to run under System Account? because SP1 prevents declarative workflows.
SPList list = web2.Lists[new Guid(ListId)];
 
SPListItem listItem = list.GetItemById(ListItem);
 
SPWorkflowAssociation myWorkflowAssoc = null;
 
//resolve any lookup parameters
string wkId = Common.ProcessStringField(executionContext, this.WorkflowIdentifier);
 
//find workflow association by name
myWorkflowAssoc = list.WorkflowAssociations.GetAssociationByName(wkId, System.Threading.Thread.CurrentThread.CurrentCulture);
 
if (myWorkflowAssoc != null)
 {   
     // using site2 to start the workflow is not enough, the listItem passed into the StartWorkflow
     // method has to have been instantiated using the web2 object
     site2.WorkflowManager.StartWorkflow(listItem, myWorkflowAssoc, myWorkflowAssoc.AssociationData, true);
}
 
site2.Close();
web2.Close();

The above code is a direct replacement of what’s currently in source on codeplex for the Start Another Workflow activity. This is just presented as an option to those not wanting to change their app pool configuration for whatever reason.

3 Responses to “SharePoint Designer 2007 Workflows, System Account, and Declarative Starts”

  1. jkormann October 20, 2011 at 2:53 am #

    Replacing the line,
    SPWeb web2 = site2.OpenWeb();

    with

    SPWeb web2 = site2.OpenWeb(web.relativeaddress);

    will allow it to work with lists that are in sub-sites. Otherwise the fix will only work with lists that are on the site collection’s web site.

  2. shereen October 20, 2011 at 8:04 am #

    Interesting, thanks for the comment. I’ll definitely confirm that when I originally wrote this up, I was working within the lists at the site collection level. Again, thanks for posting for others to see.

  3. sam May 28, 2015 at 10:48 am #

    Hi,

    I understand the declarative error issue with system account etc. But in my scenario, the workflow is not throwing any error at all. Workflow A is calling Workflow B and completes.

    In the list, Workflow A shows as ‘completed’ but Workflow B shows nothing, i.e. no erros or any other status.

    It seems that the workflow A’s call to Workflow B is not doing anything at all.

    Any ideas on this by any chance?

    thanks

Leave a Reply