Active directory check if user belongs to a group - azure-active-directory

I am using the below code to pull active directory groups. How can I find out if a user belongs to xyz group or not?
// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// define a "query-by-example" principal - here, we search for a GroupPrincipal
GroupPrincipal qbeGroup = new GroupPrincipal(ctx);
// create your principal searcher passing in the QBE principal
PrincipalSearcher srch = new PrincipalSearcher(qbeGroup);
// find all matches
foreach(var found in srch.FindAll())
{
// do whatever here - "found" is of type "Principal" - it could be user, group, computer.....
}

You can get the list of groups a user is a member of by querying the memberOf navigation property on the user object.
Read about it here.
https://graph.windows.net/myorganization/users/{user_id}/$links/memberOf?api-version
Note that you can remove the $links part of the query to return the whole group object, rather than the link to the object. However, for simply validating a user is a member of a certain group, you can use the links, and compare the object id of the groups that are returned to the one you are looking for.

Related

Why does "Microsoft.Graph.User.AdditionalData" property contain manager information?

Within the Microsoft.Graph.User object there is a field called "AdditionalData".
It seems this can hold many values, from telling if a record is a delta record to storing manager information.
In this instance, it holds information on a users manager.
It looks like it can hold multiple records however, so I am asking what is the best way to get data from this property, to ensure I get all values it might have.
I am also unsure why manager information is in the AdditionalData property and not in the Manager property.
Yes you are correct AdditionalData may hold multiple record,You can add additionalData to your user that can hold any information based on your customization.
you can add the multiple value to additionalData using Openxtension
Trick is to add the extensions like this
extension = new OpenTypeExtension
{
ExtensionName = AzureADExtensions.UserConstants.ExtensionName,
AdditionalData = new Dictionary<string, object>
{
{"OtherEmail", externalUser.Email},
{"OtherRole" , externalUser.Roles.FirstOrDefault()}
}
};
await _graphClient.Users[user.Id].Extensions.Request()
.AddAsync(extension);
And then retrieve them like this.
user = await _graphClient
.Users[userId]
.Request()
.GetAsync();
// Note : you should be able to expand this on original request, but fails for me.
var extensions = await _graphClient.Users[user.Id].Extensions.Request().GetAsync();
user.Extensions = extensions;
Reference : Azure AD GraphServiceClient can't set AdditionalData against User
The "Additional Data" property only holds manager info if we do a delta query, if we do a regular query, we have to use extended properties to get the manager.
We are avoiding delta query for the moment in the interests of time but might come back to it at another point.
Thanks all.

How to get “Company” and “Office” from Active Directory given a UserPrincipal object?

