Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4409866

JNDI throws AuthenticationException on LDAP error code 13

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.4.0
    • 1.3.0
    • core-libs
    • beta
    • generic
    • generic



      Name: yyT116575 Date: 01/30/2001


      java version "1.3.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0)
      Java HotSpot(TM) Client VM (build 1.3.0, mixed mode)
      [also jsse1.0.2]

      Instructions:

      1. Edit the attached program. Change the values of baseDN and LDAPServer
         as necessary for your local environment. LDAPPort should be a port
         that accepts anonymous binds but not authenticated binds.

      2. Compile and run.

      Expected result would be that the authenticated bind:

          /* bind to the server */
          operation = "bind as principal \"" + principal + "\"";
          System.out.println(operation);
          ctx = new InitialDirContext(env);

      would fail with LDAP error code 13, "Confidentiality required",
      which would result in AuthenticationNotSupportedException. Instead,
      this results in AuthenticationException:

          authenticate("###@###.###", "foo")
          anonymous bind
          search for "(uid=###@###.###)"
          close anonymous connection
          authenticated bind ...
          bind as principal "emailaddress=###@###.###, ou=Employees,
          o=hp.com"
          bind as principal "emailaddress=###@###.###, ou=Employees,
          o=hp.com" failed: javax.naming.AuthenticationException: [LDAP: error
          code 13 - Authenticated binds are only allowed over SSL on port 636]
          returns: false

      The code needs to be able to distinguish these! LDAP error code 13 is
      an administrative error: the code should have used port 636, not 389.
      AuthenticationException is supposed to mean "Invalid credentials",
      that is, the wrong password.

      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cut here ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

      import java.util.Hashtable;
      import java.util.Enumeration;
      import javax.naming.*;
      import javax.naming.directory.*;

      /**
       * Implements LDAP authentication.
       * If SSL is enabled then a Java secure socket implementation
       * (like JSSE) needs to be installed in the JVM.
       */

      class LDAPAuthenticationProvider
      {
          /** The distinguished name under which to search for a user name */
          private String baseDN = "ou=Employees, o=hp.com";

          /** The attribute name that stores the user name */
          private String uidAttr = "uid";

          /** The host name of the LDAP server */
          private String LDAPServer = "ldap.hp.com";

          /** Should we use an SSL connection to the LDAP server */
          private boolean useSSL = false;

          /** The port number of the LDAP server. If useSSL is true,
           * this must be the port for SSL connections to the LDAP server
           */
          private String LDAPPort = "389";

          /** What kind of LDAP authentication to use */
          private String authType = "simple";


          public boolean authenticate(String userName, String password)
                  throws Exception
          {
              System.out.println("authenticate(\"" + userName + "\", \"" + password +
                      "\")");

              Hashtable env = new Hashtable(5, 0.75f);
              env.put(Context.INITIAL_CONTEXT_FACTORY,
                      "com.sun.jndi.ldap.LdapCtxFactory");

              /* Specify host and port to use for directory service */
              env.put(Context.PROVIDER_URL, "ldap://" + LDAPServer + ":" + LDAPPort);
              if (useSSL) {
                  env.put(Context.SECURITY_PROTOCOL, "ssl");
              }

              String operation = null;
              DirContext ctx = null;
              SearchResult sr = null;

              try {
                  /* get a handle to an Initial DirContext */
                  operation = "anonymous bind";
                  System.out.println(operation);
                  ctx = new InitialDirContext(env);

                  /* specify search constraints to search subtree */
                  operation = "search ...";
                  SearchControls constraints = new SearchControls();
                  constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);

                  /* search for all entries with the uid */
                  String target = "(" + uidAttr + "=" + userName +")";
                  operation = "search for \"" + target + "\"";
                  System.out.println(operation);
                  NamingEnumeration results
                          = ctx.search(baseDN, target, constraints);

                  operation = "close anonymous connection";
                  System.out.println(operation);
                  ctx.close();

                  if ((results == null) || (!results.hasMore()) ||
                          ((sr = (SearchResult) results.next()) == null)) {
                      System.out.println("uid not found");
                      return false;
                  }
                  if (results.hasMore()) {
                      System.out.println(
                              "multiple search results for uid");
                      return false;
                  }
              }
              catch (InvalidSearchFilterException e) {
                  String message = operation + " failed: " + e.toString();
                  System.out.println(message);
                  return false;
              }
              catch (NamingException e) {
                  String message = operation + " failed: " + e.toString();
                  System.out.println(message);
                  throw(new Exception(message));
              }
              catch (Exception e) {
                  String message = operation + " failed: " + e.toString();
                  System.out.println(message);
                  throw(new Exception(message));
              }


              try {
                  /* prepare to do authenticated bind */
                  operation = "authenticated bind ...";
                  System.out.println(operation);
                  env.put(Context.SECURITY_AUTHENTICATION, authType);
                  String principal = sr.getName() + ", " + baseDN;
                  env.put(Context.SECURITY_PRINCIPAL, principal);
                  env.put(Context.SECURITY_CREDENTIALS, password);

                  /* bind to the server */
                  operation = "bind as principal \"" + principal + "\"";
                  System.out.println(operation);
                  ctx = new InitialDirContext(env);

                  operation = "close authenticated connection";
                  System.out.println(operation);
                  ctx.close();
              }
              catch (AuthenticationException e) {
                  System.out.println(operation + " failed: " + e.toString());
                  return false;
              }
              catch (NamingException e) {
                  String message = operation + " failed: " + e.toString();
                  System.out.println(message);
                  throw(new Exception(message));
              }
              catch (Exception e) {
                  String message = operation + " failed: " + e.toString();
                  System.out.println(message);
                  throw(new Exception(message));
              }

              return true;
          }

          public static void main(String args[])
          {
              LDAPAuthenticationProvider ap = new LDAPAuthenticationProvider();
              boolean result;

              try {
                  result = ap.authenticate(args[0], args[1]);
                  System.out.println("returns: " + result);
              }
              catch (Exception e) {
                  System.out.println("caught exception: " + e.toString());
              }
          }
      }
      (Review ID: 116055)
      ======================================================================

            vinnie Vincent Ryan
            yyoungsunw Yung-ching Young (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: