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
https://sharepoint-server/sites/my-site/_vti_bin/MyCustomService.svc
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
"WWW-Authenticate":["NTLM"]
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 1.2.3.4 GET /sites/my-site/_api/web/lists(guid'xx-xx-xx-xxxx')/items(8) - 443 - 1.2.3.4 - - 401 0 0 6
2021-02-26 18:15:35 1.2.3.4 GET /_vti_bin/client.svc/web/lists(guid'xx-xx-xx-xxxx')/items(8) - 443 0#.w|domain\myaccount 1.2.3.4 - - 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 (200
).
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 /_api/
endpoint.
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 WorkflowSolutionServiceBehavior
s, 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.]