What security features does Json2Ldap offer?

Json2Ldap is not just about giving developers a nice JSON web API for working with LDAP directories. It also provides a number of security features such as:

  • LDAP server whitelists.

  • Connection quotas per client IP and authenticated user (bind DN).

  • Use of secure connection identifiers (CID).

  • Clients may be required to authenticate with LDAP "bind" at connection time.

  • Supports hiding of the hostname / IP address of the back-end LDAP server from from web clients.

  • TLS/SSL may be required for web client access to Json2Ldap, or for connections to the backend LDAP directory.

  • Directory access may be limited to read-only or authenticate-only.

How do I set a user password in Microsoft Active Directory?

In Active Directory (AD) the password attribute is called unicodePwd. The password value is expected to be provided in the following format: surrounded by quotes and encoded as a UTF-16 (little-endian) string. For example:


Failing to meet the unicodePwd encoding criteria will result in the following LDAP error:

Server is unwilling to perform (53)

MS AD also requires an SSL/TLS LDAP connection for all password modify requests. A plain (unsecured) connection will not work.

JSON mandates a UTF-8 encoding and so does Json2Ldap by extension. To work around this and feed a UTF-16 string to MS AD we suggest use of the optional binary parameter of ldap.add / ldap.modify:

The steps:

  1. Produce the UTF-16 password string as expected by AD. Don't forget the double quotes!

  2. Encode it into a BASE64 string.

  3. Set the optional binary parameter true.

How do I set the user password in other directories?

The preferred method for setting user passwords in other LDAP servers is the password modify extended operation. It is supported by the following LDAP servers:

  • OpenLDAP
  • OpenDJ
  • 389 Directory Server

The above list is not exhaustive.

How to set passwordNeverExpires in Microsoft Active Directory?

This setting is actually a bit in a bitfield of the userAccountControl attribute.

When the needed bitfield is composed convert it to an unsigned integer, such as 65536, and then set the userAccountControl attribute to that integer.


You can use the popular cURL command line utility to send requests to Json2Ldap.

Example ldap.connect request with cURL:

curl -H 'application/json' --data-binary '{"method":"ldap.connect","id":1,"jsonrpc":"2.0"}' http://demo.c2id.com/json2ldap/

Example ldap.getEntry request:

curl -H 'application/json' --data-binary '{"method":"ldap.getEntry","params":{"CID":"qkiHiA35XlzVj-hDjXrFG54UIWcaVgVBbZEVQugGN5c","DN":"uid=alice,ou=people,dc=wonderland,dc=net"},"id":2,"jsonrpc":"2.0"}' http://demo.c2id.com/json2ldap/

The -H parameter sets the Content-Type HTTP request header.

The --data-binary parameter sets the HTTP POST body (with the the JSON-RPC 2.0 request).

How to deal with international characters?

UTF-8 is the default character set for JSON messages and for LDAP strings. Therefore Json2Ldap will always return UTF-8 encoded content.

To avoid gibberish in your request parameters when dealing with non-ASCII strings, which may occur in DNs, search filters and attribute values, set your HTTP request content type header accordingly and make sure your strings are output in UTF-8 too:

Content-Type: application/json; charset=utf8

If you don't do that you may get unexpected results, such as search filters not matching or attributes with garbled values.

Note that MS Active Directory instances may deviate from the norm and be configured with a different character set.

Why do I get an LDAP error 11 (Admin Limit Exceeded) when making searches?

This error is raised when the so-called "look through" limit is exceeded. If you're using OpenDS set the ds-cfg-lookthrough-limit configuration parameter to a value that is greater than the total number of entries in your directory.

Setting up client X.509 certificate authentication

On the client side:

If you're using a Java client library to connect to Json2Ldap, such as the open source JSON-RPC 2.0 Client, you need to specify the key store where the client's public certificate and its private key are stored.

This can be done by setting the following system properties, either with the -D switch to the java command, or with System.setProperty from within your client code:


You can find more information in the following Stack Overflow post.

On the server side:

The client certificate must also be imported into a Java trust store which is made available to the web server (e.g. Tomcat) where Json2Ldap is installed.

This can be done by setting the following system properties to the web server:

