SPWeb.Groups vs SPWeb.AssociatedGroups - c#

I've seen three types of group properties for an SPWeb object - Groups, SiteGroups, AssociatedGroups.
I understand that SiteGroups will fetch all the groups in the current site collection. But what is the difference between Groups and AssociatedGroups. MSDN definition says that Groups will get all the 'cross-site'(!) groups for that web site. AssociatedGroups are fairly easily to understand just from the very name.
So what does Groups return? Can somebody explain me with an example?

Groups return all groups which have security roles assigned to the current site.
AssociatedGroups return all groups visible in the left menu of the People and Group page. Those groups may not have access to the current site (if the security settings do not inherit from parent site). In this case, some of them will not be listed in the Groups property.
To view the difference, in a subsite, create a new group without giving any permission. The group will be visible in the AssociatedGroups and Left menu, but will not be listed in Groups or Site Permissions page.

I believe msdn has the answer
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.sitegroups.aspx
Gets a collection that contains all the groups in the site collection.
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.groups.aspx
Gets a collection that contains all the groups for the website. The following code example uses the Groups property to return the collection of groups for a specified site in the current site collection.
Which means, the SPGroup has been used in (ie assigned a permission in) the SPWeb somewhere.

Related

GetAuthorizationGroups() wrongly assumes I´m an domain administrator

I have a domain group name and have to check if a domain user is part of it recursively. After getting my users domain prinical I try to get through all authorization groups
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
UserPrincipal userPrin = UserPrincipal.FindByIdentity(ctx, userToCheck);
if (userPrin != null)
{
foreach (GroupPrincipal group in userPrin.GetAuthorizationGroups())
{
if (group.Name.Equals(groupName, System.StringComparison.OrdinalIgnoreCase))
{
if (group.Context.Name.StartsWith(domain, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
}
}
}
[I know, the startsWith might not be the best way but everything work like a a charm]
Only problem: I have two accounts that are both NOT part of the builtin administrators group of the domain. Both user principals are found and the groups are enumerated but:
For one user the result is FALSE when checking builtin administrators group
For one user the result is TRUE when checking builtin administrators group
I know that the group checked is indeed the correct domain object for both tries.
Why does it say the one account is in that group?
UPDATE
When searching via cmd (net user /domain) the group does NOT show up.
When running the code from another machine (same user is queries) the group does also not show up.
But if you query the current user that is logged in as an administrator this user is considered to be in the group
CN=Administratoren,CN=Builtin,DC=domain,DC=de
which is just wrong. He might be in the local group but definetly NOT in the domain administrators group.
The SID of the group is S-1-5-32-544 btw.
UPDATE2
Since PrincipalContext internally uses the DirectorySearcher I tried to have a solution with the directory searcher. It returns only the correct groups. (although I´m not sure right now if it has a function für recursive group search like Principle context has)
So either this is a bug or has something to do with the additional groups like dlatikay pointed out
This method searches all groups recursively and returns the groups in which the user is a member. The returned set may also include additional groups that system would consider the user a member of for authorization purposes.
The groups that are returned by this method may include groups from a different scope and store than the principal. For example, if the principal is an AD DS object that has a DN of "CN=SpecialGroups,DC=Fabrikam,DC=com, the returned set can contain groups that belong to the "CN=NormalGroups,DC=Fabrikam,DC=com.
But why does it return additional groups, I have to make sure the user really is privileged in the groups returned.

Nested Active Directory Groups in a Group

I have a need to find all the nested groups in a particular group 1 layer down. The problem I have is the code below usually works, but for some groups it does not.
If I use Windows Explorer to search for a particular group (click on the Network icon, then click on 'Search Active Directory', I can see the members and nested groups within the parent group. But through code using System.DirectoryServices.AccountManagement on 3.5 Framework, var Groups = MyGroup.GetGroups(); can't see the nested groups of some groups. I thought it was a permissions thing, but if i can see inside the group from my own manual search mentioned above, then I assume the code running from the same account should be able to see the same thing too. Is there something different I should try?
For what its worth, I'm using a script task on top of Framework 3.5 inside of a SSIS package. Also in the same package, searching for groups from a user principle object instead of a group principle works fine.
And for clarity, when I run this code
PrincipalContext AD = new PrincipalContext(ContextType.Domain, "ctx", "mypath");
GroupPrincipal myGroup = GroupPrincipal.FindByIdentity(AD, "myparentgroup");
var nestedgroups = myGroup.GetGroups();
"Nestedgroups" is null when it should contain my nested groups.
The problem I had was I used var Groups = MyGroup.GetGroups(); when I should have used var Groups = MyGroup.GetMembers();. Putting that behind a link statement allowed me to get all the objects I was looking for because .GetMembers() includes users and groups. Hope that helps.

Load list of Users in two Azure Active Directory Groups using Graph API

I am extremely new to Active Directory and to Azure, as will likely be obvious from my question. I am using the MVC Directory Graph Sample as a reference. I am able to do most of the things that I am attempting but I ran into a problem:
I have a hierarchy of Groups and Users in Azure Active Directory where I have two levels of groups (e.g. GroupA contains GroupB and GroupC, GroupD contains GroupE...). Users can be in, theoretically, any combination of these groups (e.g. GroupA, GroupD and GroupE).
I pass two strings to my MVC project controller where each string is the ID of a Group in my Azure Active Directory. I want to load only the User objects that overlap in the two Groups, i.e. only the Users that are in both groups.
Following along with one of the example projects from MSDN, I am able to load a list of all of the users in one of the Groups like so:
Group groupA = DirectoryService.groups.Where(it => (it.objectId == GroupAId)).SingleOrDefault();
DirectoryService.LoadProperty(groupA , "members");
List<User> usersListA = groupA.members.OfType<User>().ToList();
Duplicating this for the second list, I can then intersect the two:
Group groupB = DirectoryService.groups.Where(it => (it.objectId == GroupBId)).SingleOrDefault();
DirectoryService.LoadProperty(groupB , "members");
List<User> usersListB = groupA.members.OfType<User>().ToList();
List<User> finalList = usersListA.Intersect(usersListB);
Basically, I'm loading both lists fully... my question is - is there a better way to do this?
For example, after I've loaded the list of Users from GroupA, is there a way for me to filter the list to include only those who belong to GroupB? Something along the lines of:
//<Incorrect syntax>
List<User> finalList = groupA.Where(user => user.memberOf("GroupB"));
//</Incorrect syntax>
No, there is currently no way to do this server-side, if that's what you are looking for.

c# LDAP membership enumeration

here is my problem: I need to enumerate the members of certain groups in our Active Directory. The complication is that the DN of the objects that are in the 'membersOf' property of the groups do not contain the identifier I need. Specifically, the CN of the user object is useless to me, only a property of the user object (the userID) is useful.
So three approaches comes to mind:
I can first enumerate the group to get a list of DN's in the group, and then do a lookup on each user DN to find out their userID
I can enumerate every user in the AD, grabbing their userID & their membersOf collection, and then check afterwards if they have the right memberships.
I could grab a list of all users with their CN's and userID's, and then enumerate the groups to get the member CN's. Then I could join the lists on the original list to get my list of member userID's.
Some problems immediately appear - option 1) will generate an extremely large number of subqueries and congest network traffic (undesirable), and option 2) pulls a HUGE amount of data from AD (something like 30mb). Option 3) is middle of the road - but it still pulls quite a bit of data and has multiple queries. Is there another option for how to do this which does not have these problems?
I am doing this in c# using the System.DirectoryServices tools.
Thank you in advance for your time and consideration.
Maybe there's an option #4, too:
you could set up a DirectorySearcher which enumerates users
you could define memberOf=....... as one of your search criteria
you can define what attributes you need from the directory searcher very easily
If this works (and I'm under the impression I got this to work before - but it's been quite a while!) then you could do one, single fairly focused search and automatically get your information that you need.
Try something like this:
// define the "root" of your search (where to begin)
DirectoryEntry searchRoot = new DirectoryEntry("LDAP://cn=users,dc=yourcompany,dc=com");
DirectorySearcher searcher = new DirectorySearcher(searchRoot);
// set properties
searcher.SearchScope = SearchScope.Subtree;
// define search filter
searcher.Filter = "(&(objectCategory=Person)(memberof=CN=YourGroup,OU=Users,DC=YourDomain,DC=com))";
// define attributes to load
searcher.PropertiesToLoad.Add("userid");
... add more if needed .....
foreach(SearchResult entry in searcher.FindAll())
{
string userid = entry.Properties["userid"][0].ToString();
}

