Look up user in AAD based on AADB2C attribute value - azure-active-directory

If I have a user in Aure AD B2C that was created based on an Azure AD (enterprise) identity (as described here: https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-setup-aad-custom), is there an attribute stored in AADB2C that will allow me to look up (using Graph API or similar) the user object in AAD? I see that among the AADB2C attributes there is userPrincipalName and issuerUserId but it's not obvious to me if either of these match any value stored in AAD.
thanks!
Martin

For an external account, the external issuer (i.e., Azure AD) and the external user identifier (i.e., the object identifier of the Azure AD user) are written to the "userIdentities" property of the user object in the Azure AD B2C directory, where the "issuerUserId" property contains the Base64-encoding of the external user identifier:
{
"userIdentities": [
{
"issuer": "contoso.com",
"issuerUserId": "Mjk2NzdlNTAtY2MwZS00MmU5LWJhNWMtZjFmMDdkZTUwMDhm"
}
]
}
To find the user object by the external account, you can invoke the following Graph API operation, where the "x/issuerUserId" value is set to the hexadecimal-encoding of the external user identifier:
GET https://graph.windows.net/myorganization/users?$filter=userIdentities/any(x:x/issuer eq 'contoso.com' and x/issuerUserId eq X'32393637376535302d636330652d343265392d626135632d663166303764653530303866')
Update:
The issuerUserId from the external identity provider should be treated as string and not decimal. In above example, when you base 64 decode "Mjk2NzdlNTAtY2MwZS00MmU5LWJhNWMtZjFmMDdkZTUwMDhm" - it returns a guid 29677e50-cc0e-42e9-ba5c-f1f07de5008f. In case of facebook, the issuerUserId will be a number, but still should be treated as string.
Next step will be to use string to hexadecimal converter and then use that value in the query.

Related

Azure AD SCIM: SystemForCrossDomainIdentityManagementMultipleEntriesInResponse

We're using Azure AD as the Identity Provider for User Provisioning into our system.
We have started getting this error of late.
EntrySynchronizationError
Result Failure
Description Failed to match an entry in the source and target systems User 'XXX#XXX.com'
ErrorCode SystemForCrossDomainIdentityManagementMultipleEntriesInResponse
There has been no change in our scim server code. The error message is obviously stating it's fetching more than 1 entry when it should return 1 but in reality, there is no user with the said username & Azure AD should be sending a request to create a new one.
This is happening under the action "Other", I'm guessing it's a GET.
Any idea on what's going wrong here?
A GET operation with a filter (ie: GET /Users?filter=userName eq "Test_User_dfeef4c5-5681-4387-b016-bdf221e82081") is expecting either 0 or 1 result to be returned, but is receiving more than one result. Either your configuration in provisioning is matching on an attribute that is not uniqueness constrained (ie: department eq "Sales") or there's a problem with your logic for returning filtered results.

How to extract whole userPrincipalNames of the user from AD?

