ging / fiware-idm

OAuth 2.0-based authentication of users and devices, user profile management, Single Sign-On (SSO) and Identity Federation across multiple administration domains.
https://keyrock-fiware.github.io
MIT License
36 stars 81 forks source link

Authentication issue with external LDAP to Microsoft AD (Active Directory) #296

Open kent010341 opened 1 year ago

kent010341 commented 1 year ago

As far as my understanding, the behavior of fiware-idm's "External Authentication (LDAP)" is using the reader_dn and reader_password, with the suffix as the search base, and use a filter (uid=<user>) to do an LDAP bind and search operation. (code: external_auth/authentication_driver_ldap.js, line 26)

However, the DN of AD (Microsoft Active Directory) looks like CN=guest,OU=example,DC=oa,DC=test,DC=com, so the filter to this case (uid=guest) won't match any user in AD. By manually change const filter = '(uid=' + username + ')'; to const filter = '(cn=' + username + ')'; at external_auth/authentication_driver_ldap.js, line 26, the login with LDAP works.

Maybe this issue can be fixed by making the filter able to be configured by config.js?

kent010341 commented 1 year ago

In my opinion, the changes will be:

  1. Add a key to config.external_auth_ldap of config.js, like user_rdn, the value is uid by default. (start at line 143)

    // External user authentication with LDAP
    // Testing credentials from https://www.forumsys.com/tutorials/integration-how-to/ldap/online-ldap-test-server/
    config.external_auth_ldap = {
    enabled: true,
    id_prefix: 'external_ldap_',
    database: {
    /* eslint-disable snakecase/snakecase */
    host: 'ldap.forumsys.com',
    port: 389,
    reader_dn: 'cn=read-only-admin,dc=example,dc=com',
    reader_password: 'password',
    suffix: 'dc=example,dc=com',
    idAttribute: 'uid',
    usernameAttribute: 'uid',
    emailAttribute: 'mail',
    user_rdn: 'uid'
    /* eslint-enable snakecase/snakecase */
    }
    };
  2. At external_auth/authentication_driver_ldap.js, use this config as a filter. (start at line 26)

    const filter = '(' + external_auth.database.user_rdn + '=' + username + ')';
kent010341 commented 1 year ago

Furthermore, according to this document, Microsoft Active Directory supports several possible ways to make an LDAP bind.

Except for binding with DN (distinguished name), AD accepts binding with something like UPN (User Principal Name, looks like john@example.com). In this way, the reader_dn and reader_password aren't necessary because we don't need to search for the user's DN.

kent010341 commented 1 year ago

There's another issue found recently, the original code assumes that it can use (uid=<username>) as a filter to search for the user info. However, the uid could somehow be different from the given account (username), or the account is stored at another attribute. Therefore, the RDN used for the filter should be able to be set with config.