JAX WS/CXF, SSL and NTLM

2019-07-26 15:54发布

I need to communicate with a soap webservice (through a VPN tunnel) which requires a) https (with custom certificates) b) ntlm authentication

Thanks to pedrofb ( JAX-WS, trusting all ssl certificates not working ) I got SSL (by ignoring certifiactes) "working". But now I end up not getting through the NTLM authentication...

The credentials I have are correct. I have tested these using cUrl and a minimal HttpClient-only unitTest.

The (ntlm authentication) relevant code looks alike:

public class NtlmAuthenticator extends Authenticator
{
private final String username;
private final char[] password;

public NtlmAuthenticator ( final String username, final String password )
{
    super();
    this.username = username;
    this.password = password.toCharArray();
}

@Override
public PasswordAuthentication getPasswordAuthentication ()
{
    return new PasswordAuthentication( username, password );
}
} 
... 
String ntlmDomain = properties.getProperty( "ntlmDomain" );
    String ntlmUser = properties.getProperty( "ntlmUser" );
    String ntlmPassword = properties.getProperty( "ntlmPassword" );
    String username = ( StringUtils.isNotBlank( ntlmDomain ) ? ntlmDomain + '\\' : "" ) + ntlmUser;
    Authenticator.setDefault( new NtlmAuthenticator( username, ntlmPassword ) );
    ....
    Client client = ClientProxy.getClient( tmpSoapService );
    // SSL stuff
    final HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
    TLSClientParameters params = httpConduit.getTlsClientParameters();
    if ( params == null )
    {
        params = new TLSClientParameters();
        httpConduit.setTlsClientParameters( params );
    }
    params.setTrustManagers( new TrustManager[] { new NaiveTrustManager() } );
    params.setDisableCNCheck( true );

    HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
    httpClientPolicy.setConnectionTimeout( connectTimeout );
    httpClientPolicy.setReceiveTimeout( responseTimeout );
    httpClientPolicy.setAllowChunking( false );

    httpConduit.setClient( httpClientPolicy );

    final BindingProvider bp = (BindingProvider) tmpSoapService;
    final Map<String, Object> requestContext = bp.getRequestContext();
    requestContext.put( BindingProvider.ENDPOINT_ADDRESS_PROPERTY, serviceUrl );
    requestContext.put( BindingProvider.USERNAME_PROPERTY, username );
    requestContext.put( BindingProvider.PASSWORD_PROPERTY, ntlmPassword );

I get to see the following log output:

org.apache.cxf.interceptor.Fault: Could not send Message.
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:64) ~[cxf-core.jar:3.0.1]
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307) ~[cxf-core.jar:3.0.1]
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:516) [cxf-core.jar:3.0.1]
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:425) [cxf-core.jar:3.0.1]
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326) [cxf-core.jar:3.0.1]
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279) [cxf-core.jar:3.0.1]
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96) [cxf-rt-frontend-simple.jar:3.0.1]
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:138) [cxf-rt-frontend-jaxws.jar:3.0.1]
at com.sun.proxy.$Proxy49.nasMgmtRequest(Unknown Source) [na:na]
...
Caused by: org.apache.cxf.transport.http.HTTPException: HTTP response '401: Unauthorized' when communicating with <!! webservice url !!>
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.doProcessResponseCode(HTTPConduit.java:1603) ~[cxf-rt-transports-http.jar:3.0.1]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1610) ~[cxf-rt-transports-http.jar:3.0.1]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1551) ~[cxf-rt-transports-http.jar:3.0.1]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1348) ~[cxf-rt-transports-http.jar:3.0.1]
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) ~[cxf-core.jar:3.0.1]
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:651) ~[cxf-rt-transports-http.jar:3.0.1]
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62) ~[cxf-core.jar:3.0.1]
... 39 common frames omitted

NtlmAuthenticator is being consulted, stacktrace:

