web-dev-qa-db-fra.com

Utilisation de l'authentification NTLM dans les applications Java

Je souhaite utiliser l'authentification Windows NTLM dans mon application Java pour authentifier de manière transparente les utilisateurs d'intranet. Les utilisateurs ne doivent pas remarquer d’authentification s’ils utilisent leur navigateur (connexion unique).

J'ai trouvé quelques bibliothèques avec le support NTLM, mais je ne sais pas laquelle utiliser:

Des suggestions par où commencer?

11
deamon

En dehors de la liste ci-dessus, seuls ntlmv2-auth et Jespa prennent en charge NTLMv2. Jespa est réalisable mais commercial. ntlmv2-auth Je n'ai pas essayé, mais c'est basé sur le code de Liferay, que j'ai vu travailler auparavant.

'ntlm-authentication-in-Java' correspond uniquement à NTLMv1, ancien, non sécurisé et fonctionnant dans un nombre réduit d'environnements lorsque les utilisateurs effectuent une mise à niveau vers des versions plus récentes de Windows. JCIFS possédait un filtre d’authentification HTTP NTLMv1, mais celui-ci a été supprimé dans les versions ultérieures, car sa mise en œuvre s’apparente à une attaque de type «man-in-the-middle» sur le protocole non sécurisé. (Il semble en aller de même pour 'ntlm-authentication-in-Java'.)

Le projet 'spnego' est Kerberos et non NTLM. Si vous souhaitez répliquer IWA complet comme le fait IIS, vous devez prendre en charge NTLMv2 et Kerberos (autorisation 'NTLM', autorisation 'Negotiate', autorisation NTLMSSP-in-SPNego et masquage NTLM. autorisation de négociation).

10
bobince

Le script de Luigi Dragone est vraiment vieux et semble toujours échouer.

HttpURLConnection peut fonctionner avec NTLM si vous ajoutez la bibliothèque jcifs , cet exemple fonctionne avec le dernier jcifs-1.3.18 :

import Java.io.BufferedReader;
import Java.io.IOException;
import Java.io.InputStream;
import Java.io.InputStreamReader;
import Java.net.HttpURLConnection;
import Java.net.URL;
import Java.net.UnknownHostException;
import Java.util.HashMap;
import Java.util.Map;

import org.Apache.http.impl.auth.NTLMEngineException;

public class TestNTLMConnection {
    public static void main(String[] args) throws UnknownHostException, IOException, NTLMEngineException {
        // Method 1 : authentication in URL
        jcifs.Config.registerSmbURLHandler();
        URL urlRequest = new URL("http://domain%5Cuser:[email protected]/");

        // or Method 2 : authentication via System.setProperty()
        // System.setProperty("http.auth.ntlm.domain", "domain");
        // System.setProperty("jcifs.smb.client.domain", "domain");
        // System.setProperty("jcifs.smb.client.username", "user");
        // System.setProperty("jcifs.smb.client.password", "pass");
        // Not verified // System.setProperty("jcifs.netbios.hostname", "Host");
        // System.setProperty("Java.protocol.handler.pkgs", "jcifs");
        // URL urlRequest = new URL("http://127.0.0.1:8180/simulate_get.php");

        HttpURLConnection conn = (HttpURLConnection) urlRequest.openConnection();

        StringBuilder response = new StringBuilder();

        try {
            InputStream stream = conn.getInputStream();
            BufferedReader in = new BufferedReader(new InputStreamReader(stream));

            String str = "";
            while ((str = in.readLine()) != null) {
                response.append(str);
            }
            in.close();   

            System.out.println(response);
        } catch(IOException err) {
            System.out.println(err);
        } finally {
            Map<String, String> msgResponse = new HashMap<String, String>();

            for (int i = 0;; i++) {
                String headerName = conn.getHeaderFieldKey(i);
                String headerValue = conn.getHeaderField(i);
                if (headerName == null && headerValue == null) {
                    break;
                }
                msgResponse.put(headerName == null ? "Method" : headerName, headerValue);
            }

            System.out.println(msgResponse);
        }
    }
}

Et si vous êtes curieux du contenu de chaque poignée de main, vous pouvez trouver un autre exemple en utilisant jcifs et Socket sur ce thread .

3
ron190

Réf.: https://jcifs.samba.org/src/docs/faq.html#ntlmv2

Q: jCIFS prend-il en charge NTLMv2?
A: Oui. À partir de la version 1.3.0, JCIFS prend entièrement en charge NTLMv2 et l’utilise par défaut.

Remarque: Le filtre NTLM HTTP SSO précédemment inclus dans JCIFS ne peut pas prendre en charge NTLMv2.

0
Nikhil

Relativement à partir de la liste que vous avez donnée, j'irais avec JCIFS . La bibliothèque est mature et leur documentation est bonne. Pour couronner le tout, ils ont eu des publications assez régulières, et le dernier étant novembre 2011.

Personal Experience: c'était assez facile de commencer par rapport aux autres que j'ai essayés (spnego et ntmv2auth)

0
Sudhakar