Allowing Anonymous Access with SharePoint Web Services and SPServices

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.

Similar Posts

33 Comments

  1. Remember, Marc, anonymous access to Web Services is a discussion we had a couple months ago. You even sent an e-mail to Microsoft.
    Well, I definitely want to try this out. For me, the fact that Web Services were only for authenticated users has always been a major issue. As you say, this is exciting news!

    1. Christophe:

      I’ve had more than one conversation about this “limitation”! I’m hoping that this is a legitimate solution. I’ve pinged my pals @MSwannMSFT and @spwiki over at Microsoft (at your suggestion) to see if they can lend any credence to the approach.

      M.

  2. Hi Marc,

    Its funny – our paths have converged for the very same reason – I too thought “Uh-oh. I had steered *myself* wrong on the use of SPServices”. Was I trying to be too clever for my own good!?

    I have implemented the very solution that you refer to in your EndUserSharePoint article “Enabling Anonymous Contributions to a SharePoint List” – even to the extent of being a Contact Us form, but using Ajax instead of the OOTB postback.

    Months ago, I had successfully created a cool page with JQuery supplying the form validation, Ajax submission to create new List Item (UpdateListItems), “submit success” overlaid dialogues &etc and it worked a treat in development. I implemented the Ajax code using Jan Tielens magic work.

    Happy and proud Days!

    Come the time of deploy + test, and i was presented with the infamous Credentials Dialog.

    I have (since researching and coming across Jans and your articles) configured Anonymous Access, discovered that it is an web services issue, and with great trepidation (after reading this article), removed the SOAP Header in hope that it would work for unauthenticated users as per your comment “…if you *don’t* pass it with the read/write functions, they only fail if you *are* authenticated.” (when live, all my users will be anonymous).

    Unfortunately, there was no change – the Credentials Dialog is still appearing.

    Can you offer something of a Master Checklist of how you/Christine Wheeler got things working? But specific to using Write web services. Are there any tricks in your CodePlex Library that makes it a better choice than the basic version offered by Jan T.?

    Cheers,
    Ben

    1. Ben:

      I haven’t tried to solve the “write with Web Services anonymously” problem, at least yet. The main thrust of this article (and release v0.5.3 of SPServices) was to get the read capabilities working.

      I pinged a few of my contacts at Microsoft about these questions, but I haven’t heard back yet. In the meantime, I believe that v0.5.3 at least lets the read functions working. I’d be interested to hear if you try that at all and how it works for you.

      M.

  3. Hey Marc,

    Much appreciated! I will battle on and when (if?) I get a viable solution I will post back here with details.

    It will be a great shame to have to axe the Ajax functionality, and revert to the clunky post-back.

    My client is tap-tapping their feet on this one, so the pressure is on…

    Ben

  4. Hi Marc,

    Call off the dogs – seems like I found the answer I DIDNT want… and it’s a show-stopper – and the reason why is a bit mind-boggling as to why Microsoft did what they did.

    No matter what security you apply to your servers, SharePoint is *** HARD-CODED*** to ignore it and kick back a 401 UNAUTHORISED message.

    This morning I stumbled on this definitive explanation as to why it doesn’t work:
    http://chrisdomino.com/Blog/Post/401-Reasons-Why-SharePoint-Web-Services-Don-t-Work-Anonymously?Length=4

    Sigh,
    Ben

  5. It would be nice to know if this is supported (removing the soapheader). Wouldn’t want a service pack or hotfix “correcting” this workaround.

    1. Jon:

      As I mentioned above, I really don’t have any contacts at Microsoft who I can get information like this from. If you know anyone, please let me know! I suppose one plus is that SharePoint 2007 is unlikely to get any significant changes with SP2010’s release being imminent. However, I’m trying to be sure that SPServices is compatible with both.

      M.

  6. Marc,
    This worked perfectly for me, will see if anything comes up in testing, but looking great so far!

    Can’t believe how hard to track down this post was!

    1. This method has been a part of SPServices since this post (about a year) and it hasn’t fallen down yet. AFAIK, I’m the only one who’s ever figured this out. :-) It’s certainly not anywhere in the SDK.

      M.

  7. This code snippet works fine when I don’t turn on Anonymous access

    SocialCommentData.SocialDataService mysocialDataService = new SocialCommentData.SocialDataService();
    mysocialDataService.Credentials=System.Net.CredentialCache.DefaultCredentials;
    mysocialDataService.Url=URL+”/_vti_bin/socialdataservice.asmx”;
    SocialCommentData.SocialCommentDetail[] comments=mysocialDataService.GetCommentsOnUrl(URL,null,null,null);
    But when annonymous acces turn on at Sharepoint Site Permission I got Unauthorised Access error.

    I am looking for a solution and I came to see your site. You seem to have solution but I have no idea how to remove the soap header which you mentioned about. Any pointers?

    1. Leo:

      I’ve implemented this solution in my SPServices jQuery library on Codeplex. I’m not sure what context your code come from, but you may not be able to pull off this trick.

      M.

    1. Calvin:

      Support from anonymous writes (assuming all the other criteria are met) has been in SPServices since the release following this post, which is from way back in 2010.

      M.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.