I wanted to share an example which can be used by a developer to integrated LDAP authorization with Sun Java System Directory Server into an application. The application, of course, can then be integrated into a SSO infrastructure such as Sun Java System Access Manager to bridge the gap between authentication, SSO, and application level authorization.

In order to provide a high performance connection to the LDAP server, a connection pool (ouside the scope of this posting) can be used and in order to enforce the LDAP aci's proxied authorization can be used. Since this is not a part of the standard jndi package, the JNDI/LDAP Booster Pack 1.0 can be used for this purpose. The Booster Pack includes a LDAP control, which when added to the jndi configuration will produce the desired behaviour. Description of the control: ProxiedAuthorizationControl - Performs the requested LDAP operation as the specified authorization identity

This is not new, this has been around for many years, but I wanted to share this as a technique to establish an authorization model in an application, then provide a way for SSO to pass the information necessary to enable the application to recognize the current user and enforce their privledges.

In order to test this, we first must setup the LDAP server and the ACI's which will be enforced:

Here is the ACI for a suffix named o=jolt:
dn: o=jolt
changetype: modify
replace: aci
aci: (targetattr = "cn || givenName || uid || TelephoneNumber || sn || givenname || mail || 
displayName || employeenumber ||  facsimilietelephonenumber || objectclass || 
destinationindicator || employeetype")(version 3.0;acl "JOLT Proxy (Anon)";allow 
(read,compare,search)(userdn = "ldap:///uid=joltadmin,ou=People, o=jolt");)

aci: (targetattr = "cn || givenName || uid || TelephoneNumber || sn || givenname || mail || 
displayName || employeenumber ||  facsimilietelephonenumber || objectclass ||  
facsimilietelephonenumber || mobile || homephone || destinationindicator || manager || 
physicaldeliveryofficename || roomnumber || postaladdress || postalcode || st ||street || 
entryid || l || ou || parentid") (version 3.0;acl "Authenticated users access";allow 
(read,search,compare)(userdn != "ldap:///uid=joltadmin, ou=People, o=jolt");)

aci: (targetattr = "givenName || uid || TelephoneNumber || sn || givenname || mail || 
displayName || employeenumber ||  facsimilietelephonenumber || mobile || homephone || 
objectclass || destinationindicator || manager || physicaldeliveryofficename || roomnumber || 
postaladdress || postalcode || st || street || entryid || l || ou || parentid") (targetfilter =
 (employeetype=*))(version 3.0;acl "Sales Group Access";allow (all)(groupdn = "ldap:///cn=Sales
 Group,ou=Groups,o=jolt");)

aci: (targetattr = "*") (version 3.0;acl "JOLTadmin Proxy rights";allow (proxy)(userdn = "ldap:///uid=joltadmin,ou=People,o=jolt");)

This ACI does a few things to demonstrate privledges to different users:
  • Proxy (Anon) - This is the default access level for the application which will use this proxy account (userdn = "ldap:///uid=joltadmin,ou=People, o=jolt"), attributes allowed: cn, uid, TelephoneNumber, sn, givenname, mail, displayName, employeenumber, facsimilietelephonenumber, objectclass, destinationindicator, employeetype
  • Allow the following user to proxy ldap requests for other users: userdn = "ldap:///uid=joltadmin,ou=People,o=jolt"
  • Authenticated users access - This is the ACI that will be enforced for authenticated users (through the proxy), attributes allowed: cn, uid, TelephoneNumber, sn, givenname, mail, displayName, employeenumber, facsimilietelephonenumber, objectclass, destinationindicator, employeetype, manager, physicaldeliveryofficename, roomnumber, postaladdress, postalcode, st, street, entryid, l, ou, parentid
  • Sales Group Access - allow even more access if the authenticated user is in the Sales Group, allowed attributes: mobile, homephone


Here is an example of using the command line ldapsearch to login as the user joltadmin, and proxy the request for Robert.Bailey. The -Y is used to identify the use to encorce the ACI's for:
ldapsearch -D uid=joltadmin,ou=People,o=jolt -w joltpassword -Y dn:uid=Robert.Bailey,ou=People,o=jolt -b o=jolt uid=Robert.Bailey
In the whitepages application, this will allow anonymous users (through the joltadmin connection pool) to access a limited set of attributes for users they are looking up.

User who are authenticated (and will be proxied through the joltadmin user) will also be able to view these ldap attributes for records they lookup: physicaldeliveryofficename, roomnumber, postaladdress, postalcode, st, street, entryid, l, ou, parentid

An users who are in the Sales Group (and will be proxied through the joltadmin user), will also be able to view these ldap attributes for records they lookup: mobile, homephone
This can be confirmed with a command line ldapsearch.

The Ldap Booster Pack includes a jar file: ldapbp.jar, which must be added to the classpath.

Here is an example of the relevant snippets of jndi code to test it.
     // specify jndi connection information
     Hashtable env = new Hashtable(11);
     env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
     env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=jolt");
     env.put(Context.SECURITY_PRINCIPAL, "uid=joltadmin,ou=people,o=jolt");
     env.put(Context.SECURITY_CREDENTIALS, "joltpassword");

     // create an initial context using the supplied environment properties
     LdapContext ctx = new InitialLdapContext(env, null);

     // activate the control
     ctx.setRequestControls(new Control[] { new ProxiedAuthorizationControl("dn:uid=chuck.boyle,ou=people,o=jolt")});

     // Ask for all attributes of the object
      Attributes attrs = ctx.getAttributes("uid=chuck.boyle, ou=People");
  

Now test the configuration to ensure that the Sun Directory ACI's are being enforced by editing the userdn in the ProxiedAuthorizationControl, and adding the user to the Sales group.

Finally, Single Sign on integration with Sun Java System Access Manager can be accomplished by configuring an Access Manager agent to protect the application (and configure Access Manager policies to allow users to access the application) and to insert an http header which is equal to the user dn that the application will extract and pass to the ldap request.

Comments:

Post a Comment:
Comments are closed for this entry.

This blog copyright 2009 by harcey