Wednesday, March 12, 2008

SharePoint: Checking User Permissions On a Web/List/Item

When writing any kind of application that has more than one role it's often the case that you end up showing/hiding page elements based on the users security. This holds true for applications and Web Parts that are in SharePoint as well. Thankfully this is taken care of for us in WSS/MOSS, at least when it comes to Webs (SPWeb), Lists (SPList) and List items (SPListItem). All these objects (and potentially more) implement the ISecurableObject interface which among other useful methods and properties has the DoesUserHavePermissions() method.

This method takes one or more SPBasePermissions and will tell you if the current SPUser (or another one if you're checking SPList/Item/Web/Site) has the given permissions. There's a ton of permissions that are available, and they're analogous to what you would set in the permission screen in the SharePoint UI. You can find a list of them here.

It's important to note that the SPBasePermission enum uses the [Flags] attribute which means you can check many at the same time by using the bit wise OR (|) operator. You can check to see if a user has permissions on a list (or any ISecurableObject) this with code like:

if (list.DoesUserHavePermissions(SPBasePermissions.ViewListItems)
{
//do something clever...
}

Because they all implement ISecurableObject you can use similar code on SPWeb, SPList and SPListItem.

To programmatically check to see if there is anonymous access allowed on a list you can do something like:

if ((list.AnonymousPermMask64 & SPBasePermissions.ViewListItems) == SPBasePermissions.ViewListItems)
{
// do something clever...
}

Finally I'd like to share a wonderful control that's saved my bacon a couple of times. Because our changes to SharePoint should always be subtle and involve as little code as possible, it's often convenient to show hide content by declaratively setting down some syntax in SharePoint Designer. The SPSecurityTrimmedControl allows us to do just that. This control will hide content for any user who doesn't have the appropriate permission. I often use this control to wrap the Site Actions Menu to hide the "View All Site Content" when that's the only permission users have. For example:

<Sharepoint:SPSecurityTrimmedControl runat="server" PermissionsString="AddAndCustomizePages" PermissionContext="CurrentSite">
Any HTML or controls between these tags will only show for users who have the 'AddAndCustomizePages' permission.
</SharePoint:SPSecurityTrimmedControl>

Note that the permissions that appear in the PermissionsString are analogous to those listed above, so strings like 'ViewListItems' apply. You can also set an optional PermissionContext which can be any of the contexts listed in the enum.

Hope some of that's useful.

Best,
Tyler

7 comments:

AAron nAAs said...

You write:
>the DoesUserHavePermissions() method.
>This method takes one or more SPBasePermissions
>and will tell you if the current SPUser
>(or another one you want to check)

I don't see how to check the permissions of an arbitrary user. DoesUserHavePermissions only seems to check the "current user"

Tyler Holmes said...

Aaron,

You're technically right. The ISecurableObject interface only exposes the single DoesUserHavePermissions(SPBasePermissions) method. However all of SPListItem, SPList, SPWeb and SPSite also have an overloaded version of the method which allows you to specify an SPUser and allow you to check the permissions of an arbitrary SPUser. The method signature is DoesUserHavePermissions(SPUser, SPBasePermissions).

I'll update the article to make the distinction. Thanks for posting!

AAron nAAs said...

The reason that matters is that I wanted to examine the security for an arbitrary user for a generic ISecureableObject. I didn't want to have a bunch of "obj is SPWeb" type ifs, or have to use Introspection to get the proper DoesUserHavePremissions method. I thought you might have known something that I didn't see. I guess this is one case where the Interface design may have lagged behind the design of the actual implementation folks.
Thanks for the reply.

Vishal's Blog said...

Hello Tyler

In my webpart I want to show all Webs from all webapplications in farm which user has access. I am taking help of SpSecurity.RunWithElevatedPrivalege but still getting access denied error.

SPSecurity.RunWithElevatedPrivileges(delegate()
{

SPFarm spf = SPFarm.Local;
SPWebService spws = spf.Services.GetValue(SPWebService)("");

foreach (SPWebApplication spwa in spws.WebApplications)
{
foreach (SPSite oSiteCollection in spwa.Sites)
{

foreach (SPWeb oWeb in oSiteCollection.RootWeb.Webs)
{
if (oWeb.DoesUserHavePermissions(SPContext.Current.Web.CurrentUser.LoginName, SPBasePermissions.Open))
{
writer.Write(oWeb.Title + " " + oWeb.WebTemplate);
oWeb.Dispose();
}
}
oSiteCollection.Dispose();
}
}



}
);

I assume I will have to check SpSite.DoesUserHavePermissions for SiteCollections as well. I am not sure how to use for SPSite.DoesUserHavePermissions(SPReusableAcl, SPBasePermission) method.

Please suggest how to use or why I am getting access denied message.

david lozzi said...

awesome!

Varshan said...

Have a look at the article "Check User Permissions Programmatically in SharePoint 2010"

at http://tad.co.in/?p=748

digital signature said...

A special thanks for this informative post. I definitely learned new stuff here I wasn't aware of !