Sunday, August 14, 2011

Extending the SharePoint Security Trimmed Control to support SharePoint Groups

We all know that (SPSecurityTrimmedControl) SharePoint Security Trimmed Control comes to our rescue when we need to show role/permission based data in SharePoint. It helps you Conditionally renders the contents of the control to the current user only if the current user has permissions defined in the PermissionString.

<Sharepoint:SPSecurityTrimmedControl runat=”server” Permissions=”ManageLists”>
      Place your control(s) here
</SharePoint:SPSecurityTrimmedControl>

All this is good and works fine for most of the scenarios, however you may seldom find a need to be able to add a “SharePoint Group” instead of a “PermissionString”

So, let’s tell you how…

The idea is to create your wrapper control to support this feature. Let’s get started

Create a custom Web Control and write down the required logic based on your requirements. This should inherit from SPSecurityTrimmedControl

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.WebControls;
using System.Web.UI;
using System.Web;
using Microsoft.SharePoint;

namespace SPSecurityTrimmedControlExtender
{
public class SPUserGroupTrimmedControl : SPSecurityTrimmedControl
{
private List groups = new List();

public string GroupsString
{
get
{
return string.Join(",", groups.ToArray());
}
set
{
groups.AddRange(
value.Split(new char[] { ',' },
System.StringSplitOptions.RemoveEmptyEntries)
);
}
}

protected override void Render(HtmlTextWriter output)
{
if (!string.IsNullOrEmpty(GroupsString) && IsMember())
{
base.Render(output);
}
}

private bool IsMember()
{
using (SPWeb web = new SPSite(SPContext.Current.Web.Url).OpenWeb())
{
bool isMember = false;
foreach (string group in groups)
{
isMember = web.IsCurrentUserMemberOfGroup(web.Groups[group].ID);
}
return isMember;
}
}
}
}

Now, put this assembly in GAC and add a safe control entry in the web.config of you web application.



You are now ready to use this in your web page or master page by registering it.

<%@ Register TagPrefix="MyUserGroupExtender" Assembly="SPSecurityTrimmedControlExtender, Version=1.0.0.0, Culture=neutral, PublicKeyToken=121fae78165ba3d4" %>

//your control to show to the specified group only


And you are done!!!

11 comments:

  1. If I could buy you a beer I would! Awesome assembly - I was able to get this to work in my environment and it has now opened up more capabilities for our security. THANK YOU!!! :D

    Curious, ever think of taking it one more notch ahead and seeing if multiple groups can be used within the "groupsstring" attribute, just like how the built-in SPSecurityTrimmedControl works?

    Thanks,
    -Eric

    ReplyDelete
  2. Thanks Eric for the gesture :-) I am glad it helped you

    Definitely, would do that and update the code, good point though

    ReplyDelete
  3. Just to add, I played around with it some more and it looks like this assembly will take multiple groups, but its in the 'all' mode; meaning the user would have to be a member in all of the groups set. Cool, but I'm looking for 'any' if possible.

    Thanks,
    -Eric

    ReplyDelete
  4. Hi, thank you for your article, but the final assignment should be done with |= instead of =.
    Thank you, Damiano

    ReplyDelete
  5. Could you please explain this code if you do it in asc.x file in a class file and then as in the GAC and register it in the masterpage

    ReplyDelete
  6. thank you!
    I have been very useful your article

    ReplyDelete
  7. This is really great! Thanks.

    ReplyDelete
  8. Thanks for this. I tweaked it to check specific claims in my case.

    ReplyDelete
    Replies
    1. Could you please post your tweaked code?

      Delete
  9. Good article dude! Although your code has a leak as SPSite is not being disposed. Replace it with the code below to fix it.

    using (SPSite siteCollection = new SPSite(SPContext.Current.Web.Url))
    using (SPWeb web = siteCollection.OpenWeb())
    {
    // Perform operations on site.
    } // SPWeb object web.Dispose() automatically called; SPSite object
    // siteCollection.Dispose() automatically called.

    ReplyDelete

Thumbs Up?