Tuesday, September 20, 2011

LDAP/AD user password check

Simple algorithm.


  1. connect to ldap;
  2. auth with "super"-user (user1): special user with known DN and password;
  3. search another user (user2): user who must be tested, search him with some attribute (for example sAMAccountName);
  4. determine DN of user;
  5. open one more connection to ldap with just found DN and password of user2;
  6. no exception - ok, otherwise user2 has entered wrong password.
My code:

/**
 * Returns {@link Item} with addition information in case of user exists and authicated correctly, otherwise null
 * @param username username
 * @param password password
 * @return Item or null
 */
private Item checkWithLdap(String username, String password) {
    String ldap = CXConfiguration.getParameterAsString("LDAP_SERVER");
    if ((ldap != null) && !ldap.isEmpty()) {
        DirContext ctx = null;
        try {
            int port = CXConfiguration.getParameterAsInt("LDAP_SERVER");
            String ldapUrl = "ldap://" + ldap + ":" + port;
            Logger.info("checking with ldap [username: " +
                    username + ", password: ******, ldap: " +
                    ldapUrl + "]");
            Properties env = new Properties();
            env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
            env.put(Context.PROVIDER_URL, ldapUrl);
            env.put(Context.SECURITY_AUTHENTICATION, "simple");
            env.put(
                    Context.SECURITY_PRINCIPAL,
                    CXConfiguration.getParameterAsString("LDAP_AUTH_DN")
            );
            env.put(
                    Context.SECURITY_CREDENTIALS,
                    CXConfiguration.getParameterAsString("LDAP_AUTH_PASSWORD")
            );
            ctx = new InitialDirContext(env);
            String base = CXConfiguration.getParameterAsString("LDAP_BASE_DN");
            String[] attributeFilter = {
                    CXConfiguration.getParameterAsString("LDAP_USER_SEARCH_ATTR"),
                    "distinguishedName",
                    CXConfiguration.getParameterAsString("LDAP_EMAIL_ATTR")
            };
            SearchControls sc = new SearchControls();
            sc.setReturningAttributes(attributeFilter);
            sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
            String filter = "(" +
                    CXConfiguration.getParameterAsString("LDAP_USER_SEARCH_ATTR") +
                    "=" + username + ")";
            NamingEnumeration<SearchResult> results = ctx.search(base, filter, sc);
            if (results.hasMore()) {
                Properties env1 = new Properties();
                env1.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
                env1.put(Context.PROVIDER_URL, ldapUrl);
                SearchResult result = (SearchResult) results.next();
                Attributes attrs = result.getAttributes();
                Attribute dnAttr = attrs.get("distinguishedName");
                String dn = (String) dnAttr.get();
                Attribute emailAttr =
                        attrs.get(CXConfiguration.getParameterAsString("LDAP_EMAIL_ATTR"));
                String email = (emailAttr.get() != null) ? (String) emailAttr.get() : "";
                env1.put(Context.SECURITY_PRINCIPAL, dn);
                env1.put(Context.SECURITY_CREDENTIALS, password);
                new InitialDirContext(env1); // in case of problem exception will be threw
                Item i = new Item();
                i.setValue("email", email);
                Logger.info("checking with ldap - ok");
                return i;
            } else return null;
        } catch (Exception e) {
            Logger.error("checking with ldap - ldap error", e);
            return null;
        } finally {
            if (ctx != null)
                try {
                    ctx.close();
                } catch (NamingException e) {
                }
        }
    } else return null;
}

highlighted with: http://tohtml.com/

2 comments:

  1. Hi,

    I have seen this posted in quite a few places but no reference as to where to find the CXConfiguration jar/class file which I don't seem to be able to locate anywhere
    are you able to please share them?
    cheers

    ReplyDelete
    Replies
    1. Hi,

      Thanks for question. This piece of code is just an example. Class 'CXConfiguration' works with configuration of my application and can be used for extracting of settings and parameters.

      Here you can find that only two methods of this class are used: getParamterAsString and getParameterAsInt. For example "CXConfiguration.getParameterAsString("LDAP_SERVER")".

      Just replace these methods with constants, for example:
      - LDAP_SERVER = "https://my_domain.com:389";
      - LDAP_AUTH_DN = "cn=ldapquery,uo=Service Accounts,dc=my_domain,dc=com";
      - LDAP_BASE_DN = "dc=my_domain,dc=com";
      - LDAP_USER_SEARCH_ATTR = "sAMAccountName";
      - LDAP_AUTH_PASSWORD = "password";
      - LDAP_EMAIL_ATTR = "mail";
      - LDAP_NAME_ATTR = "displayName".


      Feel free to contact me for any reason, I'll be glad to help you.

      Delete