October 11, 2005

Confluence & LDAP

I struggled with an Active Directory LDAP integration to Confluence for a couple of hours. I had previously written my own LDAP integration class, so I new the integration could work. Fundamentally, my problem was that AD required authentication to read an entry. But I work in a large company with a "challenged" IT department, and to ask them to setup a read-only account for this kind of thing takes years. So, thankfully, Confluence uses the OSUser libraries. Because that's open source, it was easy to extend the LDAPGredentiallsProvider to work in my IT environment. I then created an osuser_addon.jar and placed it in the Confluence lib directory, modified osuser.xml, and all was working. The class is below:
public class AiLDAPCredentialsProvider extends LDAPCredentialsProvider {

	private static final long serialVersionUID = 1L;

	String userSuffix;
	String myProviderName;
	
	public boolean init(java.util.Properties properties) {
		boolean ret = super.init(properties);
		
		userSuffix = properties
                     .getProperty("userSuffix").toString();
		myProviderName = properties
                     .getProperty("java.naming.provider.url").toString();
		System.out.println("init is " + ret);
		return ret;
	}

	public boolean authenticate(java.lang.String username, 
                              java.lang.String password) {
		if ((password == null) || "".equals(password)) {
            return false;
        }
		
		Hashtable localEnv = new Hashtable();
		
		//should be "com.sun.jndi.ldap.LdapCtxFactory"
		//url + "/" + dcSuffix
		String url = myProviderName + "/" + searchBase;
		localEnv.put(Context.INITIAL_CONTEXT_FACTORY,
                       "com.sun.jndi.ldap.LdapCtxFactory");
		localEnv.put(Context.PROVIDER_URL, url);
		localEnv.put(Context.SECURITY_PRINCIPAL, username +
                       userSuffix);
		localEnv.put(Context.SECURITY_CREDENTIALS, password);

		System.out.println("url = " + url);
		System.out.println(username + userSuffix);
		
		try {
			DirContext ctx = new InitialDirContext(localEnv);
			ctx.close();
			
			return true;
		} catch (CommunicationException e) {
			System.out.println(e);
			return false;
		} catch (NamingException e) {
			System.out.println(e);
			return false;
		}

	}
}

Posted by rob at October 11, 2005 11:15 AM