Using data URIs with Json2Ldap

Json2Ldap iconPerson entries in a LDAP directory may contain photos. These are typically stored in a jpegPhoto attribute, defined in the standard inetOrgPerson schema. In this article I’ll show you how to display such JPEG images in the browser using Json2Ldap and a cool new HTML feature called data URIs.

Json2Ldap is a neat LDAP gateway software for web applications. It’s web API presents a set of JSON calls that JavaScript code running in a browser can address to access remote directory servers to perform tasks such as authenticating users, browsing their directory records, reading and updating attributes.

When Json2Ldap returns a directory entry it inspects the value of each attribute. If it is text, it passes it unmodified (save for escaping the special JSON chars). If the content is binary data, it encodes it into a Base64 string.

{ "DN" : "uid=alice,ou=people,dc=wonderland,dc=com",
  "cn"        : [ "Alice Wonderland" ],
  "mail"      : [ "alice@wonderland.net" ],
  "mobile"    : [ "+1 382 077 4180" ],
  "jpegPhoto" : [ "yugEMFjdQyRoxCP2KaZ041BUSctnUgY5TS7PBg==" ]
}

Your client JavaScript application will have no problems displaying the text attributes inside a web page. But how to render the JPEG image which was received as a Base64 string? What to do with it?

In the pre HTML 5 days you would have had to produce a physical JPEG URL from the received Base64 string, for example as by uploading it to a web server and then linking to it.

Fortunately, work-arounds such as this are no longer necessary. The solution is called Data URIs, a feature which was originally specified in 1998 and is now finally implemented by the latest crop of HTML 5 browsers.

How do data URIs work?

They provide an option for image data to be “in-lined” within the HTML page, instead only being able to link to it.

Here is a standard img element where the src attribute is a typical URL pointing to a file on the web server:

<img src="http://myapp.com/users/alice.jpg"/>

And here is an img with a data URI, where the image content is pasted directly into the src attribute. So when a data URI aware browser reads it, it will fetch the JPEG data from the in-lined Base64 string:

<img src="data:image/jpeg;base64,yugEMFjdQyRoxCP2KaZ041BUSctnUgY5TS7PBg=="/>

I don’t know why it took over 10 years to implement support for data URIs in browsers, but this is now a powerful technique for Ajax apps to render images on the web page which content was received through a XHR call.

Data URIs can naturally be applied to Ajax apps that interface to an LDAP directory through Json2Ldap. Rendering jpegPhoto attributes is then as simple as setting the src attribute of the desired image element to a data URI and then appending the Base64 content to it:

// We're using jQuery and the user directory entry 
// resides in the 'user' variable
$("#user-photo").attr("src", "data:image/jpeg;base64," + user.jpegPhoto[0]);

The online Json2Ldap demo makes use of inline images too. You can check it out at http://nimbusds.com/json2ldap-demo.html

The online Json2Ldap featuring data URIs for JPEG image rendering

Things to bear in mind:

While data URIs are supported by all major browsers today, some may impose a limit on the content size. IE 8 for example has a limit of 32 KB. So this technique may not work well for large images. For avatars and photos in user profiles, where 10 to 20KB are sufficient, it is going to be just fine.

CORS and HTTP 302 redirect responses

CORS Filter
Earlier this week a user of the CORS Filter library asked why his browser app wasn’t able to connect to his web service despite it having Cross-Origin Resource Sharing (CORS) enabled.

Investigation of the problem showed that his XHR was not landing on the CORS-enabled URL directly, but was being redirected to it through an HTTP 302 (redirect) response.

So bear in mind that the redirecting URL must also include an Access-Control-Allow-Origin header, else the browser will stop right there with its attempted cross-domain request.

For a quiet and cool workplace

I am at my most productive when I can clearly hear my thoughts. And this requires silence and a cool atmosphere. No fans humming, no power supplies buzzing, no discs clicking. Back in my home office in Bulgaria I took drastic measures to achieve that: I drilled a ø 4cm hole in the wall to the adjacent room and moved my PC case there. Then I got 5m USB and DVI extension cables to link the PC back to the monitor, keyboard and mouse on my desk. So all noisy and EMF emitting bits moved away and next door; the only things that remained on my desk were just the peripheral I/O devices.

