R – SOAP web service running on SharePoint

sharepointsoapweb services

I have a SOAP web service running on my sharepoint box under the _layouts directory, and a thick client which uses that SOAP service. We have one sharepoint box that uses basic auth and another which uses client certificates. I need that SOAP service to update some list items in a document library. The problem I'm having is nothing seems to work unless I run within an elevated privileges block. Here is a code snippet of what I'm trying to do.

using (SPSite site = new SPSite(fileUrl))
using (SPWeb web = site.OpenWeb()) {
   // web.CurrentUser is always null unless in elevated privileges block.
   // do something with document library...
   web.Files.Add(...); // fails with access denied unless in elevated privileges block.
}

I also tried "SPContext.Current.Web" but it returns null for "web.CurrentUser" even if I'm in an elevated privileges block.

I really can't use an elevated privileges block because the users complain that anything my SOAP service touches has a modified by system.

From the thick client we are using code like the following…

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestString);
if(basicAuth) {
   request.Credentials = System.Net.CredentialCache.DefaultCredentials;
}
else {
   X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
   store.Open(OpenFlags.ReadOnly);
   foreach (X509Certificate2 certificate in store.Certificates) {
      request.ClientCertificates.Add(certificate);
}
request.GetResponse();

We are manually constructing the SOAP request for various reasons.

Best Answer

If you want your webservice to properly integrate within the sharepoint context (i.e. being able to query the "current sharepoint user"), you should really deploy it to _vti_bin (the ISAPI subfolder of the 12 hyve), not to _layouts.

Discovery is a bit of a pain and requires manual tweaking of files (see the MSDN article on custom webservices within SharePoint for more information), but as you are hand-building your request anyway discovery should not be an issue.

[Edit] As an alternative, you can try acquiring the SPUserToken of the windows authenticated user,

SPUserToken token = web.AllUsers[WindowsIdentity.GetCurrent().Name].UserToken;

and then use this token to open the site and web as this user.