Related to this question.
Also, full disclosure – I have only developed a very few custom web services, and have very little experience with .NET outside of SharePoint, so I am very unfamiliar with
web.config settings, bindings, all that kind of stuff. I know what they are, I just don’t know how to interpret and use them very well. So the answer to this may be very simple and I just don’t see it.
I have deployed my own custom web service
MyCustomService.svc to the SharePoint
ISAPI folder, which exposes it at the URL
I try to call that web service using the stock SP 2013
Microsoft.Activities.Messaging.HttpSend activity from within a custom declarative 2013 workflow.
My calls always result in a
401 UNAUTHORIZED response. Examining the response headers, I can see that one of the headers is
which tells me that IIS is challenging the caller (Workflow Manager) to authenticate in order to access the service. A subsequent call that includes the authentication information never happens, and the request ultimately fails.
Now, I know that the built in SP REST API exposed at
/sharepoint-site/_api/...etc... is actually mapped to
/_vti_bin/client.svc. And I know that if I make a call to that endpoint from a workflow using the
HttpSend activity, the call will work and I will get a response from the web service.
If I look at the IIS logs from such a call, I see:
2021-02-26 18:15:35 184.108.40.206 GET /sites/my-site/_api/web/lists(guid'xx-xx-xx-xxxx')/items(8) - 443 - 220.127.116.11 - - 401 0 0 6 2021-02-26 18:15:35 18.104.22.168 GET /_vti_bin/client.svc/web/lists(guid'xx-xx-xx-xxxx')/items(8) - 443 0#.w|domainmyaccount 22.214.171.124 - - 200 0 0 35
What’s interesting to me about that is that the first call does not include user information and in fact is responded to by a
401 UNAUTHORIZED response. (I can only assume that that response also includes the
WWW-Authenticate: (NTLM) header.)
But then Workflow Manager apparently understands that response, and then immediately sends another request that includes the authentication information for the user that initiated the workflow. (The user account shown in the IIS logs corresponds to a real user, the user that initiated the workflow, not the service account that Workflow Manager is running as.) And then, with the correct authentication information included, the request succeeds (
So… why doesn’t Workflow Manager handle the initial
401 response from my custom service the same way, and immediately try to send another request that includes the authentication information of the user who initiated the workflow?
Is there something I need to include in the configuration of my custom web service to tell Workflow Manager that it’s OK and possible to respond to an initial
401 with another call that includes authentication info?
I’ve looked through the
web.config in the
ISAPI folder, and I don’t see anything specifically calling out the
client.svc endpoint or the mapped
I do however see a bunch of stuff called
WorkflowSolutionsServiceBehavior that reference these other bindings called
StreamBindingXX. Do I need to configure my web service to use either one of those
WorkflowSolutionServiceBehaviors, or to use one of the
StreamBindingXX bindings? If so, how do I do that?
I am not doing any
SPWebConfigModification on feature activation, although I am aware of what that is and am comfortable doing so if that’s what is required. I just don’t know what modifications I need to make in order to get things working.
I am happy to post my custom web service code if that helps.
(Also, just want to add that my custom service works fine when tested with Postman or called from JS in a browser – between looking at Fiddler data and the IIS logs I can see that the initial request is responded to with a
401, but then apparently the browser handles that and then sends the authentication information (since I am not prompted for login information). The problem I am trying to solve here is that the initial
401 is not handled when the call is coming from Workflow Manager.)