2009-08-25 20 views
11

Mam aplikację Java (nie aplet), która musi uzyskać dostęp do usługi sieci Web. Serwery proxy dla usługi sieciowej zostały wygenerowane za pomocą JAX-WS i wydają się działać dobrze. W jednym scenariuszu musi porozmawiać przez serwer proxy sieci Web (w rzeczywistości Squid 3.0), który jest ustawiony na wymaganie uwierzytelniania NTLM.Java 6 NTLM uwierzytelnianie proxy i HTTPS - czy ktoś ma go do pracy?

Działa w JRE 1.6.0_14 Sun'a, wszystko działa dobrze, aby uzyskać dostęp do adresów URL HTTP, bez konieczności wprowadzania jakichkolwiek zmian: wbudowany uwierzytelniacz NTLM uruchamia się i wszystko działa bezbłędnie. Jeśli jednak adres URL serwis internetowy jest URL HTTPS, rozmowa serwis internetowy nie głęboko wewnątrz kodu Sun:

com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport error: java.lang.NullPointerException 
     at com.sun.xml.internal.ws.transport.http.client.HttpClientTransport.getOutput(HttpClientTransport.java:121) 
     at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.process(HttpTransportPipe.java:142) 
     at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.processRequest(HttpTransportPipe.java:83) 
     at com.sun.xml.internal.ws.transport.DeferredTransportPipe.processRequest(DeferredTransportPipe.java:105) 
     at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:587) 
     at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:546) 
     at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:531) 
     at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:428) 
     at com.sun.xml.internal.ws.client.Stub.process(Stub.java:211) 
     at com.sun.xml.internal.ws.client.sei.SEIStub.doProcess(SEIStub.java:124) 
     at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:98) 
     at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:78) 
     at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:107) 
     ... our web service call ... 
Caused by: java.lang.NullPointerException 
     at sun.net.www.protocol.http.NTLMAuthentication.setHeaders(NTLMAuthentication.java:175) 
     at sun.net.www.protocol.http.HttpURLConnection.doTunneling(HttpURLConnection.java:1487) 
     at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:164) 
     at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:896) 
     at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230) 
     at com.sun.xml.internal.ws.transport.http.client.HttpClientTransport.getOutput(HttpClientTransport.java:109) 
     ... 16 more 

Patrząc w bazie błędów Słońca obraca się kilka wyjątków w takich zajęciach, ale wszystkie z nich wydają się zostały naprawione. Czy ktoś ma coś takiego? Czy ktoś ma to do pracy?

+0

Proszę podać również swój import? – itro

Odpowiedz

4

Czy jesteś żonaty z JAX-WS? Używam Apache Axis2, który używa wspólnego httpclient i ma wbudowane uwierzytelnianie NTLM.

przykład:

//Configure SOAP HTTP client to authenticate to server using NTLM 
HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator(); 

//TODO make report server credentials configurable 
auth.setUsername("jdoe"); 
auth.setPassword("strongpass"); 
auth.setDomain("WINDOWSDOMAIN"); 
auth.setHost("host.mydomain.com"); 
auth.setPort(443); 

Options o = new Options(); 
o.setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE,auth); 
myWebServiceStub._getServiceClient().setOptions(o); 
+2

Projekt jest nieco zbyt blisko wydania, aby móc wygodnie wyrywać JAX-WS i zastępować go czymś, ale dzięki za sugestię. – DavidK

10

Po Trcohę, to wydaje się, że usterka w bibliotekach klasy JRE, zwłaszcza w sun.net.www.protocol.http.HttpURLConnection.

Badanie żądań HTTP i odpowiedzi w przypadkach punktów końcowych HTTP i HTTPS pokazało, że w pomyślnym przypadku HTTP, żądania miały nagłówek Proxy-Connection=keep-alive, którego brakowało w przypadku awarii HTTPS. Czytając bardziej ogólnie, wydaje się, że nie ma pewności, czy należy używać "połączenia proxy", czy też "połączenia" ...

W każdym razie należy zauważyć, że w przypadku HTTP kod przechodzi przez HttpURLConnection.writeRequests() , który zawiera następujący kod snippet

/* 
    * For HTTP/1.1 the default behavior is to keep connections alive. 
    * However, we may be talking to a 1.0 server so we should set 
    * keep-alive just in case, except if we have encountered an error 
    * or if keep alive is disabled via a system property 
    */ 

    // Try keep-alive only on first attempt 
    if (!failedOnce && http.getHttpKeepAliveSet()) { 
    if (http.usingProxy) { 
     requests.setIfNotSet("Proxy-Connection", "keep-alive"); 
    } else { 
     requests.setIfNotSet("Connection", "keep-alive"); 
    } 

nie ma takiego kodu podczas tworzenia tunelu przez proxy HTTPS, co powoduje Squid denerwować podczas rozmowy uwierzytelniania NTLM.

Aby obejść ten problem, w HttpURLConnection.sendCONNECTRequest() dodałem

if (http.getHttpKeepAliveSet()) { 
    if (http.usingProxy) { 
     requests.setIfNotSet("Proxy-Connection", "keep-alive"); 
    } 
} 

tuż przed

setPreemptiveProxyAuthentication(requests); 
http.writeRequests(requests, null); 

I wstrzyknąć mój zmodyfikowany HttpURLConnection.class do JRE z flagą "-Xbootclasspath/p", a teraz to działa! Niezupełnie elegancki, ale jesteśmy.

+1

Mam ten sam problem. Znalazłem błąd JDK opisujący dokładnie ten sam problem: http://bugs.sun.com/view_bug.do?bug_id=6206466 Co dziwne, jest oznaczony jako duplikat/naprawiony, chociaż drugi błąd jest zupełnie inny. – sereda

+2

Tak, czasami nie jestem pewien, czy baza danych błędów firmy Sun sprawia, że ​​chcę się śmiać lub płakać. Być może są zbyt zajęci martwiąc się, czy Larry Ellison ich zwolni, czy też nie, aby sprawdzić, czy błędy są naprawdę duplikaty ... – DavidK

+1

BigZig, czy mógłbyś też podać swój import? – itro