# AD for LDAP Authentication

# Preamble

The EE server and client support the LDAP protocol that allows you to configure an external LDAP service for authentication. This guide here will explain how to configure Psono server to use an Active Directory LDAP. We assume that Psono server can firewall / network wise access the LDAP Server / port. In addition we assume that your webclient is running on https://example.com, the server is reachable with https://example.com/server (e.g. https://example.com/server/info/ shows you some nice json output).

TIP

This feature is only available in the Enterprise Edition.

# Server (settings.yaml)

During the installation of the server you have created a settings.yaml that needs to be adjusted now.

  1. Standard configuration

    First lets configure the standard configuration part that is the same for all LDAP connections

    LDAP : [
      {
        'LDAP_URL': 'YOUR_LDAP_URL',
        'LDAP_DOMAIN': 'LDAP_DOMAIN',
        'LDAP_BIND_DN': 'YOUR_LDAP_BIND_DN',
        'LDAP_BIND_PASS': 'YOUR_LDAP_BIND_PASS',
        'LDAP_SEARCH_USER_DN': 'YOUR_LDAP_SEARCH_USER_DN',
        'LDAP_SEARCH_GROUP_DN': 'YOUR_LDAP_SEARCH_GROUP_DN',
        ...
      },
    ]
    
    • Replace YOUR_LDAP_URL with the URL to your LDAP. e.g. ldaps://192.168.0.1:636
    • Replace YOUR_LDAP_DOMAIN with your LDAP's domain. e.g. example.com
    • Replace YOUR_LDAP_BIND_DN with the DN of a user in your LDAP that can browse the directory. e.g. CN=LDAPPsono,OU=UsersTech,OU=example.com,DC=example,DC=com
    • Replace YOUR_LDAP_BIND_PASS with the password fo the user specified with the LDAP_BIND_DN
    • Replace YOUR_LDAP_SEARCH_USER_DN with the root DN underneath legit user objects would reside.
    • Replace YOUR_LDAP_SEARCH_GROUP_DN with the root DN underneath legit group objects would reside.
  2. Adjust the setting.yml as shown below

    The specific part for LDAP AD looks like this.

    LDAP : [
      {
        ...
        'LDAP_ATTR_GUID': 'objectGUID',
        'LDAP_OBJECT_CLASS_USER': 'user',
        'LDAP_OBJECT_CLASS_GROUP': 'group',
        'LDAP_ATTR_USERNAME': 'sAMAccountName',
        'LDAP_ATTR_EMAIL': 'mail',
        'LDAP_ATTR_GROUPS': 'memberOf',
        'LDAP_MEMBER_OF_OVERLAY': True,
        'LDAP_MEMBER_ATTRIBUTE': 'distinguishedName',
        'LDAP_ATTR_MEMBERS': 'member',
        ...
      },
    ]
    

    TIP

    If you specified a LDAP_SEARCH_USER_DN or LDAP_SEARCH_GROUP_DN without OU, then this is considered a global catalog search and as such you will have to use port 3268 (instead of 389) or 3269 (instead of 636). More infos can be found here: docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-2000-server/cc978012 (opens new window)

  3. Test your integration

    To test the settings you can use the testldap command like shown below

    docker run --rm \
      -v /opt/docker/psono/settings.yaml:/root/.psono_server/settings.yaml \
      -ti psono/psono-combo-enterprise:latest python3 ./psono/manage.py testldap username@something.com thePassWord
    

    TIP

    Once you have a working configuration don't forget to restart the server.

# Inherited Groups (experimental)

Psono provides the possibility to honor group inheritance. So if you have a user in Group A and Group A is a member of Group B then the regular "memberOf" attribute of a user won't include Group B. There is an optional feature called LDAP_MATCHING_RULE_IN_CHAIN in LDAP (ExtensibleMatch) that you can use. Adjust the config above and add / replace the following lines:

LDAP : [
  {
    ...
    'LDAP_MEMBER_OF_OVERLAY': False,
    'LDAP_EXTENSIBLE_MATCH_GROUP_SEARCH': ':1.2.840.113556.1.4.1941:',
    ...
  },
]

# Server Sync (optional)

Psono provides a command to keep the users and their activity state between Active Directory and the server in sync.

  1. Modify LDAP config

    You currently have a config like:

    LDAP : [
      {
        ...
        'LDAP_ATTR_GUID': 'objectGUID',
        'LDAP_OBJECT_CLASS_USER': 'user',
        'LDAP_OBJECT_CLASS_GROUP': 'group',
        'LDAP_ATTR_USERNAME': 'sAMAccountName',
        'LDAP_ATTR_EMAIL': 'mail',
        'LDAP_ATTR_GROUPS': 'memberOf',
        'LDAP_MEMBER_OF_OVERLAY': True,
        'LDAP_MEMBER_ATTRIBUTE': 'distinguishedName',
        'LDAP_ATTR_MEMBERS': 'member',
        ...
      },
    ]
    

    Modify it to include:

    LDAP : [
      {
        ...
        'LDAP_SYNC_SETTINGS': {
            'ON_CREATE': 'CREATE',
            'ON_ENABLE': 'ENABLE',
            'ON_DISABLE': 'DISABLE',
            'ON_DELETE': 'DISABLE'
        }
        ...
      },
    ]
    
    • 'ON_CREATE': 'CREATE': The server will create users that don't exist in Psono. (Pay attention as it may create users that you don't want and as such block licenses for other users.)
    • 'ON_ENABLE': 'ENABLE': The server will enable users once they are enabled in LDAP. (Pay attention as it may activate users that you disabled on purpose and potentially block licenses for other users.)
    • 'ON_DISABLE': 'DISABLE': The server will disable users and log them out once they are disabled in LDAP. (Pay attention as this flag may only be used with configurations that use a single LDAP server.)
    • 'ON_DELETE': 'DISABLE': The server will disable users and log them out once they are deleted in LDAP. Pay attention as this flag may only be used with configurations that use a single LDAP server.)
    • 'ON_DELETE': 'DELETE': The server will delete users once they are deleted in LDAP. (Pay attention as this flag may only be used with configurations that use a single LDAP server and may cause data loss.)

    None of the flags is mandatory, so feel free to leave out e.g. 'ON_CREATE': 'CREATE' completely if you don't want to automatically create users.

  2. Dryrun

    Lets see if the chosen configuration behaves correctly with a dryrun

    docker run --rm \
      -v /opt/docker/psono/settings.yaml:/root/.psono_server/settings.yaml \
      -ti psono/psono-combo-enterprise:latest python3 ./psono/manage.py syncldap --dryrun
    

    Compare the output with your expectation.

  3. Cronjob

    Configure a cronjob to execute on a regular basis.

    docker run --rm \
      -v /opt/docker/psono/settings.yaml:/root/.psono_server/settings.yaml \
      -ti psono/psono-combo-enterprise:latest python3 ./psono/manage.py syncldap
    

    TIP

    If you are in an environment where executing commands is hard, you may want to try using remote commands as explained in Commands - Remote commands.

# Client (config.json)

Now you have to configure your client, so your users can use this configured IDP.

  1. Edit config.json

    Update your config.json similar to the one shown below.

    {
      "backend_servers": [{
        "autoapprove_plain_password": true,
        ...
      }],
      "authentication_methods": ["LDAP"],
      ...
    }
    

    The variable authentication_methods restricts the allowed login methods. In the example above only LDAP will be allowed. The autoapprove_plain_password flag will hide a warning dialog for the user, informing him about the plaintext master password transfer.