How to check user password in ldap whith java with given LdapContext?

前端 未结 4 884
攒了一身酷
攒了一身酷 2020-12-08 15:58

I do have a web-application, where users must log in. The password is stored in a LDAP server. All information about the LDAP server are stored in the application server (gl

4条回答
  •  青春惊慌失措
    2020-12-08 16:48

    This is a solution that can be used to authenticate a user with something else than the DN, for example with a uid or sAMAccountName.

    The steps to do are:

    1. Connect to the LDAP server
    2. Authenticate with a service user of whom we know the DN and credentials
    3. Search for the user you want to authenticate, search him with some attribute (for example sAMAccountName)
    4. Get the DN of the user we found
    5. Open another connection to the LDAP server with the found DN and the password
    6. If the user is found and authentication works, you are fine

    Code example:

    public static boolean performAuthentication() {
    
        // service user
        String serviceUserDN = "cn=Mister Service,ou=Users,dc=example,dc=com";
        String serviceUserPassword = "abc123#!$";
    
        // user to authenticate
        String identifyingAttribute = "uid";
        String identifier = "maxdev";
        String password = "jkl987.,-";
        String base = "ou=Users,dc=example,dc=com";
    
        // LDAP connection info
        String ldap = "localhost";
        int port = 10389;
        String ldapUrl = "ldap://" + ldap + ":" + port;
    
        // first create the service context
        DirContext serviceCtx = null;
        try {
            // use the service user to authenticate
            Properties serviceEnv = new Properties();
            serviceEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
            serviceEnv.put(Context.PROVIDER_URL, ldapUrl);
            serviceEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
            serviceEnv.put(Context.SECURITY_PRINCIPAL, serviceUserDN);
            serviceEnv.put(Context.SECURITY_CREDENTIALS, serviceUserPassword);
            serviceCtx = new InitialDirContext(serviceEnv);
    
            // we don't need all attributes, just let it get the identifying one
            String[] attributeFilter = { identifyingAttribute };
            SearchControls sc = new SearchControls();
            sc.setReturningAttributes(attributeFilter);
            sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
    
            // use a search filter to find only the user we want to authenticate
            String searchFilter = "(" + identifyingAttribute + "=" + identifier + ")";
            NamingEnumeration results = serviceCtx.search(base, searchFilter, sc);
    
            if (results.hasMore()) {
                // get the users DN (distinguishedName) from the result
                SearchResult result = results.next();
                String distinguishedName = result.getNameInNamespace();
    
                // attempt another authentication, now with the user
                Properties authEnv = new Properties();
                authEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
                authEnv.put(Context.PROVIDER_URL, ldapUrl);
                authEnv.put(Context.SECURITY_PRINCIPAL, distinguishedName);
                authEnv.put(Context.SECURITY_CREDENTIALS, password);
                new InitialDirContext(authEnv);
    
                System.out.println("Authentication successful");
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (serviceCtx != null) {
                try {
                    serviceCtx.close();
                } catch (NamingException e) {
                    e.printStackTrace();
                }
            }
        }
        System.err.println("Authentication failed");
        return false;
    }
    

提交回复
热议问题