Question

I have a custom web service that runs in SharePoint 2007 as well as SharePoint 2010. I am currently testing only in SharePoint 2010 in my dev environment. I have some code that does the following:

bool allowUnsafeUpdates = web.AllowUnsafeUpdates;
try
{
    web.Properties[webPropertyBagKey] = value;
    web.AllowUnsafeUpdates = true;
    try
    {
        web.Properties.Update();
    }
    catch (Exception ex)
    {
        // Update failed likely due to security reasons, try with elevated privileges
        SPSecurity.RunWithElevatedPrivileges(delegate()
        {
            using (SPSite elevatedSite = new SPSite(web.Site.ID))
            {
                using (SPWeb elevatedWeb = elevatedSite.OpenWeb(web.ID))
                {
                    bool elevatedAllowUnsafeUpdates = elevatedWeb.AllowUnsafeUpdates;
                    try
                    {
                        elevatedWeb.Properties[webPropertyBagKey] = value;
                        elevatedWeb.AllowUnsafeUpdates = true;
                        elevatedWeb.Properties.Update();
                    }
                    finally
                    {
                        elevatedWeb.AllowUnsafeUpdates = elevatedAllowUnsafeUpdates;
                    }
                }
            }
        });
    }
}
catch (Exception ex)
{
    // log exception, but don't bubble it up...
}
finally
{
    web.AllowUnsafeUpdates = allowUnsafeUpdates;
}

Before I get to the code above, the SPWeb object (web) has been opened using a technique to impersonate the site owner by determining the site owner's user token and instantiating the SPSite object by providing the user token and getting the SPWeb from there. So, SharePoint API calls already have fairly elevated privileges.

What I found is that my first web.Properties.Update() seems to work fine if I authenticate to the web service using a site owner. However, if I authenticate to the web service using a user that simply has read access to the web, my web.Properties.Update() call fails. Not too bad, I had hoped, because I can just run with elevated privileges (which does a RevertToSelf and runs as the application pool owner). That code works properly but shortly after the code executes, the thread aborts while processing some other instructions (like the "{" after another try block in some other code.

The good news is that if I just RunWithElevatedPrivileges at all times, then I appear to be OK. Basically catching the original attempt leaves a lingering issue even though I don't bubble anything up.

Any idea what is going on here? I'm concerned that there are other places where I could run into this besides just saving SPWeb.Properties.

Was it helpful?

Solution

You might want to try turning off SharePoint's built in handling of AccessDenied exceptions which by default seem to cancel the current request and often causes ThreadAbortExceptions.

SPSecurity.CatchAccessDeniedException

Setting this property to false should allow you to handle the accessdenied exception yourself. Remember to restore its value once you are done.

OTHER TIPS

I've encountered a similar situation - at least I think this could be it. The way to solve it was to understand what I'm really doing when calling for example using (SPSite elevatedSite = new SPSite(web.Site.ID)) from inside a delegate in RunWithElevatedPrivileges.

The thing is, it seems the delegate is running on a different thread. So instead of using web.Site.ID (which is in another thread), you need to store all the data you'll need (all the IDs etc.) in simple variables before entering the delegate. That should take care of the thread aborts.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top