Directory Service Plugin - Reference Documentation
Authors: Lucas Rockwell
Version: 0.5.0
1 Introduction
Overview
DirectoryService is a Grails plugin that allows you to interact with a v3-compliant LDAP server with minimal effort. It is built on top of the UnboundID LDAP SDK.DirectoryService is inspired by GORM, but since this is LDAP, we really can only go as far as inspired, because there is no "R" (relational) in LDAP. Unlike a database, LDAP does not really have a structure (well, there is the DIT, but that is about it), so it does not seem reasonable or necessary to make concrete classes to represent LDAP objects. As you read more about this plugin, and start to use it, you will realize why concrete classes are unnecessary.Furthermore, you can use Command Objects for your logic for your directory objects, i.e., you don't need to put them into a class that is specific to a tree in LDAP. (At least that is how I feel about this now, and Command Objects are just as powerful as Domain Objects.)As mentioned above, DirectoryService is built on top of the UnboundID LDAP SDK, and therefore, that SDK is exposed through this plugin. However, it is best if you try to use the methods provided by the plugin as much as possible, as the SDK API may change. That is, we try to encapsulate the basic functionality that you need, but if you really need something you can go under the covers. Also, feel free to open an Enhancement Issue on GitHub.This plugin assumes you have working knowledge of LDAP. If you need to get familiar with LDAP, please see the Resources section.
2 History
- Pre-release 0.1.0
- July 2012
- Beta-release 0.5.0
- August 2012
3 Installation
Overview
This section describes how to install theDirectoryService
plugin.Install Plugin
TheDirectoryService
plugin is installed like any other plugin. It can be added to BuildConfig.groovy
like so:plugins { compile ':directory-service:0.5.0' }
grails install-plugin directory-service
4 Configuration
Overview
This section describes how to configure theDirectoryService
plugin.Define The DIT
Instead of crawling your LDAP directory,DirectoryService
expects you to give it some hints about how your server is set up. Once you configure the plugin, it will become obvious to you how it works.Since the DIT definition is a Map, you must put it in a .groovy
file. The easiest place to put it is in Config.groovy
, but you can put it into any config file you have defined.For this example, we are going to assume that our LDAP tree has three branches that we are interested in mapping:ou=people,dc=someu,dc=edu ou=departments,dc=someu,dc=edu ou=groups,dc=someu,dc=edu
DirectoryService
about these branches, including the singular and plural names of the objects in those branches, the RDN attribute for the objects in those branches, and the source, i.e., what server contains this information.The above branches would be defined in the directoryService.dit
as follows:grails.plugins.directoryservice.dit = [ 'ou=people,dc=someu,dc=edu':[ 'singular':'person', 'plural':'people', 'rdnAttribute':'uid', 'source':'directory' ], 'ou=departments,dc=someu,dc=edu':[ 'singular':'department', 'plural':'departments', 'rdnAttribute':'ou', 'source':'directory' ], 'ou=groups,dc=someu,dc=edu':[ 'singluar':'group', 'plural':'groups', 'rdnAttribute':'uid', 'source':'directory' ] ]
Attribute | Meaning | Notes/Example |
---|---|---|
singular | The singular spelling for the name of the tree. | This does not have to match the name in the DN. |
plural | The plural spelling for the name of the tree. | This does not have to even be the plural version of singular, but you probably what to keep these things consistent for your own sanity. |
rdnAttribute | This is the attribute which makes up the RDN of the entry. | If the DN of a person is uid=125236,ou=people,dc=someu,dc=edu , then the rdnAttribute would be "uid". If the DN of a person is cn=Rockwell, Lucas,ou=people,dc=someu,dc=edu , then the rdnAttribute would be "cn". This must be the real RDN attribute, i.e., you can't make this up. |
source | This is the source | This points to an entry in grails.plugins.directoryservice.sources . |
One Branch, Multiple Objects
Store more than one object type in the same branch? No problem! Map keys are case sensitive, so you can define multiple objects in the same branch by changing the case of at least one character in the dn. For example, let's say you have both people and accounts in the "people" branch (don't know why you would, but let's just say you do), and the rdnAttribute of people is "uid", and the rdnAttribute of accounts is "cn":grails.plugins.directoryservice.dit = [ 'ou=people,dc=someu,dc=edu':[ singular: 'person', plural: 'people', rdnAttribute: 'uid', source: 'directory' ], 'ou=People,dc=someu,dc=edu':[ singular: 'account', plural: 'accounts', rdnAttribute: 'cn', source: 'directory' ] ]
Define Sources
In thedit
definition above, there is an attribute named "source". This points to a directory server configured in grails.plugins.directoryservice.sources
. For instance:grails.plugins.directoryservice.sources = [ 'directory':[ address: 'server1,server2', port: '636,636', useSSL: true, trustSSLCert: true, followReferrals: true, bindDN: 'cn=Directory Manager', bindPassword: 'password' ] ]
More Examples
For more examples of how to configure the dit and sources, see theConfig.groovy
file in the main project: .
5 Usage
Overview
As noted in the Introduction,DirectoryService
is inspired by GORM. Therefore, the methods should be intuitive. This section gives you a brief overview, but please see the Reference Guide for details of each method.How it Works
For more in-depth details of howDirectoryService
works, please see the other sections of this guide, including the ref:DirectoryService pages.Add DirectoryService to your class
Once you haveDirectoryService
configured, you can add it to a class the way you would any other service:def directoryService
Search for an object
Now you can search for something in your directory (again, see the Configuration section) like this:def people = directoryService.findPeopleWhere('departmentNumber':'12345', 'manager':'3786258')
DirectoryServiceEntry
objects. A DirectoryServiceEntry
object is a wrapper around an UnboundID Entry
object, so everything you can do with an Entry
object is available to you.Use the results
Once you perform a search, you can then use the object the way you would use a GORM object:people.each { person ->
println "${person.displayName}, ${person.telephoneNumber}"
}
telephoneNumber
defined in their entry? Nothing! The attribute doesn't exist, it doesn't print anything. This is possible because DirectoryService
is based on the UnboundID LDAP SDK, and that SDK allows you to ask for attribute values on attributes that do not exist in the entry, with no ill effects, i.e., no exceptions are thrown. However, the call does return null
if there is no attribute with the provided name, so it is best to use the "?" operator if you plan to do something with the value, if that something you plan to do does not like null
objects.To see how the UnboundID LDAP SDK is being used here, the above person.displayName
could also be accomplished with the following:person.getEntry().getAttributeValue("displayName")
getAttributeValue
, so if you want the attribute values, then you would have to use the special Values()
method:person.cnValues()
Operations Implemented
As of the current release,find
(search
), and save
(modify
) are implemented. add
and delete
will be added in upcoming releases. See the roadmap for details.
6 Roadmap
Overview
This page outlines what to expect in future releases of theDirectoryService
plugin. If you have a feature request/enhancement, please create an "Issue" on GitHub and label it an enhancement: .Summer 2012
This summer I hope I can include the ability toadd
, along with JSON and XML output for the DirectoryServiceEntry
object.Fall 2012
By Fall I hope to implementfind*By*
methods, for instance, findPeopleBySnAndGivenName
, and findPeopleBySnLike
, etc.
7 Resources
Overview
The DirectoryService Plugin is for interacting with an LDAP directory. If you are not familiar with LDAP, please read the Wikipedia LDAP page for starters.API Docs
UnboundID LDAP SDK Docs
The DirectoryService plugin is based on the UnboundID LDAP SDK.The UnboundID LDAP SDK is very powerful, and of course DirectoryService only uses a fraction of what it has to offer. However, we have tried to encapsulate in DirectoryService what the kinds of activities you would do with a directory most of the time, so if at all possible, try to avoid using the underlying UnboundID API because if it changes, then you will have to change your code, as well, and it will be up to you to keep up with any changes.