LDAP Client

LDAP task is used to communicate with LDAP server and provides three functions ??? list/update/authenticate. List and update are for general purpose but authentication is only for user information. Because LDAP is mostly used for the authentication of users.

Input

AttributeDescription

Use SSL?

Secure communication with LDAP

Default value is no.

If SSL is enabled, ldaps:// is used.

SSL Factory

Custom SSL socket factory class

It is required when the communication with LDAP need to be secure but the certificate of the LDAP server is not valid

Host Name

LDAP Host

If SSL is enabled, use DNS name instead of ip address.

Port

LDAP Port

Default port for LDAP is 389 and 636 for LDAPS.

Base DN

Base DN for the connection

Base DN is the entry point to perform further operation.

ex) DC=active,DC=myldap,DC=com

Bind DN

User entry to access the target LDAP

Bind DN starts after the Base DN

ex)CN=Chris,CN=Users means CN=Chris,CN=Users, DC=active,DC=myldap,DC=com

Password

Password of BindDN

DataStructure Id

Data structure id for update operation

This id is used to generate input data through mapping

Input

Input parameter or data

If input data is generated through mapping or other data from previous tasks, use ## encloser.

ex)#MappingResult#

Target DN

Name to search or update

For update, this TargetDN is the target entry to be updated.

ex) CN=Chris,CN=Users

For list, this TargetDN is the parent DN where the search is started.

ex) CN=Users

Search Filter

Search filter.

Each filter consists of (attributename=attributevalue).

Use Data Structure?

Used to map the result of the list to the specific data structure.

Output

Output properties are the result of a task execution and assigned by the task.

Tasks with same type generates same result parameters. If a task is used more than once, the result data of the previously executed task will be overwritten by latter task.

You need to assign different names to avoid duplication.

AttributeDescription

ResultCount

List count

ResultRecord

The result of list operation

DataStructureId

Data structure id which will be used in mapping, if mapping exists.

Example

Authenticate

BindDN is the user who will be authenticated.

List

List operation requires TargetDN and Search Filter

Update

Input of Update operation can be acquired through mapping or from output of previous components.

Sample REST request

URL : http://localhost:8080/ api/ LDAPTest01/v1?__RoutingPath=update-v1

(*) __RoutingPath: list, authenticate, update-v1, update-v2

Request Header

Content-Type: application/json

X-Api-Key: 813ffe59f7ad9350

Request Body

{
    "request": {
      "telephoneNumber": "123456-v1"
    }
} 

Custom SSL Socket factory.

To use custom SSL socket factory, you have to implement your own SSLSocketFactory. Most of the reason you need a custom factory is the target LDAP server does not have valid certificate. The default java SSL implementation does not allow invalid certificate or incorrect host name/ip address which does not match the certificate. In that case, we need to avoid that limitation. The main purpose of the custom SSL socket factory is to make the target LDAP valid host.

There are three steps to make the invalid target LDAP valid.

· Implement custom SSL Socket Factory.

· Register host name and address to /etc/hosts file

· Register custom SSL socket factory to ISM.

You will implement a TrustManager which returns valid result for your target server in your SSLSocketFactory..

If no error is thrown from checkClientTrusted() and checkServerTruster(), JVM security manager treats the target host is valid.

ackage com.xnarum.plugins.ldap;

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LDAPSSLSocketFactory extends SSLSocketFactory {
	private static Logger logger = LoggerFactory.getLogger(LDAPSSLSocketFactory.class);

	private SSLSocketFactory ssf = null;
	
	public LDAPSSLSocketFactory() {
		logger.info( "Create SocketFactory class");
		getSSLSocketFactory();
	}
	
	private void getSSLSocketFactory() {
		TrustManager[] trustAllCerts = new TrustManager[] {
				new X509TrustManager() {

					public void checkClientTrusted(X509Certificate[] arg0, String arg1)
							throws CertificateException {
						// TODO Auto-generated method stub
						
					}

					public void checkServerTrusted(X509Certificate[] arg0, String arg1)
							throws CertificateException {
						// TODO Auto-generated method stub
						
					}

					public X509Certificate[] getAcceptedIssuers() {
						// TODO Auto-generated method stub
						return null;
					}
				}
		};
		try {
			SSLContext sc = SSLContext.getInstance("SSL");
			sc.init(null, trustAllCerts, new java.security.SecureRandom());
			ssf = sc.getSocketFactory();
			
		}catch( Exception ex ) {
			logger.error("Failed to create socket factory", ex);
		}
	}
	@Override
	public Socket createSocket(Socket s, String host, int port, boolean autoClose)
			throws IOException {
		// TODO Auto-generated method stub
		logger.debug( "Create socket #1" );
		return ssf.createSocket(s, host, port, autoClose);
	}

	@Override
	public String[] getDefaultCipherSuites() {
		// TODO Auto-generated method stub
		return ssf.getDefaultCipherSuites();
	}

	@Override
	public String[] getSupportedCipherSuites() {
		// TODO Auto-generated method stub
		return ssf.getSupportedCipherSuites();
	}

	@Override
	public Socket createSocket(String host, int port) throws IOException,
			UnknownHostException {
		// TODO Auto-generated method stub
		logger.debug( "Create socket #2" );
		return ssf.createSocket(host, port);
	}

	@Override
	public Socket createSocket(InetAddress addr, int port) throws IOException {
		// TODO Auto-generated method stub
		logger.debug( "Create socket #3" );
		return ssf.createSocket(addr, port);
	}

	@Override
	public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
			throws IOException, UnknownHostException {
		// TODO Auto-generated method stub
		logger.debug( "Create socket #4" );
		return ssf.createSocket(host, port, localHost, localPort);
	}

	@Override
	public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
		// TODO Auto-generated method stub
		logger.debug( "Create socket #5" );
		return ssf.createSocket(address, port, localAddress, localPort);
	}
	
	public static SocketFactory getDefault() {
		return new LDAPSSLSocketFactory();
	}

}

Deployment of custom SSL socket factory

Create a new module directory under wildfly-10.1.0.Final/modules/system/layers/base/com/ism/

$>mkdir -p ldap/main

Put your ssl factory implementation under main directory.

Create a file named module.xml under ldap/main directory and add these contents.

<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="com.ism.ldap">
    <resources>
        <resource-root path="your_ssl_factory.jar"/>
    </resources>
    <dependencies>
        <module name="javax.api"/>
        <module name="javaee.api"/>
        <module name="org.slf4j"/>
    </dependencies>
</module>

(*) This sample implementation uses slf4j, so slf4j dependency is added.

com.ism.ldap means the directory

Restart wildfly.

Last updated