Tôi đang cố gắng mở kết nối http đến một url được bảo vệ bằng lược đồ xác thực NTLM. Mã này đã hoạt động chính xác trong 2 năm khi chúng tôi sử dụng Java 6.I đã viết một chương trình java nhỏ truy cập vào url cụ thể đó để làm cho trường hợp thử nghiệm đơn giản nhất có thể.Lỗi Java URLConnection với xác thực ntlm, nhưng chỉ trên Linux và chỉ Java 7
Vấn đề là tôi không thể làm cho chương trình hoạt động trên Linux và khi sử dụng phiên bản của JDK 7. Java cố gắng 20 lần để truy cập URL và sau đó tôi nhận được thông báo lỗi cho máy chủ chuyển hướng quá nhiều lần . Nó hoạt động tốt với linux và JDK 6, và trong windows 7 với JDK 6 hoặc 7.
Tôi đã kiểm tra và thử giải pháp được liệt kê ở đây (và nhiều cách khác): Getting "java.net.ProtocolException: Server redirected too many times" Error. Nó không hoạt động. Tôi cũng phải thêm rằng khi truy cập url từ trình duyệt, tôi có thể thấy rằng không có cookie nào liên quan.
Dưới đây là các chi tiết chính xác của các phiên bản os/java mà tôi đã cố gắng:
thành công:
- Windows 7: Java (TM) SE Runtime Environment (xây dựng 1.7.0_15-b03) (64 bit)
- Windows 7: Java (TM) SE Môi trường Thời gian chạy (xây dựng 1.7.0_10-b18) (64 bit)
- Windows 7: Java (TM) SE Môi trường Thời gian Chạy (xây dựng 1.6.0_33-b04) (64 bit)
- Redhat enterprise li nux 6.4: Java (TM) SE Runtime Environment (xây dựng 1.6.0_33-b04) (64 bit)
Fail:
- doanh nghiệp Redhat Linux 6.4: Java (TM) SE Runtime Environment (xây dựng 1.7.0-b147) (64 bit)
- Redhat enterprise linux 6.4: Java (TM) SE môi trường thời gian chạy (xây dựng 1.7.0_05-b06) (64 bit)
- Redhat enterprise linux 6.4: Java (TM) SE Môi trường thời gian chạy (xây dựng 1.7.0_13-b20) (64 bit)
- Redhat enterprise linux 6.4: Java (TM) S E Runtime Environment (xây dựng 1.7.0_15-b03) (64 bit)
Khi chương trình hoạt động, tôi thấy các phương pháp xác thực đã được sử dụng và tài liệu mà tôi đang cố gắng để tải về càng đầu ra:
Scheme:Negotiate
Scheme:ntlm
.... document content ....
Done
Khi nó không thành công, tôi có kết quả như sau:
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)
đây là mã nguồn của chương trình:
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());
}
}
Mọi trợ giúp sẽ được đánh giá cao.
UPDATE:
Sau khi một số nghiên cứu kỹ hơn, tôi thấy rằng các việc chứng thực nếu tôi sử dụng một người dùng tên miền, nhưng không nếu tôi sử dụng một người dùng cục bộ.
Mã này từ JDK 7 khiến tôi gặp khó khăn (class com.sun.security.ntlm.Khách hàng):
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;
}
Vì vậy, vì máy chủ được đăng ký trong một miền, nó sẽ gửi lại cho khách hàng đó là một phần của giao thức NTLM. Java thay thế tên miền mà tôi đang cố gắng ép buộc bởi biến "domainFromServer" mọi lúc và nó không thành công vì người dùng tồn tại trên máy chủ chứ không phải trên miền của máy chủ.
Tôi không biết chính xác phải làm gì với điều đó.
bạn đang sử dụng bản phát hành java 7 nào? Tôi có một số vấn đề khi làm việc với https hoặc xác thực hoặc bảo mật. Một ứng dụng tôi phát triển chỉ làm việc với java 1.7_02 (Java 7.2) nhưng khi tôi sử dụng các bản phát hành mới nhất, nó không hoạt động nữa. Có một số sửa đổi mà Oracle đã thực hiện trong các bản phát hành mới nhất đặc biệt trong các chính sách bảo mật. Hãy thử với một phiên bản cũ của java 7 như 1.7_02. –
Tôi đã thử nó với phiên bản Java jdk 1.7.0_02 64 bit cho Linux, và nó không hoạt động, cùng một kết quả. – Yanick
Cũng không có thật 1.7.0_25-b15 cho linux (64 bit) –