Developer’s Corner: Active Directory based security in GeoServer through LDAP

Dear all,
as you may already know, the GeoServer security subsystem, based on the Spring Security framework, is quite flexible and configurable to allow you to integrate GeoServer into your existing security infrastructure.
For example, by default, it allows usage of the most known authentication mechanisms and sources, such as HTTP Basic Authentication, X509 certificates, J2EE container controlled security, form based security and so on.

For more information on the GeoServer security subsystem you can take a look at the related documentation, here and here.

Among the available authentication sources, the LDAP choice is one of the most important, because many enterprise authentication services are based on an LDAP repository to store users and all the information related to them, also for security purposes, such as the username and password, group membership and so on.

The LDAP Authentication provider allows to authenticate users through “binding” to the LDAP repository using the user credentials (usually composed of the user Distinguished name and its password).
To transform the username to a complete Distinguished name the User lookup pattern option is used. This is a pattern with a placeholder, where {0} stays for the entered username (e.g uid={0},ou=People).

Moreover, it also allows to get authorities for the user (essentially the roles the user has) mapping them to LDAP groups and user group membership (this is optional, authorities/roles can also be filled using a given UserGroupService). The authorities retrieval from the LDAP service can be enabled using the Use LDAP groups for authorization flag.

Talking of security infrastructures, can you think of a more widespread one than Windows domains, the default in all the Windows based networks worldwide?
Well, the good news is that a Windows domain uses an LDAP repository for this purpose, the ActiveDirectory service. The bad news is that the standard GeoServer LDAP Authentication provider (that is the module able to use LDAP as an authentication source) was not able to correctly connect to an ActiveDirectory service and extracts the information needed for a couple of reasons:

  • ActiveDirectory allows searching only when the user is authenticated, while the Geoserver module was doing searches anonymously
  • Distinguished names of users cannot be easily built from the username, but a filter search is needed to get user objects, while Geoserver could only extract user data from its distinguished name
For these reasons we recently added some new options to the GeoServer LDAP Authentication provider, allowing usage of an ActiveDirectory server as the authentication source.
This improvement is available since the version 2.3.5 of GeoServer.

To enable searching with the user authenticate, we added this new option:

  • Bind user before searching for groups: flag used to enable authenticated searching,  needs to be checked when using ActiveDirectory, that doesn’t allow anonymous searches.

To enable authentication without having a distinguished name, the thing was a little bit more complex.
First of all, if you are not familiar with Windows domains and ActiveDirectory, we should explain a couple of things. In a Windows domain, users can authenticate themselves using two different usernames, tha main one is the User Principal Name, that is an email-like username in the form username@domain.local, the other one is the SAM Account Name, that is the old username used before Windows 2000 (but still valid in modern Windows versions). Unfortunately none of them are part of the distinguished name.
So, we added these two options:

  • Filter used to lookup user: to be used instead of User lookup pattern as a username to user details filter. This can be:
    •  (userPrincipalName={0}), if you want to use email-like usernames (e.g user@domain.local); in this case you could also use the following Format used for user login name option, to automatically append the @domain.local part. The {0} placeholder stays for the username with the format applied.
    • (sAMAccountName={1}) if you want to use older SAM-Accounts (e.g. user). , The {1} placeholder is the username as given by the login procedure, without format applied.
    • (|(userPrincipalName={0})(sAMAccountName={1})) if you want to accept both.
  • Format used for user login name: this could be compiled when using email-like usernames (e.g user@domain.local) to automatically append domain info (e.g. {0}@domain.local )
Moreover, we added a couple of options to map LDAP groups to GeoServer administrative roles:
  • Group to use as ADMIN: LDAP group that should be equivalent to GeoServer ADMIN role.
  • Group to use as GROUP_ADMIN: LDAP group that should be equivalent to GeoServer GROUP_ADMIN role.
Here an example of configuration for a generic ActiveDirectory service, with roles binding enabled:
You can find a complete tutorial on how the LDAP AuthenticationProvider can be configured to connect to an ActiveDirectory server here.
These improvements left one annoying task to be done manually: the task of adding new roles manually to the GeoServer RoleService, so that access permissions could be assigned to groups of users.
It is true that roles could be assigned to users retrieving them from the LDAP repository, but there was no possibility to get a list of all the available roles, to be used for permission assignments, so each used role needed to be added manually to the default RoleService.
What was missing to get a complete implementation was a new LDAP RoleService able to get roles list directly from the LDAP repository used for authentication purposes.
This is not true anymore, since the new LDAP RoleService has finally landed on GeoServer master some days ago. This is going to complete the circle to have a complete LDAP support and it is (obviously) ActiveDirectory compatible.
Here a simple example of an ActiveDirectory configuration for the service.
As you can see the configuration options are very similar to those of the LDAP AuthenticationProvider, just a few notes on some of them:
  • Group user membership search filter: this is a filter that matches user to groups membership info and allows to bind users to their group. {1} stays for user complete distinguished name ({0} instead is the entered username).
  • Filter used to lookup user: filter used to get the user object (and the related distinguished name) from the simple username (e.g. from GISUSER to cn=CompleteGisUserName,cn=Users); in this example the SAM Account is used for filtering, userPrincipalName can also be used for the same purpose.
  • Authentication: since ActiveDirectory avoids anonymous searches we need to give the RoleService a set of credentials to authenticate with before doing any search on the ActiveDirectory service.

We are going to backport the new LDAP RoleService on 2.4.x as soon as it proves to be stable on master, so maybe we will have it on stable series for Christmas or at most the new year (isn’t it a good gift for your business?).
We are also going to continue improving the LDAP support in Geoserver if needed, so stay in touch with us!

If you are interested in learning about how we can help you achieving your goals with our Open Source products and professional services, do not hesitate to contact us!

The GeoSolutions team,