Erreur Java URLConnection avec l'authentification ntlm, mais seulement sur Linux et seulement Java 7
J'essaie d'ouvrir une connexion http vers une url protégée avec le modèle d'authentification NTLM. Ce code a été fonctionne correctement pendant 2 ans, lorsque nous étions sur la version 6 de Java.J'ai écrit un petit programme en java qui l'accès à ce même url pour faire le test aussi simple que possible.
Le problème est que je suis incapable de faire fonctionner le programme sur linux et lors de l'utilisation de versions du JDK 7. Java essaie de 20 fois pour accéder à l'URL et puis j'obtiens une erreur me disant que le serveur redirigé trop grand nombre de fois. Il fonctionne très bien avec linux et JDK 6, et dans windows 7 avec le JDK 6 ou 7.
J'ai vérifié et essayé la solution indiquée ici (et beaucoup d'autres) : "De java.net.ProtocolException: Serveur redirigé trop de fois" Erreur. Il n'a pas de travail. Je dois aussi ajouter que lors de l'accès à l'url à partir d'un navigateur, je peux voir qu'il y a pas de témoins impliqués.
Voici les détails de l'os/versions de java que j'ai essayé :
Succès:
- Windows 7: Java(TM) SE Runtime Environment (build 1.7.0_15-b03) (64 bits)
- Windows 7: Java(TM) SE Runtime Environment (build 1.7.0_10-b18) (64 bits)
- Windows 7: Java(TM) SE Runtime Environment (build 1.6.0_33-b04) (64 bits)
- Redhat enterprise linux 6.4: Java(TM) SE Runtime Environment (build 1.6.0_33-b04) (64 bits)
Échouer:
- Redhat enterprise linux 6.4: Java(TM) SE Runtime Environment (build 1.7.0-b147) (64 bits)
- Redhat enterprise linux 6.4: Java(TM) SE Runtime Environment (build 1.7.0_05-b06) (64 bits)
- Redhat enterprise linux 6.4: Java(TM) SE Runtime Environment (build 1.7.0_13-b20) (64 bits)
- Redhat enterprise linux 6.4: Java(TM) SE Runtime Environment (build 1.7.0_15-b03) (64 bits)
Lorsque le programme fonctionne, je vois les méthodes d'authentification qui ont été utilisés et le document que je suis en train de télécharger la sortie:
Scheme:Negotiate
Scheme:ntlm
.... document content ....
Done
Lorsqu'il échoue, j'ai le résultat suivant :
Scheme:Negotiate
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
java.net.ProtocolException: Server redirected too many times (20)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1635)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at TestWs.testWs(TestWs.java:67)
at TestWs.main(TestWs.java:20)
Voici le code source du programme:
package com.test;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.net.URLConnection;
public class TestWs {
public static void main(String[] args) throws Exception {
new TestWs().testWs();
}
public void testWs() {
try {
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
Authenticator.setDefault(new MyAuthenticator("username", "password"));
URL url = new URL("https://someurlprotectedbyntlmauthentication.com");
URLConnection connection = url.openConnection();
InputStream is = connection.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
while (true) {
String s = br.readLine();
if (s == null)
break;
System.out.println(s);
}
System.out.println("Done");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
class MyAuthenticator extends Authenticator {
private String httpUsername;
private String httpPassword;
public MyAuthenticator(String httpUsername, String httpPassword) {
this.httpUsername = httpUsername;
this.httpPassword = httpPassword;
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
System.out.println("Scheme:" + getRequestingScheme());
return new PasswordAuthentication(httpUsername, httpPassword.toCharArray());
}
}
Toute aide serait grandement appréciée.
Mise à JOUR:
Après quelques enquête, j'ai trouvé que l'authentification fonctionne si j'utilise un utilisateur de domaine, mais pas si j'utilise un utilisateur local.
Ce code à partir du JDK 7 me cause des ennuis (classe com.soleil.de sécurité.ntlm.Client) :
public byte[] type3(byte[] type2, byte[] nonce) throws NTLMException {
if (type2 == null || (v != Version.NTLM && nonce == null)) {
throw new NullPointerException("type2 and nonce cannot be null");
}
debug("NTLM Client: Type 2 received\n");
debug(type2);
Reader r = new Reader(type2);
byte[] challenge = r.readBytes(24, 8);
int inputFlags = r.readInt(20);
boolean unicode = (inputFlags & 1) == 1;
String domainFromServer = r.readSecurityBuffer(12, unicode);
if (domainFromServer != null) {
domain = domainFromServer;
}
Donc, étant donné que le serveur est incorporée dans un domaine, il envoie au client, c'est le domaine dans le cadre du protocole NTLM. Java remplace le domaine que je suis en train de la force par la variable "domainFromServer" à chaque fois et il échoue dans la mesure où l'utilisateur existe sur le serveur et pas sur le serveur du domaine.
Je ne sais pas exactement quoi faire avec ça.
source d'informationauteur Yanick
Vous devez vous connecter pour publier un commentaire.
J'ai changé de code dans le Client.java de la classe, et recompilé avec le reste de la com.soleil.de sécurité.ntlm paquet, puis j'ai créé un bocal appelé rt_fix.jar qui contient les classes de ce package. Ensuite, j'ai utilisé un java option de démarrage pour le forcer à charger mon pot avant de l'interne rt.jar.
-Xbootclasspath/p:/path_to_jar/rt_fix.jar
Je n'aime pas cette solution, mais cela a fonctionné.
Voici le code que j'ai modifié dans Client.java dans la méthode de type3:
Avant :
Après :
Il s'arrête Java de modifier le domaine que j'ai essayer de s'authentifier avec un reçu à partir du serveur lors de l'envoi de la 3ème partie de l'authentification NTLM. Le domaine que j'essayais de vous authentifier pour est en fait le nom du serveur parce que les comptes d'utilisateurs locaux.
J'ai eu le même problème et résolu simplement en spécifiant le nom d'utilisateur par le nom de domaine inclus:
Correcte est: est-ce
Ce problème a été résolu dans le JDK 9-ea avec http://bugs.java.com/view_bug.do?bug_id=7150092 et la correction a été rétroportés de JDK 8u40 aussi avec le http://bugs.java.com/view_bug.do?bug_id=8049690