NtlmAuthenticator.getPasswordAuthentication() line: 24  
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]  
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 62  
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43  
Method.invoke(Object, Object...) line: 498  
ReferencingAuthenticator.tryWith(Authenticator) line: 132   
ReferencingAuthenticator.getPasswordAuthentication() line: 46   
Authenticator.requestPasswordAuthentication(String, InetAddress, int, String, String, String, URL, Authenticator$RequestorType) line: 317   
HttpURLConnection$1.run() line: 420 
HttpURLConnection$1.run() line: 415 
AccessController.doPrivileged(PrivilegedAction<T>) line: not available [native method]  
HttpURLConnection.privilegedRequestPasswordAuthentication(String, InetAddress, int, String, String, String, URL, Authenticator$RequestorType) line: 414 
DelegateHttpsURLConnection(HttpURLConnection).getServerAuthentication(AuthenticationHeader) line: 2425  
DelegateHttpsURLConnection(HttpURLConnection).getInputStream0() line: 1683  
DelegateHttpsURLConnection(HttpURLConnection).getInputStream() line: 1441   
DelegateHttpsURLConnection(HttpURLConnection).getHeaderFields() line: 2966  
HttpsURLConnectionImpl.getHeaderFields() line: 283  
Headers.readFromConnection(HttpURLConnection) line: 258 
URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.updateCookiesBeforeRetransmit() line: 297 
URLConnectionHTTPConduit$URLConnectionWrappedOutputStream(HTTPConduit$WrappedOutputStream).handleRetransmits() line: 1410   
URLConnectionHTTPConduit$URLConnectionWrappedOutputStream(HTTPConduit$WrappedOutputStream).handleResponse() line: 1546  
URLConnectionHTTPConduit$URLConnectionWrappedOutputStream(HTTPConduit$WrappedOutputStream).close() line: 1348   
URLConnectionHTTPConduit(AbstractConduit).close(Message) line: 56   
URLConnectionHTTPConduit(HTTPConduit).close(Message) line: 651  
MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(Message) line: 62 
PhaseInterceptorChain.doIntercept(Message) line: 307    
ClientImpl.doInvoke(ClientCallback, BindingOperationInfo, Object[], Map<String,Object>, Exchange) line: 516 
ClientImpl.invoke(BindingOperationInfo, Object[], Map<String,Object>, Exchange) line: 425   
ClientImpl.invoke(BindingOperationInfo, Object[], Exchange) line: 326   
ClientImpl.invoke(BindingOperationInfo, Object...) line: 279    
JaxWsClientProxy(ClientProxy).invokeSync(Method, BindingOperationInfo, Object[]) line: 96   
JaxWsClientProxy.invoke(Object, Method, Object[]) line: 138 
...

I am not sure this stacktrace reveils/denotes a ntlm authentication attempt, though?

I also tried

    httpConduit.getAuthorization().setAuthorizationType( "NTLM" );
    httpConduit.getAuthorization().setUserName( username );
    httpConduit.getAuthorization().setPassword( ntlmPassword );

which results in

Caused by: java.io.IOException: Authorization loop detected on Conduit "{urn:microsoft-dynamics-schemas/codeunit/RB_Web}RB_Web_Port.http-conduit" on URL "https://10.5.46.136:7057/NAVTEST/WS/RS%20Vertriebs%20AG/Codeunit/RB_Web" with realm "null"
at org.apache.cxf.transport.http.HTTPConduit.detectAuthorizationLoop(HTTPConduit.java:1930) ~[cxf-rt-transports-http.jar:3.0.9]
at org.apache.cxf.transport.http.HTTPConduit.access$600(HTTPConduit.java:147) ~[cxf-rt-transports-http.jar:3.0.9]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.authorizationRetransmit(HTTPConduit.java:1507) ~[cxf-rt-transports-http.jar:3.0.9]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.processRetransmit(HTTPConduit.java:1438) ~[cxf-rt-transports-http.jar:3.0.9]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleRetransmits(HTTPConduit.java:1412) ~[cxf-rt-transports-http.jar:3.0.9]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1546) ~[cxf-rt-transports-http.jar:3.0.9]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1348) ~[cxf-rt-transports-http.jar:3.0.9]
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) ~[cxf-core.jar:3.0.9]
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:651) ~[cxf-rt-transports-http.jar:3.0.9]
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62) ~[cxf-core.jar:3.0.9]

Any advices? Thx in advance Clemens

标签: cxf jax-ws ntlm
0条回答
登录 后发表回答