The change in terms of silence and comfort were amazing! If you’re working many hours on the PC and would love to have an office atmosphere for utmost peace and concentration – this is the thing to do.

Here in London I now decided to reproduce the same arrangement. This time I took extra care in selecting a low power LCD monitor, as my old Philips screen was heating up quite a bit and its power supply was slightly humming. Samsung’s SyncMaster BX2250 is probably the best choice. It’s spec cites 18 Watts of operational power whereas 20″ to 25″ LCDs from other manufacturers typically consume at least twice as much – between 40 and 50 Watts. The plastic parts are also spec’ed as environmentally friendly, so thumbs up to Samsung for their green mindset and efforts.

Good, back to work now 🙂

Which LDAP servers support the Virtual List View (VLV) control?

Json2Ldap iconIf you’re making an LDAP search against a large directory you may potentially get a huge result set that you may rather wish to consume in chunks or “pages”. You may need this if you have a UI where results should be displayed, say, in portions of 10 or 20 at a time; also, if the LDAP server is configured with a max limit (typically in the order of 1000) on the number of entries a client may receive in a single search response.

To handle search results paging two LDAP extensions come to the rescue:

  • The Simple Paged Results control. It breaks the result set into pages of a specified size which the client fetches through a series of search requests. It is formally defined in RFC 2696. I have written an article in the past that lists the LDAP servers which support the Simple Paged Results control. This control is also supported by the Json2Ldap gateway / proxy as of version 1.7.
  • The Virtual List View control. It is the more featureful of the two as it allows clients to request an arbitrary “view” into the result set, by specifying a target offset, entry count, and even a “before” and “after” entry count. It is defined in an IETF Internet Draft, which for some reason still unknown to me hasn’t made it to standard status yet (as opposed to the Simple Paged Results control).

Note that the Virtual List View requires the results of the request to be sorted by a specified key on the server side using the Server Side Sort control (defined in RFC 2891). With the Simple Paged Results control sorting is optional.

The following screenshot, from the Json2Ldap online demo, shows an web app widget that uses the Simple Paged Result control.

LDAP search result chunking using the Simple Paged Result control

Here is a list of the directory servers that support the Virtual List View (VLV) control, in alphabetical order:

  • 389 Directory Server
  • IBM Tivoli Directory Server (since version 6.2)
  • Microsoft Active Directory (since Windows Server 2003)
  • Novell eDirectory (see note)
  • OpenDS / OpenDJ

Directory servers that don’t support the VLV control:

  • Apache DS
  • Oracle Internet Directory
  • OpenLDAP

The VLV control is perhaps not as widely supported by the various directory server vendors as the Simple Paged Results, but if you have an application that has to be able page up and down through the search results, it is indispensable.

Support for VLV in Json2Ldap from NimbusDS is planned for the next 1.10 release.

Easy LDAP user authentication over the web

NimbusDS AuthServiceAuthService is a simple web service software offered by Nimbus Directory Services. It can authenticate users against any LDAP directory using a web-friendly HTTP+JSON protocol.

Where to use?

AuthService can be used in any situation where you have to authenticate user credentials (login) over the web against an LDAP-compatible directory such as Microsoft Active Directory, Novell eDirectory or OpenLDAP.

  • You’re a SaaS provider and want to provide your corporate customers with a method for authenticating users against their internal directory.
  • Your company has applications in the cloud and wish them to use the corporate directory for user login.
  • You’re designing an Ajax app and want to authenticate users with a single JSON XHR. No redirection and page reloading, please!

How does it work?

AuthService is a nimble web service that sits in front of an LDAP directory and receives JSON-RPC request from web clients. It resolves the supplied usernames to valid directory entry entries (DNs) and translates between the binary LDAP protocol and HTTP/JSON.

AuthService authenticates users against an LDAP-compatible directory

The JSON request and response messages, what do they look like?

AuthService communicates with simple JSON messages. These follow the standard JSON-RPC 2.0 protocol.

