Over the last few days or so, Christina Wheeler (@cwheeler76) and I were trying to figure out why my jQuery Library for SharePoint Web Services (SPServices) wouldn’t work when SharePoint was enabled for anonymous access. I had always assumed that it was just one of those things. Even though I couldn’t find any definitive documentation on it, there was enough speculation and innuendo that anonymous access and the Web Services wouldn’t mix that I just wrote it off.
Well, Christina posted a fantastic article on EndUserSharePoint.com last week called Real World Project: Transparent Overlays for SharePoint Interface Enhancement. In it, she described how she used some slick CSS tricks with the SharePoint Web Services and SPServices on a client’s home page for their Internet-facing site. Christina and I had even looked at an early version of the page together while she was working on it and I gave her some tips on how best to use SPServices. Somehow, though, we never talked about the fact that she needed anonymous access to work. We both missed that little wrinkle.
Skip forward a few days and she got a call from the client, wondering why people were being prompted for credentials. Uh-oh. I had steered her wrong on the use of SPServices. That was enough impetus right there to get to the bottom of the anonymous access with Web Services issue.
Well I’m happy to say that after some fiddling and help from Christina that I believe we’ve got it figured out. I had been *always* passing the SOAPAction in the RequestHeader. Everything that I had read had told me that was required, even the Web Services documentation in the SDK on MSDN. Christina pointed out this article from Jan Tielens: The security validation for this page is invalid" when calling the SharePoint Web Services. It also describes the problem and the solution using SOAPAction.
It turns out that you don’t need to pass the SOAPHeader if the Web Service operation is a read-only one. For instance, some of the most useful things, like GetListItems, don’t require it. In my testing, *none* of the read-only operations need the SOAPHeader. Oddly, if you don’t pass it with the read/write functions, they only fail if you *are* authenticated, the error says that you *aren’t* authenticated, and that you should hit the back button and refresh. Well that’s hardly helpful given that you aren’t working interactively, but talking to the Web Services programmatically.
So the solution was pretty simple, once I know what was going on. I added a new element to the WSOps array [true | false] for the requirement of SOAPAction. (The WSOps array is where I store which Web Service each operation belongs to.) All of the read-only operations are set to false, and the rest are set to true. If the value is false, I don’t pass the SOAPAction: problem solved. I released v0.5.3ALPHA2 with this fix tonight, and I’m pretty sure this method is a keeper.
This will be a great improvement to the library, allowing its use on public-facing Web sites. This is pretty exciting, really, as those are the sites where you are most likely to want to have real a Web 2.0 (whatever that means) feel to the site pages.