ahaenggli / AzureAD-LDAP-wrapper

LDAP-Wrapper for 'microsoft 365' work or school accounts/users (former 'office 365' - via Entra ID, former AzureAD without AADDS)
https://ahaenggli.github.io/AzureAD-LDAP-wrapper/
MIT License
121 stars 30 forks source link

customSecurityAttributes mapping #94

Open dakolta opened 1 month ago

dakolta commented 1 month ago

I am trying to get the customSecurityAttributes that have been setup in AzureDirectory and assigned to users.

Screenshot 2024-09-28 at 9 59 14 AM

How can I get UsersWeb, NMLS and Extension mapped to the user information?

dakolta commented 1 month ago

I managed to figure it out from looking at the users.json file, here is my solution: modified the ldap_customizer.js with the following, I added 'customSecurityAttributes' to the apiConfig.uri, then added the code bellow. var flattendAttributes = {}; if (azureuser.customSecurityAttributes && azureuser.customSecurityAttributes.CustomAttributes) { const extension = azureuser.customSecurityAttributes.CustomAttributes.Extension; const nmls = azureuser.customSecurityAttributes.CustomAttributes.NMLS; const usersWeb = azureuser.customSecurityAttributes.CustomAttributes.UsersWeb; if (extension !== null && extension !== undefined) { flattendAttributes.phoneExtension = extension; // Will only print if Extension is not null or undefined } if (nmls !== null && nmls !== undefined) { flattendAttributes.nmls = nmls; // Will only print if Extension is not null or undefined } if (usersWeb !== null && usersWeb !== undefined) { flattendAttributes.usersWeb = usersWeb; // Will only print if Extension is not null or undefined } } // assign first ldapuser so all attributes are there in the correct order // then append flattendAttributes ldapuser = Object.assign({}, ldapuser, flattendAttributes, ldapuser);

I had to remove '${config.GRAPH_FILTER_USERS}' because I was getting this error:

'ERROR: 2024-09-29T21:45:12.613Z: graph.fetch.js callApi error with {

endpoint: "https://graph.microsoft.com/v1.0/users?$select=businessPhones,displayName,givenName,jobTitle,mail,mobilePhone,officeLocation,preferredLanguage,surname,userPrincipalName,id,identities,userType,externalUserState,onPremisesExtensionAttributes,customSecurityAttributesuserType eq 'Member'",

opts: {},

error: 'Request failed with status code 400',

graphErrorDetail: {

code: 'BadRequest',

message: "Parsing OData Select and Expand failed: Term 'businessPhones,displayName,givenName,jobTitle,mail,mobilePhone,officeLocation,preferredLanguage,surname,userPrincipalName,id,identities,userType,externalUserState,onPremisesExtensionAttributes,customSecurityAttributesuserType eq 'Member'' is not valid in a $select or $expand expression.",

innerError: {

  date: '2024-09-29T21:45:12',

  'request-id': '7569a88b-180a-4056-b380-ce8c2760a639',

  'client-request-id': '7569a88b-180a-4056-b380-ce8c2760a639'

}

}

}

ERROR: 2024-09-29T21:45:12.615Z: graph.checkVars.js checkPermissions: Probably missing permission User.Read.All for the Application. Request failed with status code 400'

ahaenggli commented 1 month ago

I tried it out about 1.5 years ago. A customizer is the way to go. Maybe you can take inspiration from the attempt from back then. Back then you had to use the beta endpoint instead of v1.0. Maybe that has changed in the meantime.

dakolta commented 1 month ago

This is the full code for my ldap_customizer.js and it is working as expected. ldap_customizer.txt Like I said in my last comment, I had to remove the '${config.GRAPH_FILTER_USERS}' because of the error complaining about that filter not working, but I have since resolved that by changing the syntax of the filter that was in the ldap_custmizer.js examples to this &$filter=${config.GRAPH_FILTER_USERS}

dakolta commented 1 month ago

Here is my solution for this, also I applied a fix for the user filter: For the customSecurityAttributes I check if thy exist first, then populate out, we had been using onPremisesExtensionAttributes extensionAttributes so I incorporated those.

// flatten customSecurityAttributes
var flattendAttributes = {};
if (azureuser.customSecurityAttributes && azureuser.customSecurityAttributes.CustomAttributes) {
    const extension = azureuser.customSecurityAttributes.CustomAttributes.Extension;
    const nmls = azureuser.customSecurityAttributes.CustomAttributes.NMLS;
    const usersWeb = azureuser.customSecurityAttributes.CustomAttributes.UsersWeb;
    if (extension !== null && extension !== undefined) {
        flattendAttributes.phoneExtension = extension; // Will only print if Extension is not null or undefined
    }
    if (nmls !== null && nmls !== undefined) {
        flattendAttributes.nmls = nmls; // Will only print if Extension is not null or undefined
    }
    if (usersWeb !== null && usersWeb !== undefined) {
        flattendAttributes.usersWeb = usersWeb; // Will only print if Extension is not null or undefined
    }
} else {
    flattendAttributes.phoneExtension = azureuser.onPremisesExtensionAttributes.extensionAttribute1;
    flattendAttributes.nmls = azureuser.onPremisesExtensionAttributes.extensionAttribute2;
    flattendAttributes.usersWeb = azureuser.onPremisesExtensionAttributes.extensionAttribute3;
}

// assign first ldapuser so all attributes are there in the correct order
// then append flattendAttributes
ldapuser = Object.assign({}, ldapuser, flattendAttributes, ldapuser);

For the filtering of the users that was causing the error that was happening was caused by not defining the filter properly in the code,,customSecurityAttributes${config.GRAPH_FILTER_USERS}. The fix was to specify the filter as per MS Graph documentation, ,customSecurityAttributes&$filter=${config.GRAPH_FILTER_USERS}