-1

I have builded a Java server that listen on a port (6666). Now, i need to connect to this server with a LDAP Browser (I use Softerra). The connection is done, but i have to know when there is an LDAP bind/search, and i have no idea of how to do that.

Here is the code of my server (feel free to tell me if it's not very clear/good, i'm quite new to Java Prog.):

package net.nantes.littleldap;
import java.net.*;
import java.io.*;

public class Serverside {

    public static void main(String[] args) {
        ServerSocket socketserver  ;
        Socket socket ;
        BufferedReader in;
        PrintWriter out;

        try {
            Authenticate auth = new Authenticate();
            socketserver = new ServerSocket(6666);
            System.out.println("Le serveur est à l'écoute du port "+socketserver.getLocalPort());
            auth.connect();
            socket = socketserver.accept(); 
            String inputLine = new String();
            in = new BufferedReader(
                        new InputStreamReader(
                        socket.getInputStream()));
                System.out.println("Connecté au serveur");
                while ((inputLine = in.readLine()) != null){
                    System.out.println(inputLine);
                out = new PrintWriter(socket.getOutputStream());
                out.println("Connection réussie");
                out.flush();
                }
                socket.close();
                socketserver.close();

        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Sorry, the message are in french, but it's not really important. I think maybe I could do something with InputLine (when I print it, it returns some String relative to LDAP, but i can be hard to parse).

So, any idea ? Thanks a lot !

Roux
  • 293
  • 2
  • 17
  • What's going on here? Are you trying to write an LDAP proxy? – user207421 Sep 11 '12 at 23:22
  • In some words, i'm trying to re-create the behavior of a virtual directory (like Penrose). So yes, it's kind of a LDAP proxy :). – Roux Sep 12 '12 at 07:28
  • This is the same use case as mine: I allow other sub systems to authenticate employing our own authentication framework, which includes authenticating against the database and issuing LDAP (client) requests. I'm sure Penrose is doing a better job, though, it just was not an option for us, because we needed a simple embedded solution. – Matthias Wuttke Sep 12 '12 at 13:59
  • I'm writing a module for penrose too, but my boss asked me to prepare the two solution: Penrose or this "ldap proxy". – Roux Sep 12 '12 at 14:04

3 Answers3

1

I would strongly recommend you utilize either JNDI or one of the LDAP SDKs that are available. We like: https://www.unboundid.com/products/ldap-sdk/ -jim

jwilleke
  • 10,467
  • 1
  • 30
  • 51
0

Check out the UnboundID LDAP SDK and some sample code.

EDIT:

I would not recommend the use of JNDI:

  • JNDI uses a deprecated configuration
  • JNDI has software defects
  • JNDI does not fully support LDAP standards

see also

Terry Gardner
  • 10,957
  • 2
  • 28
  • 38
0

In addition to listening to the port, your server has to "understand" the LDAP protocol. I use the OpenDS LDAP SDK (http://www.middleware.vt.edu/pubs/opends-sdk-0.9.0/).

Code is like this

public class MyLdapServer 
implements ServerConnectionFactory<LDAPClientContext, Integer> {

private LDAPListener listener;

public void init() {
    try {
        listener = new LDAPListener(1389, this);
    } catch (IOException e) {
        logger.error("error opening LDAP listener", e);
    }
}

public void destroy() {
   listener.close();
}

@Override
public ServerConnection<Integer> handleAccept(LDAPClientContext context)
        throws ErrorResultException {
    if (logger.isDebugEnabled())
        logger.debug("ldap connection from: " + context.getPeerAddress());

    IncomingLdapConnection ilc = new IncomingLdapConnection(context);
    return ilc;
}

private static Logger logger = LoggerFactory.getLogger(MyLdapServer.class);

}

The IncomingLdapConnection allows you to handle the LDAP operations:

public class IncomingLdapConnection 
implements ServerConnection<Integer> {

    public void handleBind(Integer ctx, int version, BindRequest request,
        ResultHandler<? super BindResult> resultHandler,
        IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException {
    if (request.getAuthenticationType() != -128) {
        logger.warn("LDAP BIND: unsupported authentication type: " + request.getAuthenticationType());
        resultHandler.handleResult(Responses.newBindResult(ResultCode.AUTH_METHOD_NOT_SUPPORTED));
        return;
    }

    String bindName = request.getName();
    if (bindName.length() > 0) {
        if (request instanceof GenericBindRequest) {
            GenericBindRequest bindRequest = (GenericBindRequest)request;

            String userName = parseUidDn(bindName);
            if (userName == null) {
                // manche LDAP-Clients senden keine DN, sondern direkt den Namen
                userName = bindName;
            }

            String password = bindRequest.getAuthenticationValue().toString();

            logger.debug("LDAP BIND: non-anonymous bind, user = " + userName);
            anonymous = false;
        } else {
            logger.warn("LDAP BIND: non-anonymous bind, but unsupported request");
            resultHandler.handleResult(Responses.newBindResult(ResultCode.AUTH_METHOD_NOT_SUPPORTED));
            return;
        }
    } else {
        logger.debug("LDAP BIND: anonymous bind");
        anonymous = true;
    }

    boolean success = anonymous;
    if (!anonymous) {
        // authenticate user, set "success"
    }

    if (success)
        resultHandler.handleResult(Responses.newBindResult(ResultCode.SUCCESS));
    else
        resultHandler.handleResult(Responses.newBindResult(ResultCode.INVALID_CREDENTIALS));

    authenticated = success;
}

EDIT: OpenDS Code for answering to LDAP search requests

public void handleSearch(Integer ctx, SearchRequest request,
        SearchResultHandler responseHandler, IntermediateResponseHandler intermediateResponseHandler)
    throws UnsupportedOperationException {
    if (request.getScope() == SearchScope.BASE_OBJECT && request.getName().isRootDN()) {
        logger.debug("LDAP Search: BASE_OBJECT");
        responseHandler.handleEntry(Responses.newSearchResultEntry(rootEntry));
    } else {
        // do the search
        // parameters: request.getName(), request.getScope(), request.getFilter()
    }

    responseHandler.handleResult(Responses.newResult(ResultCode.SUCCESS));
}
Matthias Wuttke
  • 1,982
  • 2
  • 21
  • 38
  • Maybe OpenDJ or UnboundID LDAP SDK would be a better choice - see http://stackoverflow.com/questions/6260555/what-are-the-maven-2-coordinates-for-opends-sdk – Matthias Wuttke Sep 11 '12 at 16:15
  • In case you are interested, I can also provide sample code for LDAP search. – Matthias Wuttke Sep 11 '12 at 16:15
  • Thanks a lot Matthias, it helps me ! I'll check OpenDJ and UnboundID. And, yes, if you have the time, it would be great to show me the sample of LDAP search. Again, thanks ! – Roux Sep 12 '12 at 07:31
  • This is rather low level code. Maybe UnboundID gives you a higher-level API. I read about a in-memory directory. It really depends on your exact use case - I needed this low-level access. – Matthias Wuttke Sep 12 '12 at 13:55