Showing posts with label ldap. Show all posts
Showing posts with label ldap. Show all posts

November 19, 2016

LDAP User Authentication

What is LDAP and LDAP Authentication ?

To get started on what and how LDAP works, take a look at [1].

Quoting from the above article, following is about how LDAP Authentication works :
To perform any of these LDAP operations, an LDAP client needs to establish a connection with an LDAP server. The LDAP protocol specifies the use of TCP/IP port number 389, although servers may run on other ports.
The LDAP protocol also defines a simple method for authentication. LDAP servers can be set up to restrict permissions to the directory. Before an LDAP client can perform an operation on an LDAP server, the client must authenticate itself to the server by supplying a distinguished name and password. If the user identified by the distinguished name does not have permission to perform the operation, the server does not execute the operation.
In order write a simple LDAP Authenticator using Java, refer to the article [2] first to get an idea.

As per the above quote and explanations, in order to perform an LDAP based user authentication, we validate the user's permission by trying to execute an operation on LDAP.

Java LDAP Authenticator

import javax.naming.Context;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import java.util.Hashtable;
/**
 * Open a connection to the LDAP server with uid and password and authenticate the user.
 */
public class LDAPAuthenticator {
    private static String UID_FORMAT_STRING = "uid=%1s,%2s";
    private static String VDS_SERVER = "LDAPS://localhost:389";
    private static final String PEOPLE_OU = "ou=people,dc=local,dc=com";
    public static void main(String[] args) {
        Hashtable<String, String> authEnv = new Hashtable<String, String>();
        authEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        authEnv.put(Context.PROVIDER_URL, VDS_SERVER);
        authEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); //default authentication
        authEnv.put(Context.SECURITY_PRINCIPAL, String.format(UID_FORMAT_STRING, "uidName", PEOPLE_OU));
        authEnv.put(Context.SECURITY_CREDENTIALS, "password");
        try {
            DirContext ctx = new InitialDirContext(authEnv);
            ctx.close();
            System.out.println("User Authentication Successful");
        } catch (Exception e) {
            System.out.println("User Authentication Failed");
            e.printStackTrace();
        }
    }
}

In addition if you need perform attribute matching along with authentication use the following code as an example :

Attributes matchAttrs = new BasicAttributes(true); // ignore attribute name case
matchAttrs.put(new BasicAttribute("uid", "AARSupport"));

// Search for objects with those matching attributes
NamingEnumeration answer = ctx.search(PEOPLE_OU, matchAttrs);

WSO2 LDAP Connector

If you are using WSO2 ESB, you can use the WSO2 LDAP connector to perform LDAP authentication. You can download the connector from [6]. Documentation on using the LDAP connector for authentication can be found at [7].

Use the following configurations to call the Authenticate operation.

Create a local entry with authentication details as below.

<ldap.init xmlns="http://ws.apache.org/ns/synapse">
      <providerurl>LDAPS://localhost:389</providerurl>
      <securityprincipal>uid=UIDName,ou=people,dc=local,dc=com</securityprincipal>
      <securitycredentials>password</securitycredentials>
      <secureconnection>false</secureconnection>
      <disablesslcertificatechecking>false</disablesslcertificatechecking>
</ldap.init>


Or you can also create local entry as below without authentication details since they are again later provided at the authenticate operation.

<ldap.init xmlns="http://ws.apache.org/ns/synapse">
      <providerurl>LDAPS://localhost:389</providerurl>
      <securityprincipal></securityprincipal>
      <securitycredentials></securitycredentials>
      <secureconnection>false</secureconnection>
      <disablesslcertificatechecking>false</disablesslcertificatechecking>
</ldap.init>

In the mediation, you can call the LDAP connector's authenticate operation to perform authentication.

<ldap.authenticate configkey="LDAPConfig">
        <dn>uid=UIDName,ou=people,dc=local,dc=com</dn>
        <password>password</password>
</ldap.authenticate>


If the authentication is successful, you would be getting a Success response back.

References : 

  1. https://docs.oracle.com/cd/E19957-01/816-6402-10/ldap.htm
  2. http://docs.oracle.com/javase/jndi/tutorial/ldap/security/ldap.html
  3. https://tools.ietf.org/html/rfc4519#section-2.39
  4. http://stackoverflow.com/questions/2522770/how-to-check-user-password-in-ldap-whith-java-with-given-ldapcontext
  5. http://stackoverflow.com/questions/7813868/whats-the-difference-in-using-distinguished-name-with-cn-or-uid-when-logging-in
  6. https://store.wso2.com/store/assets/esbconnector/details/4ecf8dde-60f3-4e91-ba22-5f49a4e302f4
  7. https://docs.wso2.com/display/ESBCONNECTORS/Working+with+User+Authentication+in+LDAP