HttpClient 4.1.1 retourne 401 lors de l'authentification avec NTLM, navigateurs, beau travail
Je suis en train d'utiliser Apache/Jakarta HttpClient 4.1.1 pour se connecter à un arbitraire de la page web à l'aide de la donnée d'identification. Pour tester cela, j'ai une installation minimale d'IIS 7.5 sur ma machine de dev de course où un seul mode d'authentification est actif à la fois. L'authentification de base fonctionne très bien, mais Digest et NTLM retour 401 messages d'erreur à chaque fois que j'essaie de me 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());
La seule chose que j'ai remarqué dans un violon, c'est que les hachages envoyé par Firefox par rapport à HttpClient sont différents, me faisant penser que peut-être IIS 7.5 attend plus fort de hachage que HttpClient? Des idées? Ce serait génial si je pouvais vérifier que ce serait de travailler avec NTLM. Digest serait sympa aussi, mais je ne peux vivre sans que, si nécessaire.
Le code fonctionne pour moi, mais c'est déconseillé en 4.3. Je ne peux pas trouver un guide clair à utiliser pur 4.3 code.
OriginalL'auteur Jesse | 2011-05-06
Vous devez vous connecter pour publier un commentaire.
Je ne suis pas un expert sur le sujet, mais au cours de l'authentification NTLM à l'aide de http composants, j'ai vu que le client a besoin de 3 tentatives pour se connecter à un NTML point de terminaison dans mon cas. Elle est un peu décrit ici pour Spnego mais c'est un peu différent pour l'authentification NTLM.
Pour NTLM dans la première tentative, le client devra faire une demande auprès de
Target auth state: UNCHALLENGED
et le serveur Web renvoie une erreur HTTP 401 statut et un en-tête:WWW-Authenticate: NTLM
Client vérifie la configuration de systèmes d'Authentification, NTLM doit être configuré dans le code client.
Deuxième tentative, le client devra faire une demande auprès de
Target auth state: CHALLENGED
, et envoie un en-tête d'autorisation avec un jeton encodés en base64 format:Authorization: NTLM TlRMTVNTUAABAAAAAYIIogAAAAAoAAAAAAAAACgAAAAFASgKAAAADw==
Serveur renvoie une erreur HTTP 401 statut, mais l'en-tête:
WWW-Authenticate: NTLM
maintenant est rempli avec les informations codées.3ème Tentative Client utilise les informations de
WWW-Authenticate: NTLM
en-tête et fera de la demande finale avecTarget auth state: HANDSHAKE
et d'une autorisation de l'en-têteAuthorization: NTLM
qui contient plus d'informations pour le serveur.Dans mon cas, j'ai un message d'
HTTP/1.1 200 OK
après.Afin d'éviter tout cela, dans chaque demande la documentation au chapitre 4.7.1 les états que la même exécution jeton doit être utilisé pour la logique des demandes. Pour moi, il n'a pas travaillé.
Mon code:
J'initialise le client, une fois dans un
@PostConstruct
méthode d'un EJBUtiliser la même instance de client à chaque demande:
De libérer les ressources et le retour de la connexion dans le gestionnaire de connexion, à l' @PreDestroy méthode de mon EJB:
OriginalL'auteur gazgas
Cela a fonctionné pour moi.
OriginalL'auteur Mohammed Irfan Tirupattur
J'ai eu un problème similaire avec HttpClient 4.1.2. Pour moi, il a été résolu par un retour à la HttpClient 4.0.3. Je n'ai jamais pu obtenir NTLM de travail avec 4.1.2 utilisant le construit-dans la mise en œuvre ou à l'aide de JCIFS.
OriginalL'auteur Jeff Nadler
Le moyen le plus facile à résoudre de telles situations que j'ai trouvé est Wireshark. C'est un très gros marteau, mais il va vraiment vous montrer tout. L'installer, assurez-vous que votre serveur est sur une autre machine (ne fonctionne pas avec Localhost) et démarrer l'enregistrement.
Exécuter votre requête échoue, exécutez l'une qui fonctionne. Ensuite, filtrer par http (juste mettre l'adresse http dans le champ de filtre), de trouver la première demande, la demande d'OBTENIR et de comparer. Identifier différence significative, vous avez maintenant des mots clés spécifiques ou des questions de code de la recherche/net. Si pas assez, étroit vers le bas de la première TCP conversation et de regarder plein de requête/réponse. De même pour l'autre.
J'ai résolu un nombre incroyable de problèmes avec cette approche. Et Wireshark est outil très utile à savoir. Beaucoup de super-fonctions avancées pour rendre votre réseau de débogage plus facile.
Vous pouvez également l'exécuter sur le client ou le serveur. Ce qui te permettra de vous montrer à la fois demandes pour vous permettre de comparer.
OriginalL'auteur Alexandre Rafalovitch
Mise à jour de notre application pour utiliser les petits pots dans le httpcomponents-client-4.5.1 résolu ce problème pour moi.
OriginalL'auteur Andrew Plata
J'ai enfin compris. L'authentification Digest est que, si vous utilisez une URL complète dans la demande, le mandataire doit également utiliser l'URL complète. Je n'ai pas quitté le code proxy dans l'échantillon, mais elle a été dirigée à "localhost", qui l'a fait échouer. La modification de cette 127.0.0.1 fait le travail.
OriginalL'auteur Jesse