I am building a custom Rest service to be hosted on a SharePoint 2013 farm. The service currently has only one method called "Ping" which simply return the current DateTime.
public interface IService
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
DateTime Ping();
}
Following the many online tutorials, I have created a .svc file to be deployed to the ISAPI folder. I use the standard REST service factory, MultipleBaseAddressWebServiceHostFactory:
<%@ ServiceHost Language="C#" Debug="true"
Service="............"
Factory="Microsoft.SharePoint.Client.Services.MultipleBaseAddressWebServiceHostFactory,
Microsoft.SharePoint.Client.ServerRuntime, Version=15.0.0.0, Culture=neutral,
PublicKeyToken=71e9bce111e9429c" %>
Service endpoints seems to be there, but any attempt to call the service from JavaScript fails with a 401 Unauthorized exception. I have tried both $.ajax call and fiddler calls. Also notice that the ajax call is performed by a script running in a web part on the same site collection I call the service on.
The funny thing is that if I browse the page with the offending web part (the one that calls the custom service) I get the standard windows login credential prompt but even if I insert the correct credential the system just ask them again (up to three times - why three?).
I am stumped understanding what is happening here. SharePoint 2013 sites by default use claim based authentication, and I can see from fiddler that the server is attempting to negotiate NTML auth with the caller, so I assume that this is the reason the call doesn't work.
What I really don't understand is why all the online sample and tutorial don't seem to be affected by this problem. I guess there must be something obvious I am missing... but what?
See for example this page: SharePoint 2013: Create a Custom WCF REST Service Hosted in SharePoint and Deployed in a WSP. There is no sign of special configuration or anything (no override web.config service configuration file either), yet the tutorial claims that I should be able to call my service with a basic $.ajax call. Where is the difference? Are all this tutorial actually wrong? Default site auth schemas have been changed between the 2010 and the 2013 version, so it wouldn't surprise me if the sample where outdated...
EDIT:
I have made some attempt to consume the service via a standard C# console application
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("...", "....");
client.Headers["Content-type"] = "application/json";
client.Encoding = Encoding.UTF8;
string response = response = client.DownloadString(serviceUrl);
This also fails with a 401 error. Credentials are correct.