Contents


Overview

Skill Level: Beginner

Reader is assumed to be familiar with the fundamentals of Node.JS and Loopback and basic LDAP knowledge

While Loopback.io documentation provides a comprehensive guide on Oauth authentication. using loopback-component-passport, there is less detail on LDAP authentication. This recipe will provide step-by-step guidance to perform LDAP authentication

Ingredients

Step-by-step

  1. Create New Loopback Project, Install Dependencies and Create Datasource

    Create a new Loopback project by issuing the command¬†apic loopback¬†(optional:¬†include¬†–explorer to test out APIs without using API Editor) and wait until the process completes.

    step1-1-create-loopback-project

     

    Install loopback-component-passport and passport-ldapauth.

    loopback-component-passport is an additional module for 3rd Party Authentication. It is based upon PassportJS, a populer 3rd Party Authentication module for NodeJS.

    passport-ldapauth is a PassportJS Strategy module which enables authentication by LDAP. To learn more about Passport Strategies, refer to http://passportjs.org/docs

    step1-2-install-passport

     

    As a reference, these are the latest version of the modules installed as per the time of writing (can be found in package.json file)

    step1-3-verify-package.json_

     

    Create a new datasource. In this Recipe I will be using MongoDB, but feel free to use any other database.

    step1-4-datasource

     

    Create a new model, user, which has a base class of User. It is better to extend the built-in User model rather than using it directly as we can create custom remote methods and add new properties (Creating custom methods are out of this Recipe's scope)

    step1-5-user

  2. Configure model-config.json

    In server/model-config.json, add ../node_modules/loopback-component-passport/lib/models to the array of sources. Also add UserIdentity, UserCredential, AccessToken and ACL to the list of models.

    step2-1-model.config1

  3. Configure providers.json

    Create a new file with name providers.json in the project root directory. A couple of important points to note:

    • Feel free to assign any name. In this case, ldap¬†is used
    • authScheme should be set to¬†ldap
    • module should be set to¬†passport-ldapauth
    • authPath is the path for the authentication. i.e. the front-end will send a POST request to <server_hostname>/auth/ldap consisting of the username and password
    • successRedirect¬†is the path to be redirected to if authentication succeeds. However, this is overrided by¬†“json”: true.¬†“json”:true¬†will mean that Loopback will return a JSON response consisting of the token and userId¬†instead of redirecting. I find this is more useful as I will leave the redirection to be performed by the front-end
    • failureRedirect¬†is the path to be redirected to if authentication fails
    • session¬†is set to¬†false¬†as we will not be using session
    • ldap_attribute_for_login/username/mail will¬†need to be matched to the LDAP server
    • server¬†consists of an object with the LDAP server properties

    step3-1-providers1

  4. Create Boot Scripts

    Create a boot script in server/boot. In this case, it is named ldapAuth.js. This script will create an instance of passportConfigurator, which will load the settings in providers.json and an additional function named createAccessToken (do not rename) which enables us to override the default Token Time to Live (TTL) value (The Default value is 2 weeks).

    Note in the function passportConfigurator.setupModels, the userModel is mapped to user, which is a new model which is based on the built-in User model

    step4-1-ldapAuth

    Create a boot script to handle authentication failure path redirection. Note that this path matches the failureRedirect property in providers.json. If authentication fails, HTTP status 401 will be returned to the requester

    step4-2-routes

     

    Create a boot script to enable the server to only allow invoking APIs with authentication.

    step4-3-authentication

  5. Using Middlewares

    In server/server.js, inject the body-parser and loopback.token middleware

    body-parser is a Node.JS middleware to parse JSON requests

    loopback.token will check for tokens in HTTP requests.

    step5-1-server

  6. Test

    Start the server by running node . or node server/server.js

    Test out the request using an API Tester. In this example, I'm using Postman to simulate a POST request. 

    Correct credentials will result in a token that is returned to the requester, which then can be attached in headers when invoking other APIs.

    step6-1-postman

     

    Let's take a look at what happened in the database:

    A new AccessToken record (or document in MongoDB terms) is created. Note the TTL is 3600 (1 hour), not the default 2 weeks. Also note the id of the token and userId matches the response from Loopback

    step6-1-database1

    A new UserIdentity record is also created. Note the userId in AccessToken and UserIdentity matches with id of user

    step6-1-database2

     A user is automatically created in user table/collection

    step6-1-database3

     

    And that's it!!

    A strict disclaimer is that passport-ldapauth has an issue in which there is no error-handling if the LDAP server is unreachable (https://github.com/vesse/passport-ldapauth/issues/29)

6 comments on"Configuring Token-based LDAP Authentication with Loopback.io"

  1. Thanks, this is great!

    The passport-ldapauth issue has been fixed as of version 1.0.0.

    Do you have any insights as to why the password is stored in the User table for 3rd party authorization and how to disable this? This seems like an unnecessary security issue, even though it’s encrypted. I’m not sure why anything is stored in the User table. Also, email and passwords in the User table are not updated if they change in LDAP, and I’m sure the same is true of other providers.

    Thanks again for this tutorial!

  2. heisenberg13 February 02, 2017

    Thanks for this great recipe !
    I have a question : is there a way to consider the LDAP server as a datasource for User model (that way any CRUD operation will affect the LDAP server) ?
    Because the LDAP server is useful only for the first authentification of the user, after that the credentials used to authenticate the same user are retrieved from the mongodb datasource.

    Thanks a lot !!

  3. The correct LdapAttribute property names and default values are in providers.json:
    “LdapAttributeForLogin”: “uid”,
    “LdapAttributeForUsername”: “cn”,
    “LdapAttributeForMail”: “mail”,

  4. […] Configure token-based LDAP authentication with Loopback.io […]

  5. hi, this works for loopback “loopback”: “^3.0.0”,

    regards
    Eduardo

Join The Discussion