Inconvenient SPSecurityTrimmedControl


While working recently with the SPSecurityTrimmedControl I have found that it doesn’t work as most of us would expect it to. The usage of the AuthenticationRestrictions and PageModes attributes took my attention in particular.

The SPSecurityTrimmedControl shipped with WSSv3 is a very powerful control. It basically allows you to conditionally display content depending on the user’s permission. Personally I think that the most common usage of the SPSecurityTrimmedControl is hiding the Site Actions menu and the Publishing Console from anonymous users:

<SharePoint:SPSecurityTrimmedControl ID="SPSecurityTrimmedControl1"
  PermissionsString="BrowseDirectories" runat="server">
    <PublishingSiteAction:SiteActionMenu runat="server" />
    <wssuc:Welcome id="explitLogout" runat="server" />
    <PublishingWebControls:AuthoringContainer ID="authoringcontrols"
    runat="server">
        <PublishingConsole:Console runat="server" />
    </PublishingWebControls:AuthoringContainer>
</SharePoint:SPSecurityTrimmedControl>

But using the permissions is not the only way to conditionally display content using the SPSecurityTrimmedControl. Looking at the WSSv3 SDK you will discover a few more attributes. I want to focus on the two I have just mentioned: AuthenticationRestrictions and PageModes.

It doesn’t take much to figure out that the AuthenticationRestrictions attribute allows you to determine whether the output should be accessible by All, Authenticated or Anonymous users only. Unfortunately, the given value doesn’t seem to affect the control in any logic way. This problems has been posted on MSDN SharePoint Forums not that long ago. Trying to figure out what is the reason of that problem, I have discovered that the SPSecurityTrimmedControl uses a simple check to determine whether the current user should see the output based on the AuthenticationRestrictions:

if ((authenticationRestrictions !=
    AuthenticationRestrictions.AllUsers) &&
    ((CurrentAuthenticationRestriction &
    authenticationRestrictions) == 0))
{
    
}

Unfortunately this check is based on a constant value (CurrentAuthenticationRestriction) which returns the AuthenticationRestrictions.AuthenticatedUsersOnly value. By doing this the check returns true only if you have defined the AuthentiactionRestrictions attribute either as AllUsers or AuthenticatedUsersOnly.

A similar situation has to do with the PageModes attribute. Based on the value type (Microsoft.SharePoint.Utilities.PageModes) I have figured out that the SPSecurityTrimmedControl allows you to distinguish whether you would like to display some content in Design or Normal (Display) mode only. Unfortunately while checking the current page mode the SPSecurityTrimmedControl uses a constant value of PagesMode.Normal. By doing that it makes the PageModes attribute unusable.

And now?

As I needed the functionality described above, I have decided to create my own wrapper: ImtechSecurityTrimmedControl (for those who are interested in creating their own wrapper controls: I have recently written an article on how to create custom wrapper controls). To avoid redundancy I have decided to implement the missing functionality only and keep using the SPSecurityTrimmedControl whenever possible.

First of all I have covered the AuthenticationRestrictions functionality. To achieve the desired result I have used a really simple comparison. If the user is an authenticated user, you can retrieve the object representing that particular user by using SPContext.Current.Web.CurrentUser. But if the user is anonymous the SPWeb.CurrentUser property returns null.

Then I implemented the PageModes functionality. The original PageModes functionality, as introduced by the SPSecurityTrimmedControl, uses the PageModes enumeration. As far as I know however, there is no way to retrieve the current page mode based on that particular enumeration. That is why I decided to use the Microsoft.SharePoint.WebControls.SPControlMode enumeration instead. Some time ago already Sezai has written a short article about using the FormContext Property to determine the current mode of the ASP.NET form. By comparing the value of SPContext.Current.FormContext.FormMode property with the value passed by the FormMode attribute of the ImtechSecurityTrimmedControl I was able to determine whether the output should be rendered.

Summary

SPSecurityTrimmedControl is a very powerful control which allows you to conditionally display content on Master Pages, Page Layouts and Application Pages. By using it you will keep your pages compact and their HTML output clean. Although SPSecurityTrimmedControls successfully covers the most common usage scenarios, it has some shortcomings when it comes to rendering the output based on authentication and page mode. Creating a custom wrapper control providing that functionality is not difficult and can provide you a baseline for implementing your own rules.

Technorati Tags: SharePoint, SharePoint 2007, MOSS 2007, MOSS, WSS, WCM

Others found also helpful: