LDAP LAMBDA



  • Hi,

    We are just getting started with FusionAuth, currently investigating its suitability for our requirements, and cant seem to get the LDAP lambda to work. I know this is a new feature, which is why there is no documentation, but can someone please provide a reference lambda to use? Or a quick how-to?

    Our basic use case is to have an app authenticate against FusionAuth which behind the scenes uses LDAP, so just looking to get this off the ground in its most simple configuration.

    Thanks

    Brad.



  • Hi Bradley,

    It seems you mean the ability to authenticate against LDAP? The functionality described here: https://github.com/FusionAuth/fusionauth-issues/issues/219 correct?

    If so, this is a new feature in 1.18 and I know we're working on documentation right now, since this is a technology preview. I expect some docs to be delivered toward the end of the week, as I know the team is working on them.

    I'll pass on this forum post and hopefully get you an answer sooner.



  • Here is how I would suggest you work through the construction of your lambda function.

    Start with a basic function like this to print out the SAML response.

    function reconcile(user, userAttributes) {
      // Dump the userAttributes object to an Info Event Log
      console.info(JSON.stringify(userAttributes, null, 2));
    }
    

    This will give you an Event log to show you what is being returned from your LDAP, and more specifically the attributes we have extracted from that response. To find the event log, navigate to System > Event Log.

    The goal of this lambda will be to build up the user and registrations. Here is a more full featured example of what that may look like. The result of this lambda would be a user with an email and fullName set and a single registration.

    function reconcile(user, userAttributes) {
      // Dump the userAttributes object to an Info Event Log
      // console.info(JSON.stringify(userAttributes, null, 2));
    
      user.id = userAttributes.uid;
      user.active = true;
    
      user.email = userAttributes.mail;
      user.fullName = userAttributes.cn;
    
      // This is the basic idea of how to build the registration.
      // The values will be dependent upon what is returned in your SAML
      // response. You can hard these values if you want them to always
      // be the same, or it may be variable based upon the SAML attributes returned.
      user.registrations = [{
        applicationId: "5d562fea-9ba9-4d5c-b4a3-e57bb254d6db",
        roles = ['user', 'admin']
      }];
    }
    

    We should have documentation out shortly as well, but hopefully this will get you moving. As @dan mentioned, this is a preview release for this feature, so if you run into bugs or missing capability please open a GitHub issue and let us know.



  • @robotdan This is as far as I got on Friday.

    The problem is that the user.id requires a GUID as a string. If I use the sAMAccountName or userPrincipalName I get the following error:

    Lambda invocation exception.
    
    Id: 79e93d02-aeb6-47a4-9e41-1478ec79a4e5
    Name: Active Directory
    
    com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.util.UUID` from String "bradley.kite@cybanetix.com": UUID has to be represented by standard 36-char representation
     at [Source: (String)"{"active":true,"data":{},"memberships":[],"passwordChangeRequired":false,"preferredLanguages":[],"registrations":[],"twoFactorEnabled":false,"verified":false,"email":"bradley.kite@cybanetix.com","firstName":"Bradley","lastName":"Kite","id":"bradley.kite@cybanetix.com"}"; line: 1, column: 241] (through reference chain: io.fusionauth.domain.User["id"])
    

    I've tried using the actual objectGUID field from Active Directory, but this comes across in binary format, and needs to be translated to the string representation of a GUID. I've tried (with the code below) to convert the GUID from binary to string representation but no such luck as yet.

    function reconcile(user, userAttributes) {
      
      console.debug("USER: " + JSON.stringify(user));
      
      console.debug("ATTR: " + JSON.stringify(userAttributes));
      
      user.email     = userAttributes.userPrincipalName;
      user.firstName = userAttributes.givenName;
      user.lastName  = userAttributes.sn;
      user.active    = true;
      user.id        = guidToString(userAttributes.objectGUID);
      
        // guidToString("\374\240\270\317\260\260\213\104\206\233\357\330\240\225\130\207");
      
    }
    
    function guidToString(x)
    {
        var ret = "";
      
        for (i = 3; i >= 0; i--)
        {
            ret += ('00'+x.charCodeAt(i).toString(16)).substr(-2,2);
        }
        ret += "-";
        for (i = 5; i >= 4; i--)
        {
            ret += ('00'+x.charCodeAt(i).toString(16)).substr(-2,2);
        }
        ret += "-";
        for (i = 7; i >= 6; i--)
        {
            ret += ('00'+x.charCodeAt(i).toString(16)).substr(-2,2);
        }
        ret += "-";
        for (i = 8; i <= 9; i++)
        {
            ret += ('00'+x.charCodeAt(i).toString(16)).substr(-2,2);
        }
        ret += "-";
        for (i = 10; i < 16; i++)
        {
            ret += ('00'+x.charCodeAt(i).toString(16)).substr(-2,2);
        }
      
        return ret;
    }
    


  • Any update on this guys? I cannot commit our solution to being based on FusionAuth if I'm not able to get this working.

    Thanks in advance

    --
    Brad.



  • We do offer paid support plans if you'd like engineering support.

    We do our best to get to all of the community issues as well, but our resources are limited.

    Hope to get back to this soon.



  • @robotdan

    I'm very disappointed with this reply.

    In order to evaluate Fusion Auth I had to buy a subscription in the first place (Fusion Reactor) just to get it up sand running in a lab environment (it's not even in production).

    There's no documentation, and you can't even provide a reference lambda that works.

    I'm happy to provide the engineering resources on our side to get this working but I'm hesitant to pay further for a product that is lacking in basic documentation when we are just in the evaluation phase. If it turns out there is some other critical component or feature that is bit suitable then it would be wasted resources.

    Regards

    Brad



  • Hi Bradley,

    I understand your frustration. We're working on documenting this functionality, but as Daniel mentioned, this is a technology preview so there will be some sharp edges. I'm sorry you ran into one during your evaluation.

    For the developer edition we only offer community/best effort support as laid out here: https://fusionauth.io/pricing ; if you want guaranteed support request turnaround times, we do offer other plans, as previously mentioned.

    If you'd like, I'm happy to reach out to you when the feature is more fully documented.

    We also only want happy customers, so we're happy to refund your developer subscription.

    Please let me know,
    Dan



  • Regarding the proximate question, if you don't provide a user id, fusionauth will create one. So instead of trying to translate the active directory guid to a string, I'd just omit the assignment to user.id in the lambda and see if that works.



  • Hi Dan,

    I've noticed that the documentation has been updated, thats great, thanks.

    https://fusionauth.io/docs/v1/tech/lambdas/ldap-connector-reconcile

    Here it says that the UID must be a string. From Active Directory, the UID is in binary format. I've tried not assigning an ID but this doesnt work. I get this in the event log:

    8/3/2020 11:49:05 pm BST
    . WARNING DISCARDING USER because it was missing a unique id in the [user.id] property.

    So unless I'm missing something, I'm still in the position where I need to somehow convert from binary to text format.

    What LDAP directory (OpenLDAP, AD etc) are you guys testing against internally?

    --
    Brad.



  • Hiya,

    Glad the additional documentation is helpful.

    OpenLDAP is one of the LDAP servers we tested against. I'm not sure we've tested ActiveDirectory as an LDAP connector.

    https://stackoverflow.com/questions/57019325/convert-objectguid-to-uuid-string-using-javascript might be useful for doing the conversion to a string from the binary guid.

    We're using nashorn to execute the javascript; I think you need to define any functions within your main function (reconcile). Here's an issue with that information.

    HTH.



  • The problem is that the array of bytes from AD is being interpreted as invalid UTF-16 data.

    This can be seen because I've attempted to get the raw binary data from the objectGUID as follows:

    for (i = 0; i < userAttributes.objectGUID.length; i++)
    {
    console.debug("GUID " + i + ": " + userAttributes.objectGUID.charCodeAt(i));
    }

    This ends up printing the following data:

    GUID 0: 65533
    GUID 1: 65533
    GUID 2: 65533
    GUID 3: 1008
    GUID 4: 65533
    GUID 5: 65533
    GUID 6: 68
    GUID 7: 65533
    GUID 8: 65533
    GUID 9: 65533
    GUID 10: 1568
    GUID 11: 65533
    GUID 12: 88
    GUID 13: 65533

    Is it possible that I can go through the source code at all? I thought there was an open source version of FusionAuth but I couldnt find the code for it.

    I imagine that such binary data needs to actually be an array of bytes. Something is trying to UTF-16 decode the data, and as per https://www.fileformat.info/info/unicode/char/0fffd/index.htm the actual binary data is being replaced with the UTF-16 value of 65533.

    Given that the vast majority of the world (like it or not) use Active Directory, the LDAP feature is not going to be very valuable to your customers unless we can work through this.

    We have over 150 Linux servers, all joined to an Active Directory domain running on the only two Windows servers we have in our estate. Not ideal, but thats the reality of the world we live in.



  • Hi @bradley-kite

    I agree, we should definitely support activedirectory. Can you please file a bug with exact repro steps? I was going to file a bug for you and realized I didn't necessarily have all the steps, which is super helpful to folks working on the issue.

    https://github.com/FusionAuth/fusionauth-issues/issues/new/choose

    Please feel free to link to this forum topic in the "Additional info" section so the devs can have more context for what you've tried to accomplish.



  • Hi Dan,

    Thanks - I've created a ticket here:

    https://github.com/FusionAuth/fusionauth-issues/issues/822

    Regards

    Brad.



  • In case anyone else would like to do the same, I have found a solution which I have detailed here:

    https://github.com/FusionAuth/fusionauth-issues/issues/822#issuecomment-680172776


Log in to reply
 

Looks like your connection to FusionAuth Forum was lost, please wait while we try to reconnect.