Altering the Dspace 1.4.2 behaviour

What we need

Current version of Dspace installed on our Web Server works perfectly well, but we are in need of adding some new functionalities to the LDAP Auth mechanism implemented in. In our particular case, it’s necessary to allow users “white-list” and, at the same time, to implement one extra check so as to grant access to a some valid LDAP authenticated user depending on some extended attributes of our LDAP institutional servers.

Implementing the concept of “users white-list” through the LDAP Authtentication mechanism

Dspace is entirely written in Java and JScript. Our source code file involving LDAP Authentication behaviour is src/org/dspace/app/webui/servlet/ Reading this file carefully, we can found a method called ldapAuthenticate(), in charge of connecting to the LDAP servers configured in DSpace, and validating the user. The idea is so simple: in case of being connected to the LDAP tree structure, it’s supossed the user has valid credentials so that he can be entering inside Dspace webpage, returning a “true” value inside this method. Otherwise, this method will return “false”, and the access will be denied to the user.

Thus, we needed to add some code right inside this method, just after passing the LDAP binding process correctly, in order to open an external file – our white-list configuration file, in fact -, and iterate over all its entries, looking for the validated user through LDAP tree. In case of finding this user in the white-list file, we return true. Otherwise, we can go on with the last part of authentication mechanism, that is: checking for an additional LDAP attributes. In our case, the “unitCode” field, see below.

All the code added in order to implement the white-list is shown below:

65 // TCG: add support for FileReader
66 import*;
82     // TCG: the white-file-list:
83     private static final String WHITE_FILE_LIST = "/etc/dspace-white-list.cfg";
376     //TCG: check white-list :
378                  "TCG: ldap_white_list_check", "type=white-list, got=" + netid));
379     try{
381         boolean found = false;      /* By default, not found */
382         String curEntry="";         /* current user in white-list */
384         // Okay guys, in case of the presence of a white-list-file ... :
385         BufferedReader fl = new BufferedReader(new FileReader(WHITE_FILE_LIST));
386         /* Look for its name ... */
388             "TCG: ldap_white_list_opened", "type=white-list, status=opened"));
389         do{
390             curEntry = fl.readLine();
391   ,
392                 "TCG: ldap_white_list_loop", "type=search,value=" + curEntry ));
393             if(curEntry!=null && netid.compareTo(curEntry)==0){
394                 found=true;
395       ,
396                           "TCG: ldap_white_list_search", "type=white-list, status=found_white_entry, value=    " + curEntry));
397                 break;
398             }
399         }while(curEntry!=null);
400         fl.close(); /* Close the file ... */
401         if(found)return true;   /* Avoid ldap unitcode check if we've found in the white-list ...

As shown in the previous code listing, we hard-coded the filename directly, but it is absolutelly feasible to add some code so as to use a Dspace config directive to choose the path and the name of this file, which could be better than hardcoding it inside this source code file.

Checking an additional LDAP attribute before granting access to the user

In our particular case, we were in need of allowing the access to a valid linked user to the LDAP tree only if he belongs to some numerical codes for the extended LDAP attribute unitCode. This way, the access will be granted or denied, depending on this attribute. In short:

(unitCode = { 720, 721 }) ? Granted : Denied

So as to do so, I added some code in order to get this custom LDAP attribute inside the ldapAuthenticate() method, and then, right after passing the loop inside “white-list” mechanism, a trivial if clause determines if the user belongs to these numerical codes, allowing or denying the access. This code is shown below:

295         // TCG: Read new option in config file por unitCode field:
296         String ldap_unitCode_field = ConfigurationManager.getProperty("ldap.unitCode_field");
301         //TCG: need unitCode field for matching ! ?
302        matchAttrs.put(new BasicAttribute(ldap_unitCode_field));
304         // TCG: Add new field to receive after query from ldap server:
305        String attlist[] = {ldap_email_field, ldap_givenname_field, ldap_surname_field, ldap_phone_    field, ldap_unitCode_field};
341             // TCG: get the unitCode attribute and store it!
342                         if (attlist[4]!=null)
343                         {
344                             att = atts.get(attlist[4]);
345                             if (att != null) ldapunitCode = (String)att.get();
346                         }
403         // User not found in white-list ... :
405             "TCG: ldap_white_list_search", "type=white-list, status=not_found_white_entry, looking_for=" +     netid));
407         // Check the unitCode, if needed :
408   ,
409                      "TCG: ldap_attribute_check", "type=unitCode, got=" + ldapunitCode));
410         Integer icode = new Integer(ldapunitCode);
411         if(icode.intValue()<720||icode.intValue()>721) return false;

And that’s all.

Applying the changes, compiling and installing the modified Dspace server

It’s a piece of cake. Recompile the sources, copy two files and restart the TOMCAT server:

# ant clean
# ant update
# /etc/init.d/tomcat5 stop
# rm -r /usr/share/tomcat5/webapps/dspace
# rm -r /usr/share/tomcat5/webapps/dspace-oai
# cp build/* /usr/share/tomcat5/webapps
# /etc/init.d/tomcat5 start

Finally, create a new white-list file and add all users desired by hand:

# touch /etc/dspace-white-list.cfg
# echo "user_name.user_surname" >>  /etc/dspace-white-list.cfg
# echo "new_user.ldap" >> /etc/dspace-white-list.cfg