How to get All Users in the organization with their member Groups using MS Graph in a single request - azure-active-directory

Is there a way to retrieve Users in an organization including Groups that each User is a member of, in a single call to Microsoft Graph?
Something like https://graph.microsoft.com/v1.0/users?$expand=MemberOf
This call does not return the Member groups. If I call the beta endpoint with same URL though I get the member groups in the response. the problem with the beta end point is that it returns a big response and I could not find a way to combine $expand with $select to only return the MemberOf property for each User and User's id field.

This call does not return the Member groups. If I call the beta
endpoint with same URL though I get the member groups in the response.
the problem with the beta end point is that it returns a big response
and I could not find a way to combine $expand with $select to only
return the MemberOf property for each User and User's id field.
Not all relationships and resources support the $expand query parameter, $expand is only supported for beta and typically returns a maximum of 20 items for the expanded relationship. And not all resources or relationships support using $select on expanded items, I also tried https://graph.microsoft.com/beta/users?$expand=memberOf($select=id,name) in beta, the error prompts valid for this. For the details, please read here.

According to the introduction of this document, "with Azure AD resources that derive from directory Object, like user and group, $expand is only supported for beta and typically returns a maximum of 20 items for the expanded relationship".
Base on my test, you can use this API below to list out all the memberof.
'GET /users/{id | userPrincipalName}/memberOf
So there is no way to retrieve Users in an organization including Groups that each User is a memberof by using a single call to Microsoft Graph.

