Getting All SharePoint Group Membership for a User Using JavaScript

As everyone knows by now, Microsoft is pushing all development out to the client-side. But most of the time, I find customers who desire customization want a user experience that is somewhat tailored to the current user. Like managers should see one thing when they log in, but regular users should see something else. That means that on the client-side, I need to be able to distinguish managers from other users. That’s normally done by assigning the users to groups. But in large organizations, that usually means Active Directory groups, which are then added to SharePoint groups. This leads to a problem, because from the client-side, there is no way to determine if the user has membership in a SharePoint group to which they’ve been added indirectly (i.e. through membership in an Active Directory group).

To demonstrate, I have a SharePoint site, and it has the following site group membership:


Site Group Membership

I’m only directly in the owners group, but I have membership in the Active Directory security groups Managers and HumanResources. So I’m indirectly in the members and visitors groups too.

If I go to Site Settings -> Site Permissions, click on Check Permissions, enter my user name, and click the Check Now button, I get the following dialog:


Check Permissions

The result is as I would expect. It shows that I have Full Control, Edit, and Read through the owners, members and visitors groups respectively.

Now I run the following JavaScript, which is just a bit of jQuery to call the web service to get all groups to which the current user belongs.

The JSON response is:

Huh…that kind of sucks. It only shows me in the owners group. And the results are the same no matter what method I use to try to determine my SharePoint groups from the client side. ASMX and/or CSOM/JSOM both also only show me in the owners group. The reason is that all of these methods only return groups to which the user has been added directly. Any group that I’m in only through membership in an Active Directory security group does not come back.

This has also been the case in all versions of SharePoint that have any kind of API to access this stuff client-side (i.e. from SharePoint 2007 all the way up to SharePoint Online).

The only way around this is to write some server-side code. Specifically, I’m going to write a quick and dirty web service to give me all SharePoint groups for the current user (direct or indirect). To do that, I’m going to use the .Net classes PrincipalContext and UserPrincipal, both of which are in the System.DirectoryServices.AccountManagement namespace, so I need to add the following assembly reference to my web.config (really the web.config for each web application from which I want to be able to call this):

With that done, I can now write my web service, and here it is:

For simplicity sake, I’ve done the entire service in a single file with no code behind, so it can just be dropped into the layouts directory and you can start using it. In any real world situation, it should really be compiled into a DLL and deployed as a WSP.

The code is actually pretty simple. At it’s heart, I use the PrindipalContext to get the current user as a UserPrincipal. I then call UserPrincipal.GetAuthorizationGroups(), which returns an expanded list of all groups to which the principal is a member (i.e. it expands out nested groups). Finally, I loop through all of the
SharePoint groups and check if the user, or one of the user’s AD groups, is a member of each SharePoint group.

Note that the classes PrincipalContext and UserPrincipal were introduced in .Net 4.0, which means this solution only works for SharePoint 2013 and beyond (and not counting Online of course, since you can’t deploy server side code in that environment).

Also note that I’m performing these operations at elevated privileges. This isn’t that big of an issue, since the only functionality I expose through this web service is that the user can get a complete list of their own SharePoint groups (or Active Directory groups), and there isn’t any security issue with that. If I wanted to change the interface such that it takes in the user name as a parameter (i.e. it could be used to retrieve groups for users other than the current user), that would be a different story. In that case, I would remove the elevated privileges, resulting in only privileged users being able to call the method successfully.

Once it’s in the layouts directory, just call it like so:

And the JSON response is:

And that’s more like it. It wasn’t that hard. Kind of makes you wonder why Microsoft hasn’t done it sometime in the last 12 years. The OOB groups web services are really pretty useless as they are.

Just remember that the limitations are that it only works on 2013 and later, but not in SharePoint Online. It can be done on older versions of SharePoint too, but probably only by calling Active Directory multiple times to expand out groups (possibly many times). And maybe it could be done in SharePoint Online using something like an Azure function, but if so, that’s a different blog post.

Reference

Leave a Comment