Comment vérifier le mot de passe utilisateur dans ldap avec java avec LdapContext donné?


J'ai une application web, où les utilisateurs doivent se connecter. Le mot de passe est stocké dans un serveur LDAP. Toutes les informations sur le serveur LDAP sont stockées dans le serveur d'applications (glassfish) en tant que ressource jndi externe. Donc, mon application ne sait rien du serveur LDAP et n'obtient qu'un LdapContext comme ceci:

@Resource(name = "ldap/users")
private LdapContext ctx;

Dans ce contexte, il est facile de modifier ou de lire les informations stockées pour les utilisateurs, mais comment vérifier leurs mots de passe? Normalement je ferais juste un nouveau connexion pour vérifier un mot de passe utilisateur. Comme ceci:

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial");

env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=S. User, ou=NewHires, o=JNDITutorial");
env.put(Context.SECURITY_CREDENTIALS, "mysecret");

DirContext ctx = new InitialDirContext(env);

Mais comme je ne connais pas les paramètres de this, je ne peux pas le faire. Alors, comment vérifier si le mot de passe d'un utilisateur est correct avec mon LdapContext? Les mots de passe sont stockés cryptés (ssha) donc je ne peux pas simplement comparer les attributs.

Merci Raffael

Author: Benoît, 2010-03-26

4 answers

Vous devriez pouvoir obtenir l'environnement à partir du contexte ldap, le cloner, puis mettre le principal et les informations d'identification pour l'utilisateur que vous souhaitez vérifier:

@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);
 9
Author: Brandon, 2014-03-26 09:05:58

Il s'agit d'une solution qui peut être utilisée pour authentifier un utilisateur avec autre chose que le DN, par exemple avec un uid ou sAMAccountName.

Les étapes à suivre sont:

  1. Connexion au serveur LDAP
  2. Authentifier avec un utilisateur de service dont nous connaissons le DN et les informations d'identification
  3. Recherchez l'utilisateur que vous souhaitez authentifier, recherchez-le avec un attribut (par exemple sAMAccountName)
  4. Obtenir le DN de l'utilisateur que nous avons trouvé
  5. Ouvrir une autre connexion au serveur LDAP avec le DN trouvé et le mot de passe
  6. Si l'utilisateur est trouvé et que l'authentification fonctionne, tout va bien

Exemple de code:

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;
}
 23
Author: Nikolay Antipov, 2016-05-20 19:32:38

J'ai fait de même dans ma demande. voici la qui pourraient être utiles pour vous.

    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);
    } 
    }
 1
Author: Mitul Maheshwari, 2014-02-03 10:12:42

Dans les serveurs LDAP d'application réelle, le mot de passe est stocké sous forme de hashcode et chaque fois qu'un gestionnaire d'accès prend le mot de passe de l'utilisateur, ce mot de passe en texte brut est à nouveau haché avec la même clé et vérifié à celui stocké dans le LDAP. Donc, en tant que tel, vous ne pouvez pas obtenir le mot de passe simple du serveur LDAP. Donc, si vous connaissez la clé secrète, alors seulement vous pouvez la déchiffrer.

 -2
Author: Anil_irocks88, 2014-03-25 18:01:11