Trigger workflow for an item in the list by using CSOM. (env: SP 2013 on-prem, provider hosted app) and App Only will not work

This post is a contribution from Manish Joshi, an engineer with the SharePoint Developer Support team

There seems to be a check in SharePoint when starting a workflow using CSOM if SharePoint 2013 workflow is started using the App-Only context – if yes, throw Access Denied exception and log this exception.

So there is no other way than to start a SharePoint 2013 workflow in CSOM except using the App+User context

Following code illustrates using an app only access token to create a ClientContext and start the SharePoint 2013 workflow in CSOM.

  1. Get the Client Context using the App only Access Token

     // get app only access token by passing the windows identity as null
    string appOnlyAccessToken = TokenHelper.GetS2SAccessTokenWithWindowsIdentity(hostWeb, null);
    return TokenHelper.GetClientContextWithAccessToken(hostWeb.ToString(), appOnlyAccessToken); 
    

     

  2. Invoke the workflow using the Client Context retrieved

     // start the workflow using the CSOM APIs and the client context retrieved previously
    var workflowManager = new WorkflowServicesManager(clientContext, clientContext.Web);
    InteropService workflowInteropService = workflowManager.GetWorkflowInteropService();
    
    // call the StartWorkflow method   - https://msdn.microsoft.com/en-us/library/office/microsoft.sharepoint.client.workflowservices.interopservice.startworkflow.aspx
    workflowInteropService.StartWorkflow(workflowAssociation.Name, corId, list.Id, itemGuid, new Dictionary<string, object>());
    clientContext.ExecuteQuery();
    

     

The above code will throw AccessDenied exception.

 

To get this to work the code needs to be changed as below.

  1. Get the Client Context for App + User context access token

     // pass a valid windows identity to get app + user context
    string appUserAccessToken = TokenHelper.GetS2SAccessTokenWithWindowsIdentity(hostWeb, windowsIdentity);
    return TokenHelper.GetClientContextWithAccessToken(hostWeb.ToString(), appUserAccessToken);
    

     

  2. Invoke the workflow using the Client Context retrieved

     // start the workflow using the CSOM APIs and the client context retrieved previously
    var workflowManager = new WorkflowServicesManager(clientContext, clientContext.Web);
    InteropService workflowInteropService = workflowManager.GetWorkflowInteropService();
    
    // call the StartWorkflow method   - https://msdn.microsoft.com/en-us/library/office/microsoft.sharepoint.client.workflowservices.interopservice.startworkflow.aspx 
    workflowInteropService.StartWorkflow(workflowAssociation.Name, corId, list.Id, itemGuid, new Dictionary<string, object>());
    clientContext.ExecuteQuery();