Many LDAP-enabled applications use a directory server to authenticate users, which often consists of a search to find the user’s entry based on the provided login ID, followed by a bind to verify the provided credentials. Some of these applications may purely use the directory server for authentication, while others may then go ahead and perform additional operations on behalf of the logged-in users.
If the application is well designed, then it will probably maintain a pool of connections that it can repeatedly reuse rather than establishing a new connection each time it needs to perform an operation in the server. Usually, the search to find a user is performed on a connection bound as an account created for that application. And if the application performs operations on behalf of the authenticated users, then it often does so while authenticated under that user same application account, using something like the proxied authorization request control to request that the server process those operations under the appropriate user’s authority.
The problem, though, is that performing a bind operation changes the authentication identity of the connection on which it is processed. If the bind is successful, then subsequent operations on that connection will be processed under the authority of the user identified by that bind request. If the bind fails, then the connection becomes unauthenticated, so subsequent requests are processed anonymously. There are a couple of common ways to work around this problem:
- It can maintain two different connection pools: one to use just for bind operations, and the other for all other types of operations.
- After attempting a bind to verify a user’s credentials (whether successful or not), it can re-authenticate as the application account.
In the Ping Identity Directory Server, we offer a third option: the bind request can include the retain identity request control. This control tells the server that it should perform all of the normal processing associated with the bind (verify the user’s credentials, update any password policy state information for that user, etc.), but not change the authentication identity of the underlying connection. Regardless of whether the bind succeeds or fails, the connection will end up with the same authentication/authorization identity that it had before the bind was attempted. This allows you to use just a single connection pool that stays authenticated as the application’s account, while still being able to verify credentials without fear of interfering with access control evaluation for operations following those binds.
The retain identity request control is very easy to use. If you’re using the UnboundID LDAP SDK for Java, you can just use the RetainIdentityRequestControl class, and the Javadoc includes an example demonstrating its use. If you’re using some other API, then you just need to specify an OID of “184.108.40.206.4.1.30220.127.116.11”, and you don’t need to provide a value. We recommend making the control critical so that the bind attempt will fail if the server doesn’t support it (although we added support for this control back in 2008 when it was still the UnboundID Directory Server, so it’s been around for more than a decade).
I’m not aware of any other directory server that supports the retain identity request control (aside from the LDAP SDK’s in-memory directory server), but it’s very simple and very useful, so if you’re using some other type of server you might inquire about whether they’d implement it or something similar. Of course, you could also switch to the Ping Identity Directory Server and get support for this and lots of other helpful features that other servers don’t provide.