I create a user account with multiple UPNs in AD. How do we extract whole UPNs from AD?
For instance: sathishM#litwareinc.pri/ sathishM#Facrikam.com; <UPN:: #litwareinc.pri | #Facrikam.com>
I would like to extract #litwareinc.pri and #Facrikam.com. Thanks
That entire value (for example: sathishM#litwareinc.pri) is stored in the userPrincipalName attribute of the AD object. It is only AD Users and Computers that separates it.
If you want just the domain portion, then you will just need to split the string by the #. How you do that depends on how you plan on reading the object.

ADFS 3.0 Custom attribute in SAML token

I am setting up a relaying party trust (IDP) for an application a SP provides. Problem is that the SP requires a "customer ID" to be prefixed the username. E.g on-prem AD user john#company.com logges on and SP requires 001john#company.com to access the application.
How do i configure ADFS 3.0 to include the "customer id" in SAML token?
Error i receive now is: "The customer Id in the username john#company.com does not match the ones configued for the partner [001].
SP uses IBM FIM as federation solution.
Metadata is set up on both SP and IDP side.
Thanks.
You can append a string e.g.
c:[type == "http://someclaim"]
=> issue(type = "http://anotherclaim", value = "001" + c1.Value );
but there is not enough detail.
Do you always add "001" or does it vary?
Which claim do you want to alter?
Update
Have a normal LDAP rule that takes email and creates http://company.com/Temp1
(The dropdown is editable).
Then:
c:[type == "http://company.com/Temp1"]
=> issue(type = "http://company.com/Temp2", value = "001" + c.Value );
Then use a transform rule to transform http://company.com/Temp2 to NameID with a format of email.

What is the proper way to get some specific user attributes from Active Directory via LDAP C API?

I am trying to get some user attributes from Active Directry using Windows LDAP API. I am using:
Active Directory Version: The one that comes with Windows Server 2012
LDAP version: 3
Wldap32.lib version: The one that comes with Windows 10 x64
Eg:
PCHAR myAttributes[4];
myAttributes[0] = "DistinguishedName";
myAttributes[1] = "DisplayName";
myAttributes[2] = "PasswordExpired";
myAttributes[3] = "mail";
ldap_search_s(
myLdapConnection, // Ldap connection
myDomain, // DN to start search
LDAP_SCOPE_SUBTREE, // Scope
myFilter, // Filter
myAttributes, // Retrieve list of attributes
0, // Get both attributes and values
&mySearchResult // [out] Search results
);
It returns DistinguishedName, DisplayName and mail attributes, but does not reuturn the PasswordExpired attribute.
I queried with some other attributes and it looks like it does not return attributes with boolean values as well as the EmailAddress attribute.
Why does it not return PasswordExpired attribute?
What about EmailAddress ?
Is there a difference between EmailAddress and mail ?
There is no PasswordExpired LDAP attribute in Active Directory. To build your query look at this URL for attribute names in standard Active Directory schema https://msdn.microsoft.com/en-us/library/ms675090(v=vs.85).aspx. To check if password for given account is expired you'll need to check userAccountControl attribute, which is actually value storing flags of different states of user account https://msdn.microsoft.com/en-us/library/ms680832(v=vs.85).aspx. There is IADsUser interface that will translate this all for you in case you don't have to stick just to LDAP https://msdn.microsoft.com/en-us/library/aa746343(v=vs.85).aspx
You will find current primary email address in mail attribute. There is no EmailAddress LDAP attribute, unless you meant E-mail-Addresses which is CN for the same schema attribute as mail, so no difference there.
See above. In general if you do not have compelling reason to stick just to C/LDAP I'd recommend you to use .Net Framework instead. Otherwise you have a lot of work ahead of you - not just interpreting bit flags like in case of password expiration but possibly also with different authentication methods, different structures capturing time and date, accounting for timezones, UTF, chasing referrals and other stuff you might need depending on complexity of what you want to achieve. You will be productive much faster in .Net Framework. See DirectoryServices https://msdn.microsoft.com/en-us/library/mt481534(v=vs.110).aspx namespace or Security namespace https://msdn.microsoft.com/en-us/library/mt481561(v=vs.110).aspx for details.

Get users from Acctive Directory Group

I created an Active Directory domain name 'ADDOMAIN2' having a group name "CommonUsers" having 8 users. but when I do a Directory Search for users in group "CommonUsers" it returns zero result. hers is my code
DirectorySearcher searcher = new DirectorySearcher();
DirectoryEntry directoryEntry = new DirectoryEntry(string.Format("LDAP://{0}", "ADDOMAIN2"), "Administrator", "p#S$w0rd");
string dnPath = directoryEntry.Properties["distinguishedName"].Value.ToString();
// string path = string.Format("LDAP://{0}/{1}{2}", "ADDOMAIN2", "", dnPath);
string path = "LDAP://ADDOMAIN2/CN=CommonUsers,DC=ADDomain2,DC=ADDomain01,DC=WaveDomain";
directoryEntry.Path = path;
searcher.SearchRoot = directoryEntry;
searcher.Filter = "(&(objectCategory=person)(objectClass=user))";
SearchResultCollection rs = searcher.FindAll();
Any Idea what is wrong here?
Thanx
Try using some external LDAP browser (like the old and free version 2.6 of Softerra LDAP Browser) to check whether your query string is really pointing to the correct location.
DirectorySearcher is not used to find users inside a group. It's used to find objects under a base path. Since there is no user objects placed under your AD group object, you won't find anything.
In most cases, you can find the user objects in an AD group from its member attribute. Beware that AD group can contain either group or user. So, some of the entres there may be group. In some cases, the member attribute does not contain AD group nor AD user, it's containing a Foreign Security Principal. This happens if your user is coming from another forest. The primary group is also handled differently. Even "Domain User" is primary group of most of the users in AD, its member attribute doesn't contain anything at all. There are a lot other oddities that makes enumerating an AD group object really hard.
Fortunately, in .NET 3.5, Microsoft provides some useful classes in the framework to do the dirty work for you. Check out System.DirectoryServices.AccountManagement
To get some quick examples, you can check out this codeproject article
Your code should be something like this.
PrincipalContext context = new PrincipalContext(ContextType.Domain, "yourdomain.com");
GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "Domain Users");
foreach (Principal principal in groupPrincipal.GetMembers(false))
{
Console.Out.WriteLine(principal.DistinguishedName);
}
Console.In.ReadLine();

Resources