12
votes

HttpClient 4.1.1 retourne 401 lors de l'authentification avec NTLM, les navigateurs fonctionnent bien

J'essaie d'utiliser l'Apache / Jakarta httpClient 4.1.1 pour vous connecter à une page Web arbitraire en utilisant les informations d'identification données. Pour tester cela, j'ai une installation minimale de IIS 7.5 sur ma machine de développement en cours d'exécution où un seul mode d'authentification est actif à la fois. L'authentification de base fonctionne bien, mais Digest et NTLM renvoyez 401 messages d'erreur lorsque j'essaie de vous connecter. Voici mon code:

    DefaultHttpClient httpclient = new DefaultHttpClient();
    HttpContext localContext = new BasicHttpContext();
    HttpGet httpget = new HttpGet("http://localhost/"); 
    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials(AuthScope.ANY,
            new NTCredentials("user", "password", "", "localhost"));
    if (!new File(System.getenv("windir") + "\\krb5.ini").exists()) {
        List<String> authtypes = new ArrayList<String>();
        authtypes.add(AuthPolicy.NTLM);
        authtypes.add(AuthPolicy.DIGEST);
        authtypes.add(AuthPolicy.BASIC);
        httpclient.getParams().setParameter(AuthPNames.PROXY_AUTH_PREF,
                authtypes);
        httpclient.getParams().setParameter(AuthPNames.TARGET_AUTH_PREF,
                authtypes);
    }
    localContext.setAttribute(ClientContext.CREDS_PROVIDER, credsProvider);
    HttpResponse response = httpclient.execute(httpget, localContext);
    System.out.println("Response code: " + response.getStatusLine());


2 commentaires

J'ai eu l'authentification digère pour travailler dans des navigateurs, mais cela montre toujours 401 interdit à httpclient. Je suis exclu.


Le code fonctionne pour moi, mais il est obsolète en 4.3. Je ne trouve pas de guide clair pour utiliser le code PURE 4.3.


6 Réponses :


3
votes

La solution la plus simple dépannant de telles situations que j'ai trouvées est Wireshark . C'est un très grand marteau, mais cela vous montrera vraiment tout. Installez-le, assurez-vous que votre serveur est sur une autre machine (ne fonctionne pas avec localhost) et commencez à enregistrer la journalisation.

Exécutez votre demande qui échoue, exécutez une qui fonctionne. Ensuite, Filtrer par http (il suffit de mettre http dans le champ de filtre), recherchez la première demande d'obtention, recherchez l'autre demande d'obtention et comparez. Identifiez la différence significative, vous avez maintenant des mots-clés spécifiques ou des problèmes pour rechercher le code / net pour. Sinon, étroiser à la première conversation TCP et examiner la demande / réponse complète. Même avec l'autre.

J'ai résolu un nombre incroyable de problèmes de cette approche. Et Wireshark est un outil très utile pour savoir. Beaucoup de fonctions super avancées pour faciliter le débogage de votre réseau.

Vous pouvez également l'exécuter sur le client ou le serveur. Tout ce qui vous montrera les deux demandes de vous permettre de comparer.


0 commentaires

1
votes

Je l'ai finalement compris. L'authentification Digest nécessite que si vous utilisez une URL complète dans la demande, le proxy doit également utiliser l'URL complète. Je n'ai pas quitté le code proxy dans l'échantillon, mais il a été dirigé vers "Localhost", ce qui lui faisait échouer. Changer cela en 127.0.0.1 a fait fonctionner.


0 commentaires

3
votes

J'ai eu un problème similaire avec httpClient 4.1.2. Pour moi, il a été résolu en revenant à httpclient 4.0.3. Je ne pourrais jamais obtenir NTLM de travailler avec 4.1.2 en utilisant la mise en œuvre intégrée ou l'utilisation de JCIFS.


1 commentaires

Juste une note, j'ai également couru dans ce même problème aussi. Les revendications de la libération de httpClient 4.2.3 pour avoir une implémentation NTLM rafraîchie. J'ai constaté que la mise à niveau vers 4.2.3 a fonctionné sans faille avec NTLM.



6
votes

J'ai eu le même problème avec httpclient4.1.x après la mise à niveau vers HttpClient 4.2.6 Il a frappé comme un charme. Ci-dessous mon code xxx


0 commentaires

10
votes

Je ne suis pas un expert sur le sujet, mais lors de l'authentification NTLM en utilisant des composants http j'ai vu que le client a besoin de 3 tentatives pour se connecter à un point final NTML dans mon cas. Il est un peu décrit pour SPNEGO mais il est un autre bit pour l'authentification NTLM

pour NTLM dans le premier client de tentative fera une demande avec Cible État auth:. incontestées code> et retourne serveur Web HTTP 401 statut et un en-tête: WWW-Authenticate:. NTLM code> p>

client vérifiera les systèmes d'authentification configurés, NTLM doit être configuré dans le code client p>

Deuxième tentative, le client fera une demande avec Cible Etat auth: ATTAQUE code>, et envoie un en-tête d'autorisation avec un jeton encodée au format base64: autorisation: NTLM TlRMTVNTUAABAAAAAYIIogAAAAAoAAAAAAAAACgAAAAFASgKAAAADw == code> Server renvoie à nouveau HTTP 401 statut, mais l'en-tête: WWW-Authenticate: NTLM code> est maintenant peuplé d'informations codées. P>

3ème tentative client utilisera les informations de WWW-Authenticate: en-tête NTLM code> et fera la demande finale avec Cible Etat auth: HANDSHAKE code> et une autorisation en-tête autorisation: NTLM code> qui contient plus d'informations pour le serveur. P>

Dans mon cas, je reçois un p>

HTTP / 1.1 200 OK code> après. Afin d'éviter tout cela dans chaque demande documentation au chapitre 4.7.1 déclare que la même nécessité jeton d'exécution être utilisé pour les demandes liées logiquement. Pour moi, il n'a pas travaillé p>

Mon code.: J'initialiser le client une fois dans un @PostConstruct code> méthode d'un EJB p>

             this.httpclient.close();


0 commentaires

2
votes

Mise à jour de notre application Pour utiliser les pots dans le HTTPComponents-Client-4.5.1 Résolu ce problème pour moi.


0 commentaires