As other has mentioned, it's not possible with a single request.
For retrieving all users of our organization, and the groups they are members of, I resolved to this
Fetch all groups (https://graph.microsoft.com/v1.0/groups/)
For each group, fetch all members (https://graph.microsoft.com/v1.0/groups/[groupId]/members)
In memory flatten the groups (a group can have another group as a member), so that groups only has users as members, and includes any member groups users.
This produced a list of groups, each with a list of all users that are directly or indirectly (user could be a member of a group that the original group has as a member). Should be relatively easy to convert it to a list of users each with a list of groups they are members of, if that is what you need.

Related

AD Ldap query for user nested groups by sAMAccountName

I'm trying to make a query that outputs all the groups (and nested groups) that a user is part off, queried for by sAMAccountName value.
For example, the following query works and gives the expected output but uses the displayname instead.
(&(objectCategory=group)(member:1.2.840.113556.1.4.1941:=cn=Tester,ou=people,dc=Windomain,dc=local))
Simply changing "cn" to "sAMAccountName" doesn't work (I did verify that the sAMAccountName value is correct)
Is it possible to do this with LDAP queries?
There are a couple of options to display the complete group membership of a user, including all nested groups.
The simplest method is to query the TokenGroups attribute of the user object. This is a constructed attribute, that will return all the SIDs of the groups that will be added to the user's access token when the user authenticates. The only condition for the constructed attribute, the search scope must be Base scope for the attribute to be returned.
The LDAP_MATCHING_RULE_IN_CHAIN (1.2.840.113556.1.4.1941) matching rule is limited in its functionality, it will only return the groups that the user's DN has been added to the member attribute of the group, so some nested groups will not be included in the query.
The other option is to use a 3rd party tool to return the nested groups by transverse the groups membership to see the group membership. Such as NetTools User's membership option https://nettools.net/users-membership and the NetTools AD Properties dialog which includes the TokenGroups tab which will display the TokenGroups attribute with the SIDs resolved.
You can search for the user by the sAMAccountName and ask for the msds-memberOfTransitive attribute, which contains a recursive list of the distinguished names of the groups the user is a member of.
There is also the msds-tokenGroupNames attribute, which contains the distinguished names of all the groups whose SIDs appear in the tokenGroups attribute.
The difference is that tokenGroups only includes security groups, whereas memberOf includes distribution lists as well. Only security groups can be used to assign permissions.
Both are constructed attributes, so you have to specifically put it in the list of attributes to return in the search.
Sorry unable to add comments
Be careful of the msds-memberoftransitive attribute, it has some funky logic which doesn't follow the normal value ranging rules and can return incomplete results, see https://blog.joeware.net/2021/04/19/6068/

LDAP users nested group membership in websphere

IBM state that:
nested
Nested means that the response from the LDAP server to a
request for the group membership attribute already includes any nested
group relationships, but not any dynamic group memberships. If the
user is a member of group "A2" and "A2" is a member of group "A1",
then the list of group memberships includes both A1 and A2. This
information tells VMM that even if a client requests nested group
information, the response already provides it. No further work needs
to be done by VMM to satisfy the request.
How can I achieve this in websphere (connecting to Active Directory), so that if a user is a member of A2, and A2 is a member of group A1, I want the user to be in both A1 and A2.
I have nested groups enabled in the group attribute definition, however when I browse for the users, it only shows them belonging to group A2
The configuration helps VMM only to know what is expected in the attribute returned from the LDAP server. VMM performs a fast lookup of the membership by using an attribute provided by the LDAP containing the membership. The config element where you can define if it is nested, all or direct only helps VMM to have a hint if it needs to perform further actions.
All depends on the values returned from LDAP. In your case Active Directory. Usually it would be memberOf and from https://msdn.microsoft.com/en-us/library/ms677943%28v=vs.85%29.aspx
memberOf
The memberOf attribute is a multi-valued attribute that contains groups of which the user is a direct member, except for the primary
group, which is represented by the primaryGroupId. Group membership is
dependent on the domain controller (DC) from which this attribute is
retrieved:
At a DC for the domain that contains the user, memberOf for the user is complete with respect to membership for groups in that
domain; however, memberOf does not contain the user's membership in
domain local and global groups in other domains.
At a GC server, memberOf for the user is complete with respect to all universal group memberships.
If both conditions are true for the DC, both sets of data are contained in memberOf.
Be aware that this attribute lists the groups that contain the user in their member attribute—it does not contain the recursive list
of nested predecessors. For example, if user O is a member of group C
and group B and group B were nested in group A, the memberOf attribute
of user O would list group C and group B, but not group A.
This attribute is not stored—it is a computed back-link attribute.
memberOf includes only the direct members. In combination with the configuration you have done VMM will only check the values inside of memberOf and does not perform any additional LDAP call.
Now I have too many options. Do you want to have the nested Groups for J2EE roles or within your application as you are calling VMM direct using API or or. I do not want to speculate to I leave it with the statement
memberOf returns the flat membership aka direct membership and VMM needs to perform additional calls to get the full info. By setting nested VMM will not perform any additional call
You need to switch from nested to direct, to tell VMM to perform additional searches, since AD returns only direct members. See Locating user group memberships in a Lightweight Directory Access Protocol registry for more details.

Correct way to filter out built in AD SecurityGroups

I have a LDAP searchquery where i am using the following filter
"(&(objectClass=user)(objectCategory=person))"
and running against AD in order to get User-accounts out. One of the attributes being returned ("memberOf") holds a ";" separated string of groups that user is a member of.
i.e.
CN=MyGroup,OU=MyMainOU,DC=masterdom,DC=local;
CN=Administrators,CN=Builtin,DC=masterdom,DC=local
I want to filter out the BuiltIn security groups, when processing the list can I rely on the "built in" groups containing the string "cn=builtin"? Or could it change with local etc. If so what is the correct method?
You if want to utilize the memberOf attribute, you can include it in your filter by using the full container name :
(&(objectClass=user)(objectCategory=person)(memberof=CN=Builtin,DC=masterdom,DC=local))
Something to keep in mind though, is that the memberOf attribute will only show groups native to the domain component (DC) in which the user is derived from - by that I mean, if user A is part of both the Developers and Management groups, but the Developers group doesn't exist within the current domain component you're querying, then the memberOf attribute will only show the Management group for the user when queried.
Plus, the memberOf attribute is a computed back-link attribute or a constructed attribute. It's maintained and calculated by Active Directory, so as you move users and groups around, that value will automatically change for the user.
However, judging by your post, if you're just iterating through a list of users and checking the memberOf attributes for the existence of CN=Builtin (ex. a .Contains check), then yes, you can rely on that string being there, given it's part of the DC you're querying.

Generic ldap nested group implementation

I need to implement nested group membership for generic AD services.
Previously, i was using a specific search-filter ("member:1.2.840.113556.1.4.1941:=") through which using a single search request, i was able to get hold of all group membership through which that user was part of. However, it looks like that search-filter seems to work only for MS AD servers and not for generic AD servers.
So, is anybody aware of any specific search filter which we can send in a search request (applicable to All AD servers), through which i can derive nested group membership via a single search query.
Thanks in advance for your help on this.
"member:1.2.840.113556.1.4.1941" is LDAP_MATCHING_RULE_IN_CHAIN and might very well not be implemented by other LDAP vendors. LDAP Wiki
Edit:
You could do something like this if you want to reurse the groups:
Use the filter:
(&(objectCategory=organizationalPerson)(objectClass=User)(sAMAccountName=YOURUSER)
get "distinguishedName" (this is the user's distinguishedName)
get "memberOf" (this is a collection of distinguishedNames of the groups the user is a member of (minus the primary group in MS Active Directory, which should be "Domain Users"))
Foreach memberOf in the collection: (This is the first level, so there is no need to check if he is there, because he is.)
(&(objectCategory=group)(distinguishedName=THISMEMBEROF))
get "member" (this is a collection of distinguishedNames of group members)
Foreach memberOf in the collection:
This is the second level (the groups within the groups), so first check if the users distinguishedName is present.
(&(objectCategory=group)(distinguishedName=THISMEMBEROF))
get "member" (this is a collection of distinguishedNames of group members)
Foreach memberOf in the collection:
This is the third level (the groups within the groups), so first check if the users distinguishedName is present.
(&(objectCategory=group)(distinguishedName=THISMEMBEROF))
get "member" (this is a collection of distinguishedNames of group members)
etc.

Active Directory memberof property doesn't contain nested security groups

An AD setup I'm using has users that are stored as members of (multiple) security groups.
I am using software that reads the memberof property of a user to work out access permissions.
In AD Explorer I can see the memberof property of the user shows the immediate security groups they belong to say 'Course - English'. It does not show the parents groups, nested up to say 'ALL Students'.
Is there a reason for this or a way of ensuring all nested groups are shown in the memberof property?
If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
var groups = user.GetAuthorizationGroups();
// enumerate over groups
foreach(GroupPrincipal gp in groups)
{
// do something here....
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!
The .GetAuthorizationGroups() method is the only one around that I know of that will do recursive searches, e.g. find groups that a user is member of by virtue of another group. The pre-.NET 3.5 DirectoryServices stuff doesn't do this - you would have to totally roll your own if you need that.
The probable reason that the memberOf attribute does not contain all the nested group information is that the value is computed when the attribute is loaded, as noted in this link:
Be aware that this attribute lists the groups that contain the user in their member attribute—it does not contain the recursive list of nested predecessors. For example, if user O is a member of group C and group B and group B were nested in group A, the memberOf attribute of user O would list group C and group B, but not group A.
This attribute is not stored—it is a computed back-link attribute.
Hence, to support this, your DC would be forced to load all nested groups every time a LDAP query returned the memberOf attribute, which could be a lot of excess work.
Depending on the technology you are using, there are almost certainly better ways to check group membership than loading all groups and listing them all. For example, ADSI has a pre-built function to check if a user is a member of the group.
However, for a pure LDAP solution, you could use the LDAP_MATCHING_RULE_IN_CHAIN as shown in this answer (assuming you have the DN for the user), e.g.,
(member:1.2.840.113556.1.4.1941:=CN=Administrator,OU=Users,DC=fabrikam,DC=com)
Which will get all the groups which Administrator is a member of. Note, however, that this query can be extremely slow. To speed up performance, consider paging results or restricting the search base to only the group you are interested in checking.

Resources