get users by group in sharepoint

can anyone show me how to get the users within a certain group using sharepoint?
so i have a list that contains users and or groups. i want to retrieve all users in that list. is there a way to differentiate between whether the list item is a group or user. if its a group, i need to get all the users within that group.
im using c#, and im trying to do thins by making it a console application.
im new to sharepoint and im really jumping into the deep end of the pool here, any help would be highly appreciated.
cheers..
The first thing you need to know is that when you have a list with a User / Group field you must be aware of its type. When you have one user or group within the item value, the field type is SPFieldUserValue. However, if the field has multiple user / group selection the field type is SPFieldUserValueCollection.
I'll assume that your field allows a single user / group selection and you already has the following objects:
SPSite site;
SPWeb web;
SPListItem item;
Now, we'll check the field value for a user / group and retrieve a list of users, independant of which kind it is (the field's name is "Users").
SPFieldUserValue usersField = new SPFieldUserValue(mainWeb, item["Users"].ToString());
bool isUser = SPUtility.IsLoginValid(site, usersField.User.LoginName);
List<SPUser> users = new List<SPUser>();
if (isUser)
{
// add a single user to the list
users.Add(usersField.User);
}
else
{
SPGroup group = web.Groups.GetByID(usersField.LookupId);
foreach (SPUser user in group.Users)
{
// add all the group users to the list
users.Add(user.User);
}
}
I hope it helps you.
Tks,
Pedro José Batista
note: an SPUser object can also be an AD Group (that is to say, an SPUser object might exist for "DOMAIN\Domain Users"... which is why the SPUser object also contains the property IsDomainGroup.
From this information you can start to traverse through AD groups using the SPPrincipalInfo objects... however it's not always pleasant.
One thing worth keeping in mind is that the SPGroup object includes the ContainsCurrentUser property which can traverse AD groups... this assumes you've got an SPGroup object to work from, however.
Enjoy.
-Scott
private bool IsMember()
{
bool isMember;
SPSite site = new SPSite(SiteURL);
SPWeb web = site.OpenWeb();
isMember = web.IsCurrentUserMemberOfGroup(web.Groups["GroupName"].ID);
web.Close();
site.Close();
return isMember;
}
This is better to use web.SiteGroups instead of web.Groups as a group might be inherited by that site.

Categories

Resources