Example user authentication request:

{ 
  "method"  : "user.auth",
  "params"  : { "username" : "alice@wonder.net",
                "password" : "s3cr3t" },
  "id"      : "0001",
  "jsonrpc" : "2.0" 
}

And here is an example response indicating the supplied username and password were correct:

{ 
  "result"  : true,
  "id"      : "0001",
  "jsonrpc" : "2.0"
}

The complete AuthService web API is documented online.

Can you retrieve a user’s details from the directory?

Yes! In addition to checking the user’s credentials you can also configure AuthService to return a selected set of user’s directory entry attributes on auth success. This is done via the authService.userAttributes configuration setting.

Here is a sample list of attributes that can typically be retrieved:

  • Given name, surname, full name.
  • Email address.
  • Office, home and mobile phone numbers.
  • Organisational details such as manager, department and authorisations / permissions.

Here is an example of such a JSON user auth response that returns selected user details:

{ "result"  : { "userID" : "alice",
                "name"   : "Alice Wonderland",
		"email"  : "alice@wonderland.net",
		"phone"  : "+44 711 567 8910" }
  "id"      : "0001",
  "jsonrpc" : "2.0"
}

Which directory servers is AuthService compatible with?

AuthService works with any LDAP v3 compatible directory. This includes Microsoft Active Directory, Novell eDirectory, IBM’s and Oracle’s directory services, the open source OpenLDAP, OpenDJ and ApacheDS servers.

What about installation?

AuthService is delivered as a standard Java servlet application, packaged as a WAR file and ready for immediate installation into any Java web server, such as the popular free Apache Tomcat or Jetty servers. The WAR file weighs a nimble 2.5 megabytes.

How about security?

AuthService includes a number of configuration settings for managing and protecting access to the service.

  • Whitelist of allowed client IPs / hostnames that may access the service.
  • Whether secure HTTPS is mandatory.
  • Whether clients are required to authenticate with a valid X.509 certificate issued by a trusted certificate authority (CA).
  • Whether the subject of the presented X.509 client certificate must match an authorised distinct name (DN).

What about price and support?

AuthService licenses come at a super affordable price. For immediate purchase and download check out the NimbusDS online shop. Attractive discounts are available if you with to distribute the software as part of your own product or SaaS offerings, for 100, thousand or even more copies.

NimbusDS, which operates out of London, UK and Bulgaria, also offers excellent integration and consulting services, with emphasis on LDAP directory design, meeting organisational objectives, web and cloud directory applications.

The NimbusDS line gets a speed boost

The Nimbus Directory Services product lineThe complete Nimbus Directory Services product line received a speed boost in June. The latest versions of Json2Ldap, JsonSSO and AuthService now feature a greatly improved JSON parser which speeds up decoding of incoming requests by impressive 380 per cent!

Thanks to Uriel Chemouni from the JSON Smart project for his top work!

What is next on the immediate NimbusDS roadmap?

So, expect more good news as we are heading into the summer. Here in London we had quite a promising start, warm and sunny!

How to use an LDAP directory for central listing and configuration of web services

Json2Ldap iconLDAP – compatible directories such as MS AD and OpenDJ are an excellent tool for bringing order and organising things. Businesses that make extensive use of web services may benefit from having all of them nicely listed and configured in a central location. A directory server can serve this purpose well, and with a gateway such as Json2Ldap, this can be done over the web too.

Basic web service listing

At a basic level, the directory may just list the available web services with their key usage details, such as their name, protocol and the URLs where web clients can access them.

The example below shows one such case where the services are listed under a directory branch named ou=Services,dc=NimbusDS,dc=com. Each entry is a webService class which supports attributes for storing a service’s name, URL, protocol and other detail. Directories allow their schema to be freely extended, so you can define your own class for your web services and the properties you wish to store.

Listing web services in an LDAP directory

The web services entries can be administered from the console or with LDAP GUI tools such as the excellent Apache Directory Studio.

Web service lookup

If you have a Json2Ldap instance installed the service listings may be queried by web clients, for example to dynamically look up the URL for a particular web service.

