SharePoint Security and the Object Model – Part 3

Authorization and Access Control – Evaluating Permissions

This is the third part of a three part post on security object model basics in SharePoint. The other posts are: SharePoint Security and the Object Model – Part 1 and SharePoint Security and the Object Model – Part 2. The first post covers users and groups, the second post covers the mechanics of defining and applying permissions. This post is about using and applying user, groups, and permissions to control the user’s access and experience in a site in the UI and in code.

Why is this Necessary?

Before I talk about using permissions to control access (which is very easy), let’s consider why you need to know anything beyond the first two posts in this series. In the first post, you learned how to work with users and groups. That post even covered how to add users to groups based on claims with SPClaim and SPClaimProviderManager. If you know how users and groups work, why not write code that checks permission based on user or group names?

I’d bet that most of you instinctively know why this is a very bad idea – users and groups change. Obviously you wouldn’t want to write your security code based on them. But, what about claims? If you are using claims you will be tempted to write code that checks for a claim via ClaimsIdentity.Claims or a custom claim manager. If you’ve seen my Claims Identity presentation, you may recall that I use an example where the doorman lets Mary enter because she has a claim that says she is over 21. Writing code that checks for the claim directly is just as big a mistake as checking for a specific user or group, but for slightly different reasons.

Checking for a claim directly creates a dependency between your code and Windows Identity Foundation. Depending on how you do it, it might also create a dependency on a specific identity provider. It also makes your code very inflexible and requires development if the rules change.

You should never perform authorization checks based on users, groups, or claims. Instead you should use permission levels and role assignments as discussed in part 2 of this series. To perform authorization checks you should always use the simple techniques discussed below for maximum flexibility. Although doing all the work discussed in parts one and two to enable these techniques may seem like a lot of work, it is the least amount of work that doesn’t create lots of trouble over time.

DoesUserHavePermissions

ISecurableObject defines a method named DoesUserHavePermissions. The abstract SPSecurableObject provides an implementation of this method that is overridden in the various securable object implementations, i.e. SPWeb, SPList, and SPListItem. The base definition of DoeasUserHavePermissions is simple (see part 2 for more on SPBasePermissions):

public
virtual
bool DoesUserHavePermissions(SPBasePermissions permissionMask)


 

It returns true or false given a permission mask for a given web, list, or item for the current user. For example:

bool hasPermission = SPContext.Current.Item.DoesUserHavePermissions(SPBasePermissions.EditListItems);
writer.Write("User can edit this item = " + hasPermission.ToString());


 

Note:
In older versions of SharePoint this method has the bizarre behavior of throwing UnauthorizedException
instead of returning false.
This alternative code produces the same result:

permissionMask == SPBasePermissions.EmptyMask || (itemToCheck.EffectiveBasePermissions & permissionMask) == permissionMask;

(itemToCheck is a valid instance of an SPSecurableObject)

SPSecurityTrimmedControl

SPSecurityTrimmedControl is a handy web control that provides a container for other controls and markup. You simply provide a permission mask for the PermissionString property and SharePoint takes care of the rest! You can use it on pages and in user controls and web parts. Unfortunately, this control is located in the Microsoft.SharePoint.WebControls namespace and is therefore unavailable to sandbox code. Code is the operative word – you can still use it on pages as long as it is in the page markup and not in a control. You can specify multiple permissions by separating the values with commas.

The documentation for this control is good and there are plenty of posts out there the describe its full functionality. The SDK article is here.

CustomAction Rights

The CustomAction feature element allows you to add items to most menus and also to the ribbon. It exposes a Rights attribute that specifies a set of rights that the user must have for the link to be visible, for example, "ViewListItems,ManageAlerts". Simillar functionality is exposed by the SPUserCustomAction class. It has a Rights property that accepts a permissions mask.

Author: Doug Ware