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

前端 未结 4 866
攒了一身酷
攒了一身酷 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:28

    i have done same in my application. following is the which might be useful to you.

        package com.agileinfotech.bsviewer.servlet;
    
        import java.io.IOException;
        import javax.servlet.RequestDispatcher;
        import javax.servlet.ServletException;
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        import javax.naming.*;
        import javax.naming.directory.*;
        import java.util.Hashtable;
    
        public class Login extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    
        public Login() {
        super();
        }
    
        protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        final String SUCCESS = "loin.jsp";
        final String FAILURE = "Failure.html";
        String strUrl = "login.html";
        String username = request.getParameter("username");
        String password = request.getParameter("password");
    
    
    
        Hashtable env = new Hashtable(11);
    
        boolean b = false;
    
        env.put(Context.INITIAL_CONTEXT_FACTORY,
        "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://localhost:10389");
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, "uid="+ username +",ou=system");
        env.put(Context.SECURITY_CREDENTIALS, password);
    
        try {
        // Create initial context
        DirContext ctx = new InitialDirContext(env);
    
        // Close the context when we're done
        b = true;
        ctx.close();
    
        } catch (NamingException e) {
        b = false;
        }finally{
        if(b){
        System.out.print("Success");
        strUrl = SUCCESS;
        }else{
        System.out.print("Failure");
        strUrl = FAILURE;
        }
        }
        RequestDispatcher rd = request.getRequestDispatcher(strUrl);
        rd.forward(request, response);
    
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        processRequest(request,response);
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        processRequest(request,response);
        } 
        }
    
    0 讨论(0)
  • 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<SearchResult> 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;
    }
    
    0 讨论(0)
  • 2020-12-08 16:49

    You should be able to get the environment from the ldap context, clone it, and then put the principal and credentials for the user you want to check:

    @Resource(name = "ldap/users")
    private LdapContext ldapContext;
    
    Hashtable environment = ldapContext.getEnvironment().clone();
    environment.put(Context.SECURITY_PRINCIPAL, userDN);
    environment.put(Context.SECURITY_CREDENTIALS, userPassword);
    
    DirContext dirContext = new InitialDirContext(environment);
    
    0 讨论(0)
  • 2020-12-08 16:52

    In real application LDAP servers, the password is stored in hashcode form and whenever any access manager takes the password from the user, that plain text password is again hashed with same key and checked to the one stored in the LDAP. So as such u can't get the plain password from LDAP server. So if you know the secret key, only then you can decrypt it.

    0 讨论(0)
提交回复
热议问题