# 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.

&#x20;

## **Input**

&#x20;

<table><thead><tr><th width="181">Attribute</th><th>Description</th></tr></thead><tbody><tr><td>Use SSL?</td><td><p>Secure communication with LDAP</p><p>Default value is no.</p><p>If SSL is enabled, ldaps:// is used.</p></td></tr><tr><td>SSL Factory</td><td><p>Custom SSL socket factory class</p><p>It is required when the communication with LDAP need to be secure but the certificate of the LDAP server is not valid</p></td></tr><tr><td>Host Name</td><td><p>LDAP Host</p><p>If SSL is enabled, use DNS name instead of ip address.</p></td></tr><tr><td>Port</td><td><p>LDAP Port</p><p>Default port for LDAP is 389 and 636 for LDAPS.</p></td></tr><tr><td>Base DN</td><td><p>Base DN for the connection</p><p>Base DN is the entry point to perform further operation.</p><p>ex) DC=active,DC=myldap,DC=com</p></td></tr><tr><td>Bind DN</td><td><p>User entry to access the target LDAP</p><p>Bind DN starts after the Base DN</p><p>ex)CN=Chris,CN=Users means CN=Chris,CN=Users, DC=active,DC=myldap,DC=com</p></td></tr><tr><td>Password</td><td>Password of BindDN</td></tr><tr><td>DataStructure Id</td><td><p>Data structure id for update operation</p><p>This id is used to generate input data through mapping</p></td></tr><tr><td>Input</td><td><p>Input parameter or data</p><p>If input data is generated through mapping or other data from previous tasks, use ## encloser.</p><p>ex)#MappingResult#</p></td></tr><tr><td>Target DN</td><td><p>Name to search or update</p><p>For update, this TargetDN is the target entry to be updated.</p><p>ex) CN=Chris,CN=Users</p><p>For list, this TargetDN is the parent DN where the search is started.</p><p>ex) CN=Users</p></td></tr><tr><td>Search Filter</td><td><p>Search filter.</p><p>Each filter consists of (attributename=attributevalue).</p></td></tr><tr><td>Use Data Structure?</td><td>Used to map the result of the list to the specific data structure.</td></tr></tbody></table>

&#x20;

## **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.

<table><thead><tr><th width="203">Attribute</th><th>Description</th></tr></thead><tbody><tr><td>ResultCount</td><td>List count</td></tr><tr><td>ResultRecord</td><td>The result of list operation</td></tr><tr><td>DataStructureId</td><td>Data structure id which will be used in mapping, if mapping exists.</td></tr></tbody></table>

&#x20;

## **Example**

&#x20;

![](https://support.xnarum.com/download/manuals/ISM-Manual-2023.fld/image330.png)

### **Authenticate**

BindDN is the user who will be authenticated.

![](https://support.xnarum.com/download/manuals/ISM-Manual-2023.fld/image331.png)

### **List**

List operation requires TargetDN and Search Filter

![](https://support.xnarum.com/download/manuals/ISM-Manual-2023.fld/image332.png)

&#x20;

### **Update**

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

![](https://support.xnarum.com/download/manuals/ISM-Manual-2023.fld/image333.png)

&#x20;

### **Sample REST request**

URL : [http://localhost:8080/ api/ LDAPTest01/v1](http://localhost:8080/%20api/%20LDAPTest01/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();
	}

}
```

&#x20;

#### 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.