Here is a Json2Ldap ldap.getEntry request to obtain the URL of a TransactionCenter service:

{
  "method"  : "ldap.getEntry",
  "params"  : { "CID"        : "1f52b0c4-5d0d-4812-8688-8bf90b70eebf",
                "DN"         : "wsName=TransactionCenter,ou=Services,dc=NimbusDS,dc=com",
                "attributes" : "wsURL" },
  "id"      : "001",
  "jsonrpc" : "2.0"
}

The resulting JSON response:

{ "result" : { "DN"    : "wsName=TransactionCenter,ou=Services,dc=NimbusDS,dc=com",
               "wsURL" : [ "https:\/\/n1.cloudbase.net:8080\/tcenter\/"] },
  "id"      : "001",
  "jsonrpc" : "2.0" 
}

Centralised web service configuration

The administration of web services can be further centralised by storing their configuration variables in their own directory entries instead. In effect, this means projecting all configurations from your directory server. The web services would then only need to know the LDAP URL of the directory server and be provided with the appropriate credentials (username/password pair or X.509 certificate) to connect and authenticate to it.

If done on a consistent basis, having all configurations in a single place may greatly improve the manageability of your services and simplify the work of your IT administrators.

To accomplish this each web service must be provided with a set of credentials for accessing its configuration variables. ACLs may be judiciously used to limit read access to these attributes to the web service only and allow only the authorised administrator to edit them.

For the actual configuration variables, the LDAP protocol provides fair flexibility and allows storage of virtually arbitrary key/value pairs. As with the basic details example above, you can create your own schema for storing the configuration parameters of your particular web services.

Below is one such example for the TransactionCenter payment web service configuration. The directory entry contains attributes for configuring the back-end database connection as well as various variables pertaining to the web service itself.

Storing the web service configuration in its directory entry

In a future article I’ll share a few useful ideas how SaaS providers can utilise a central LDAP directory for managing subscriber accounts and multi-tenant app configurations.

OID registry for the Transaction Company

This page keeps track of the various OIDs in use by The Transaction Company.

The base OID of The Transaction Company is 1.3.6.1.4.1.31487. It was assigned by the IANA in July 2008.

  • 1.3.6.1.4.1.31487.1.* Web service directory schema
  • 1.3.6.1.4.1.31487.2.* TransactionCenter directory schema
  • 1.3.6.1.4.1.31487.3.* Secure Remote Password (SRP-6a) schema
  • 1.3.6.1.4.1.31487.4.* OpenID Connect 1.0, OP and RP schemas

JSON-RPC 2.0 Base flies with the new JSON library

JSON-RPC 2.0Two years after its initial release the JSON-RPC 2.0 Base library switches to a new package for representing and parsing JSON messages. The result is 2x to 4x times faster performance in JSON-RPC message parsing!

Back in 2009 I chose JSON Simple for its simple and relatively non-invasive model for representing and mapping JSON entities to Java primitives and objects. Performance was also relatively good against the alternatives, so JSON Simple became the natural choice for the JSON-RPC 2.0 Base classes. JSON Simple development became stale with time however, and more than 2 years passed without any new releases or fixes to reported bugs. This, I suspect, must have led to the user community becoming somewhat frustrated and a fork imminent.

A fork of JSON Simple did indeed arrive, in May this year, initiated by Uriel Chemouni and named JSON Smart. Initial tests showed considerable performance gains and after some email exchange with Uriel which resulted in the addition of strict JSON parsing, JSON Smart became the new library for JSON-RPC 2.0 Base.

So what do you gain with the new release?

JSON-RPC message parsing is sped up 2.4 times for the reusable JSONRPC2Parser and 3.8 times for the static parse methods.

Parse performance for JSON-RPC 2.0 messages

Moreover, the difference in terms of performance between the static parser and the instance parser is almost negligible, which means that for apps like servlets there is no need to pool parsers in order to speed up request processing.

Thanks for Uriel for making this great piece of software!

In the next few days Json2Ldap and the other products in the NimbusDS line will receive the new library, so expect more good news!