How to get “Company” and “Office” from Active Directory given a UserPrincipal object?
If you need to read an attribute that the UserPrincipal class does not expose, then you need to use the GetUnderlyingObject() to use the underlying DirectoryEntry object (which is what UserPrincipal uses in the background. This is one reason I don't bother using UserPrincipal at all anymore.
The AD attributes you are looking for are company and physicalDeliveryOfficeName. Assuming you have a UserPrincipal object called user, you would do it like this:
var underlyingObject = (DirectoryEntry) user.GetUnderlyingObject();
var company = underlyingObject.Properties.Contains("company") ?
(string) underlyingObject.Properties["company"].Value :
null;
var office = underlyingObject.Properties.Contains("physicalDeliveryOfficeName") ?
(string) underlyingObject.Properties["physicalDeliveryOfficeName"].Value :
null;
You use Contains to verify the attribute is in the collection. If the attribute is empty, it won't appear in the Properties collection at all.

getting Value of a field by its Name in apex salesforce

in my visualforce page i have some campaign object first user select an object then there is a multi picklist. in this picklist there is Label for all the fields user selects some fields then i have to show the value of these fields in the selected campaign object
for showing multiple picklist my apex function is
public List<SelectOption> getOptionalFields(){
Map <String, Schema.SObjectField> fieldMap= Campaign.sObjectType.getDescribe().fields.getMap();
List<SelectOption> fieldsName =new List<SelectOption>();
for(Schema.SObjectField sfield : fieldMap.Values())
{
schema.describefieldresult dfield = sfield.getDescribe();
fieldsName.add(new SelectOption(dfield.getName(),dfield.getLabel()));
}
but i have no idea how to show value for the the field
for exmple i have object instance like
Campaign c;
now i have to get value of any field whose Name is in string form.how to get corresponding value for that field.one solution is just write like
say
String fieldName;
and use multiple if
if(fieldName=='Name')
c.Name=
if(fieldName=='Id')
c.Id=
is there any other convenient method??please explain!!
You need to read about "dynamic apex". Every "concrete" sObject (like Account, Contact, custom objects) can be cast down to generic sObject (or you can use the methods directly).
Object o = c.get(fieldName);
String returnValue = String.valueOf(o);
There are some useful examples on dynamic get and set methods on Salesforce-dedicated site: https://salesforce.stackexchange.com/questions/8325/retrieving-value-using-dynamic-soql https://salesforce.stackexchange.com/questions/4193/update-a-records-using-generic-fields (second question is a bit more advanced)
You'll still need to somehow decide when to return it as String, when as number, when as date... Just experiment with it and either do some simple mapping or use describe methods to learn the actual field type...

ldap nested group membership

My user is "SPR" and it is located under dc=aaaldap,dc=com
Now the filter i am trying to send is (IDEA: TO extract all groups to which user SPR belongs to)
Filter:
(&(objectclass=*)(memberof:1.2.840.113556.1.4.1941:=cn=SPR,dc=aaaldap,dc=com))
As part of this search result, i am getting response from AD server as ldapsearchresref (which to my understanding is an indication from ldap server that it is not able to find the entry in its server and thus giving a reference to a URL of another server which might help in resolving the entry).
My doubt is why it is not able to find any entry where in i am sure entry do exists?
Also, secondly i read somewhere that LDAP search filter doesn't work with commas. Can someone help me with this?
To fond all Groups a User is a member of including Nested groupsYou need to search the groups for the member attribute:
(member:1.2.840.113556.1.4.1941:=(cn=SPR,dc=aaaldap,dc=com))
-jim
If you need to find all the groups of that user belongs to you can user PrincipalContext.
Let me show you how
PrincipalContext pr = new PrincipalContext(ContextType.Domain, "aaaldap.com", "dc=aaaldap,dc=com", username, password);
List<string> lst = new List<string>();
UserPrincipal user = UserPrincipal.FindByIdentity(pr, DomainId);
if (user != null)
{
PrincipalSearchResult<Principal> results = user.GetGroups();
foreach (Principal p in results)
{
lst.Add(p.ToString());
}
lst.OrderBy(item => item.ToString());
}
pr.Dispose();
return lst;
I guess that is what you were looking for.
Cheers
When using LDAP and querying you can sometimes get a referring URL which means the account is known, but in a different domain. This happens when I query our global catalog, so I don't anymore. :)
This works on our domain here. Note I have commas in my filter.
private static void showMemberships()
{
// instantiate the DirectoryEntry instance with the FQDN of the domain to connect to
DirectoryEntry directoryObject = new DirectoryEntry("LDAP://CHILD.DOMAIN.ORG");
// create a DirectorySearcher object and pass the DirectoryEntry instance
DirectorySearcher ds = new DirectorySearcher(directoryObject);
// set search filter using LDAP query format
// this example fetches members for a group limiting to users only (not groups)
// and where the users are not in the stale objects ou
ds.Filter = "(&(objectCategory=User)(!ou=Stale Objects)(memberOf=CN=GROUPNAME,CN=Users,DC=CHILD,DC=DOMAIN,DC=ORG))";
// perform the search using the filter and store in a SearchResultsCollection
SearchResultCollection results = ds.FindAll();
// iterate through the results and do something with the info
foreach (SearchResult current in results)
{
string userId = current.Properties["cn"][0].ToString().Trim().ToUpper();
string userDn = current.Properties["distinguishedName"][0].ToString().Trim().ToUpper();
Console.Write(userId + " (" + userDn + ")\n");
}
// set the resource instances as released
directoryObject.Close();
directoryObject.Dispose();
}

Find Group size in active directory

I have the following code. I get a directory entry for a user (strpath).
And then I get the groups where the user is listed.
How can I get the number of users in each group?
DirectoryEntry myDE = new System.DirectoryServices.DirectoryEntry(strpath);
object obGroups = myDE.Invoke("Groups");
foreach (object ob in (IEnumerable)obGroups)
{
DirectoryEntry obGpEntry = new DirectoryEntry(ob);
GroupsListBox.Items.Add(obGpEntry.Name );
}
If you're on .NET 3.5 (or can upgrade to it), there's a massively extended System.DirectoryServices.AccountManagement namespace that makes these jobs of managing user, groups and their memberships a whole lot easier.
Check out the MSDN article Managing Directory Security Principals in the .NET Framework 3.5 for an introduction to S.DS.AM.
You can get a user principal like this:
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "YOURDOMAIN");
UserPrincipal user = UserPrincipal.FindByIdentity("some user name");
PrincipalSearchResult<Principal> userGroups = user.GetGroups();
foreach (Principal p in myGroups)
{
GroupPrincipal gp = (p as GroupPrincipal);
if (gp != null)
{
int memberCount = gp.Members.Count;
}
}
This way, you can enumerate all groups a given user has, and enumerating those groups, you can find out how many members (users and other groups) each group has.

Resources