Saturday, July 17, 2010

Handle Active Directory Users in SharePoint

I had a situation in my project where I have to read active directory users from an active directory group placed inside a SharePoint group. I got this article from code project to implement the same.

http://www.codeproject.com/KB/sharepoint/Sharepoint__User.aspx

Above article checks if the user exists in active directory. I have modified the above method to read users from an active directory group placed inside a SharePoint group.

public DataTable getUsersListFromSPGroup(SPWeb currentWeb, string groupName)
{
bool reachedMax = false;
DataTable dtUsers = new DataTable();
dtUsers.Columns.Add("UserName");
dtUsers.Columns.Add("LoginName");

// The Run with elevated privileges needs read permission
// on active directory and the ability to run directory code.
// We are using RunWithElevatedPrivileges instead of impersonation since we have to access Active Directory
SPSecurity.RunWithElevatedPrivileges(delegate
{
// Get the Site Collection
using (SPSite site = new SPSite(currentWeb.Site.ID))
{
// Get the web
using (SPWeb web = site.OpenWeb())
{
// Find the group
SPGroup group = site.RootWeb.SiteGroups[groupName];

// Get ad users in the groups. Since MOSS does not support nested groups
// this will always be a collection of AD users and groups
foreach (SPUser user in group.Users)
{
// Check if this is a Group
if (!user.IsDomainGroup)
{
if (user.Name.ToUpper() != "SYSTEM ACCOUNT")
{
DataRow userRow = dtUsers.NewRow();
userRow["UserName"] = user.Name;
userRow["LoginName"] = user.LoginName;
dtUsers.Rows.Add(userRow);
}
}
else
{
// If the AD entitiy is a User Group, then check for users in that group
// SPUtility call to get principals in the group
SPPrincipalInfo[] principals = SPUtility.GetPrincipalsInGroup(web, user.LoginName, 500, out reachedMax);
// If no principals found then indicate the same
if (principals != null && principals.Length != 0)
{
// Loop through principals
foreach (SPPrincipalInfo principal in principals)
{
//TODO: Determine which principal.PrincipalType to ignore
// Check if the principal is a valid user and if so check to see if it is
//the one we are looking for
//SPPrincipalType is USER and ignoring All, DistributionList, None, SecurityGroup, SharePointGroup
if (!principal.IsSharePointGroup && principal.PrincipalType == SPPrincipalType.User && principal.DisplayName.ToUpper() != "SYSTEM ACCOUNT")
{
DataRow userRow = dtUsers.NewRow();
userRow["UserName"] = principal.DisplayName;
userRow["LoginName"] = principal.LoginName;
dtUsers.Rows.Add(userRow);
}

}
}

}
}
}
}

});
return dtUsers;
}


And this from the above article.
public bool IsUserInSharePointGroup(SPWeb currentWeb, string groupName, string username)
{
bool reachedMax = false;
bool userIsInGroup = false;
// return false if there are invalid inputs
if (String.IsNullOrEmpty(username) String.IsNullOrEmpty(groupName))
return false;
// The Run with elevated privileges needs read permission
// on active directory and the ability to run directory code.
SPSecurity.RunWithElevatedPrivileges(delegate
{
try
{
// Get the Site Collection
using (SPSite site = new SPSite(currentWeb.Site.ID))
{
// Get the web
using (SPWeb web = site.OpenWeb())
{
// Find the group
SPGroup group = site.RootWeb.SiteGroups[groupName];
string upperCaseUserName = username.ToUpper();
// Get ad users in the groups. Since MOSS does not support nested groups
// this will always be a collection of AD users and groups
foreach (SPUser user in group.Users)
{
// Check if this is a Group
if (!user.IsDomainGroup)
{
// Verify if the user name matches the user name in group
if (user.LoginName.ToUpper().Equals(upperCaseUserName))
{
// if a match is confirmed, return from the method.
// There is no need to continue
userIsInGroup = true;
break;
}
}
else
{
// If the AD entitiy is a User Group, then check for users in that group
if (IsUserInADGroup(web, user.LoginName, username, out reachedMax))
{
userIsInGroup = true;
break;
}
}
}
}
}
}
catch (Exception ex)
{
//Trace error
}
});
return userIsInGroup;
}

private static bool IsUserInADGroup(SPWeb web, string groupName, string username, out bool reachedMax)
{
// SPUtility call to get principals in the group
SPPrincipalInfo[] principals = SPUtility.GetPrincipalsInGroup(web, groupName, 500, out reachedMax);
// If no principals found then indicate the same
if (principals == null principals.Length == 0)
{
return false;
}
else
{
// Loop through principals
string upperCaseUserName = username.ToUpper();
foreach (SPPrincipalInfo principal in principals)
{
//TODO: Determine which principal.PrincipalType to ignore
// Check if the principal is a valid user
// and if so check to see if it is
//the one we are looking for
if (!principal.IsSharePointGroup && principal.PrincipalType
!= SPPrincipalType.SecurityGroup &&
principal.DisplayName.ToUpper() != "SYSTEM ACCOUNT")
{
// Check if the user matches the user we are looking for
if (principal.LoginName.ToUpper() == upperCaseUserName)
{
return true;
}
}
// If Principal is a Security Group (AD Group) then recurse through it
else if (principal.PrincipalType == SPPrincipalType.SecurityGroup)
{
// Check for users in the security groups
if (IsUserInADGroup(web, principal.LoginName, username, out reachedMax))
{
return true;
}
}
}
return false;
}
}