javax.net.ssl.trustStore = path/to/truststore.jks

More on the difference between key and trust stores.

Looking for a key store GUI?

The excellent Key Store Explorer can save you the hassle of dealing with the keytool command line utility directly, for all common tasks such as viewing a keystore's content or importing / exporting keys and certificates.

How to create an Apache Tomcat deployment package?

Script to create an Apache Tomcat ZIP package with Json2Ldap deployed as the sole web application in it:

#!/usr/bin/env bash

# Path to the Json2Ldap WAR to deploy into Tomcat

# The Tomcat version and download URL

# The ZIP file to create

# The work directory

# Create work directory
mkdir -p ${WORK_DIR}

# Download Tomcat
wget -O ${WORK_DIR}/tomcat.zip ${TOMCAT_URL}

# Unzip Tomcat and strip version from directory name
unzip ${WORK_DIR}/tomcat.zip -d ${WORK_DIR}/
mv -v ${WORK_DIR}/apache-tomcat-${TOMCAT_VERSION} ${WORK_DIR}/tomcat

# Clean up included Tomcat web applications
rm -rvf ${WORK_DIR}/tomcat/webapps/docs
rm -rvf ${WORK_DIR}/tomcat/webapps/examples
rm -rvf ${WORK_DIR}/tomcat/webapps/host-manager
rm -rvf ${WORK_DIR}/tomcat/webapps/manager
rm -rvf ${WORK_DIR}/tomcat/webapps/ROOT

# Executable script permissions
chmod a+x ${WORK_DIR}/tomcat/bin/*.sh

# Copy Json2Ldap WAR and make it the root (/) application
cp -v ${WAR_FILE} ${WORK_DIR}/tomcat/webapps/ROOT.war

# Create ZIP package
cd ${WORK_DIR}
zip -r ${ZIP_FILE} tomcat
echo "Created $ZIP_FILE"

With the unzipped package Tomcat can be started with the following command on port 8080 (configured in tomcat/conf/server.xml):


To run it in the foreground:

tomcat/bin/catalina.sh run

Go to http://localhost:8080 to check the Json2Ldap banner page.

Why JSON-RPC 2.0?

JSON-RPC provided a clean path to keep the spirit of the original LDAP protocol. Moreover, its RPC messages can flow nicely through web sockets (on our road map).

Version 2.0 of JSON-RPC was chosen over 1.0 because it enables named parameters, improving API clarity and allowing us to add new request parameters in future without breaking backward compatibility. JSON-RPC 2.0 also has better error reporting.

Why not a RESTful web API?

REST was given serious consideration. In the end JSON-RPC was deemed more appropriate for Json2Ldap for two reasons:

  1. The objective of Json2Ldap was to mimic the nature of the original LDAP protocol as closely as possible, while using JSON to encode the messages.

  2. Utility functions such as ldap.util.isValidDN and ldap.util.normalizeDN do not fit well in the concept of REST.

How about DSML?

DSML is, well, what the acronym implies - it's dismal :-) The first version of this protocol was devised in 1999, but it didn't really pick up, and even the subsequent revision in 2001 wasn't particularly successful.

Using JSON to talk to directory servers over the web has significant advantages: In terms of format, JSON encoded messages are terse and easily consumed by JavaScript programs on the browser side. In terms of API, Json2Ldap keeps a close mapping to the LDAP protocol, so programmers who have previously worked with directories would feel immediately at home.

How does the Json2Ldap API compare to SCIM?

SCIM is a recent effort to provide RESTful access to identity data. Json2Ldap on the other hand offers a general purpose web API for working with any LDAP or virtual directory, and is not tied to a particular schema.

Cloud directory with Json2Ldap?

Json2Ldap can be fitted to any LDAP directory hosted in the cloud and web-enable it so that cloud-based or on-premise apps can conveniently work with identity data stored in it.

Why was the ldap.presetBind request removed from Json2Ldap in version 1.3?

The ldap.presetBind command was removed for the sake of simplicity. We realised that explaining the various security and configuration implications of this request was rather complicated, so we scrapped it from the Json2Ldap web API. Life should now be simpler for you and us too :)