SPServices: SPRedirectWithID in Anonymous Mode – Nope, Won’t Work

I got a question about the SPServices function SPRedirectWithID via email yesterday, and it seemed like it would be good to answer it in a blog post. The idea behind SPRedirectWithID is to allow you to redirect the user to some other page from a NewForm, with the new item’s ID on the Query String.

I’ve been able to implement your $().SPServices.SPRedirectWithID script very successfully. As long as I’m a signed-in user, it works beautifully, redirecting me to a custom display page I put together. Unfortunately I can’t get it to work for an anonymous user. I have given anonymous users access to the list that creates the new item, and have given them permission to add an item. The customized NewForm.aspx loads fine, but once it is submitted, I get the following error: “The data source control failed to execute the insert command”. The funny thing is the new item is created in the target list, but the redirect will not work. I had a workflow attached to the whole procedure, so I tried the whole thing with a new list. This time it just hung on the script, and wouldn’t do anything, yet still it did create the new item. But once I log in as with my Sharepoint credentials, everything works fine. Is it just that these type of list transactions are impossible for anonymous user?
Thanks in advance for any insights you might have.

Nope, SPRedirectWithID won’t work in anonymous mode. It can’t because of the way I’ve had to build it to deal with the commit mechanisms for SharePoint lists. In fact, this was one of the hardest functions to get running in SPServices because of those mechanisms. (As of this writing, it’s stopped working with Firefox, and I have yet to figure out why.)

Here’s the way SPRedirectWithID works, from the documentation. Assuming your NewForm is called NewFormCustom.aspx and the redirectUrl is set to EditForm.aspx, like this:

  redirectUrl: "EditForm.aspx"
  • On the initial load of NewFormCustom.aspx, the form action is changed to point back to the same page, with ?Source=NewFormCust.aspx?ID=[the last ID created by the current user]%26RealSource=[the actual Source for the page]. The [the last ID created by the current user] is determined by calling the $().SPServices.SPGetLastItemId function.
  • When the form reloads, because the ID is present on the Query String, the function then waits until [the last ID created by the current user] is not equal to the value on the Query String. This ensures that the commit has completed. The [the last ID created by the current user] is again determined by calling the $().SPServices.SPGetLastItemId function.
  • The user should then be redirected to EditForm.aspx?ID=[the last ID created by the current user]

The tricky part there is the [the last ID created by the current user] part. If we’re in anonymous mode, there is no current user; they are anonymous. If multiple people are submitting items, then we don’t know which one belongs to each person. So the way I’ve built the function (to be reliable) it won’t work in anonymous mode.

All that said, if you feel like you need something similar to work in anonymous mode (and can live without Firefox and possibly other browser support), then you could simplify the function to work for yourself. just be careful!

Bonus bit: I also got this comment on the documentation page for SPRedirectWithID this week:

I’ve got a list with a custom new item form, and it turns out that the SPRedirectWithID function will not work if there is not already a redirect statement applied to the ‘save’ button. The function works perfectly with a standard form, but it will fail if the “save” button only performs a commit – it must also have a redirect action applied. I dont’ know if I just missed this in your setup, but it might be important for those of us who are using custom forms.

True, dat. If the page isn’t going to redirect on submit, then this function won’t work because, as I’ve outlined above, it piggybacks on the existing redirect.

What About Anonymous Writes to SharePoint Lists with Web Services? – Follow Up

In my post What About Anonymous Writes to SharePoint Lists with Web Services? the other day, I wondered why the SharePoint Web Services don’t allow anonymous updates to SharePoint lists through the Web Services, even when anonymous write access is enabled on those lists.

Since then, I’ve gotten two independent answers that tell me that it just isn’t possible.

From a well-respected SharePoint MVP (I won’t name him because I didn’t ask him if I could):

The anonymous settings in Site Settings / Central Admin will only update the content virtual directory in IIS. Web services live in the _vti_bin folder, which is not updated from those settings pages.

I would recommend writing a custom web service that accepts anonymous input, performs data validation, value scrubbing, logging (IP address, date-time, etc.) and most importantly watches for multiple updates from the same source to prevent denial of service attacks.

And in a blog post that my pal Ben McInerney found: 401 Reasons Why SharePoint Web Services Don’t Work Anonymously (From someone named Chris Domino? Chris, you need an About page!):

But when anonymous is set, we get that one line message: “401 UNAUTHORIZED.” Obviously, this is not coming from IIS. My only guess, after going through the trouble of Reflecting what I could of Microsoft.SharePoint.dll, is that code inside the web method sends this response if the current user is not authenticated, regardless if it’s virtual directory is set to be anonymous.

Regardless whether allowing this type of access is a good idea, it just doesn’t make sense to me.  If you are running a serious corporate site that gets thousands of hits a day, then the Denial of Service (DoS) issue is a very real one. If you’re using WSS for your kid’s soccer team or for a small business, then this concern just isn’t on your radar screen.

I’m disappointed in these findings, and would love to hear that I’m wrong in my conclusions.  Luckily, I’ve at least been able to get anonymous reads working with the Web Services in my jQuery Library for SharePoint Web Services (SPServices).  That’s a huge set of capabilities right there, but I really wish that the writes worked, too.

What About Anonymous Writes to SharePoint Lists with Web Services?

Here’s the nut of the question.  SharePoint’s Web Services fall into two main classes: those that read (generally Get* methods) and those that write. Others don’t really make sense unless you are authorized, like the Users and Groups Web Service.

In situations where you are allowing Anonymous Access, it makes perfect sense to be able to use the read functions, and I’ve solved that in my jQuery Library for SharePoint Web Services (SPServices), by not sending the SOAPAction in the RequestHeader. (This was not something I ever saw any documentation on, and I only recently figured out that it worked.)

But what about anonymous writes?  You can enable that through the UI for specific lists, but how can you make it work with the Web Services, for instance the UpdateListItems method? It seems like the Web Services ought to “respect” the permissions settings across the board, but it doesn’t seem that simple.

If anyone reads this who has an "in" with the smarties over at Microsoft, I’ve love to know what the answer is.  I’d really like to make it possible in SPServices to write to lists anonymously where the permissions allow it.

Enabling Anonymous Contributions to a SharePoint List

Cross-posted from EndUserSharePoint.com

If you are using WSS or MOSS for a public-facing site, you may want to allow people to post content in a limited way. A great example of this is where you want to have a Contact Us form on your site. If you have serious concerns about security, then this article is probably not a good answer. If you are a small business or organization that wants to use WSS for a public-facing site, then this is a great tip for you.

Let’s assume that you already have a site set up which allows anonymous access (and that all of your licensing is in order to do so). Set up a Custom List that contains the columns you want to collect; let’s call it Contact Us. Here’s an example:


This renders a form that looks something like this:


(I’ve done a little light branding on this one, so yours will look a teeny bit different.)

Now go into the List Settings for Contact Us:


(My custom branding again, and, no, it isn’t a Christmas store.)

Now go to Permissions for this list:


Then under Actions, choose Edit Permissions. This will “break” the inheritance of permissions from the containing site, allowing you to customize the permissions for just this list.


Agree to the warning message:


Now under the newly exposed Settings menu option, choose Anonymous Access:


Finally we can set the anonymous permissions how we’d like them. In the case of a Contact Us form, you’ll probably want to let people add items, but nothing else (you get View Items when you check Add Items):


Now you can embed a form into your Contact Us page for this list, and anyone, authenticated or not, can create items. If you want to monitor the list, you can either set a simple alert on it or create a SharePoint Designer-based workflow to send out customized emails with the item contents embedded in them.