"Access Denied" on Custom Web Part

I spent a couple of nights working a custom web part for a client. The purpose of the web part is to recursively walk through all sub-sites and roll up all the calendar events marked with a special flag. After including it in a feature, deploying and unit testing the web part, I was confident that it was working as designed. So, I released it for user acceptance testing.

 

Right away, I started to hear about users getting “Access Denied” errors. I thought an administrator had changed permissions on the sites. So I looked at all the security settings for all the sites but couldn’t find why users kept getting that error. It’s not until I got on a Live Meeting with a user that I found the cause was my custom web part.

 

When I did my unit testing, I was testing the web part under a site collection admin account. So I never encountered those errors. I took myself out of the site collection administrator group and just gave myself view permission. Right away, I started to see the same “Access Denied” errors. I went into debug mode and found it was throwing “unauthorized exceptions” because I was enumerating through all sub-sites and lists. This is the correct behavior because you’re not supposed to be able to go into a site or list if you don’t have access, whether you’re doing it in the browser or through code. Anyways, I changed the code so that I only retrieve the sites and lists to which I have access to. That fixed the problem.

 

To retrieve sub-sites to which the current user has access, use the SPWeb.GetSubwebsForCurrentUser() method. To retrieve lists to which the current user has access, set the SPWeb.Lists.ListsForCurrentUser property to true, and then just loop through the SPWeb.Lists collection as usual. To check if a user can access a site or list, use the DoesUserHavePermissions method of either the SPWeb or SPList class.

 

Lesson learned: when developing a custom web part, don’t run it under an account which has site collection admin permission.