如何使用用户名/密码(无证书)通过https设置CXF / SOAP客户端连接

时间:2012-08-29 12:44:04

标签: java soap cxf password-protection

我们有一个SOAP-webservice,我们试图通过使用用户名/密码连接的https连接设置获取连接,不应该涉及证书。似乎Java仍在尝试并且无法进行证书握手。如何设置连接以使其设法使用用户名/密码?

在MyWeb上尝试查询调用时生成错误:

2012-08-29 13:31:19,918 WARN  (LogUtils.java:371) - Interceptor for {http://myaddress/}MyWebService#{http://myqname/}getStatus has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Could not send Message.
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:64)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:510)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:440)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:343)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:295)
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:124)
    at $Proxy55.getTccStatus(Unknown Source)
    at se.transrail.cato.monitor.server.MonitorWsClient.readTccStatus(MonitorWsClient.java:65)
    at se.transrail.cato.monitor.server.WebServicePoller.run(WebServicePoller.java:73)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: javax.net.ssl.SSLHandshakeException: SSLHandshakeException invoking https://myaddress/: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1404)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1389)
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:623)
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
    ... 18 more
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1868)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1338)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:154)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:998)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1294)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1321)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1305)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:515)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1090)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1337)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1283)
    at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:42)
    at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1361)
    ... 21 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
    at sun.security.validator.Validator.validate(Validator.java:260)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1320)
    ... 37 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
    ... 43 more

MyWeb和MyWebService由Apache CXF 2.4.8 wsdl2java生成。 MyWeb是MyWebService的界面。 在myweb.wsdl中,我已经替换了

设定:

private MyWeb preparePort() {
    MyWebService ss = new MyWebService(
            // locally stored wsdl to avoid connection at this time
            getClass().getClassLoader().getResource("myweb.wsdl");,
            new QName("http://qname/", "MyWebService"));
    MyWeb port = ss.getMonitorWebServicePort();

    Client cl = ClientProxy.getClient(port);

    HTTPConduit http = (HTTPConduit) cl.getConduit();

    HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();

    httpClientPolicy.setConnectionTimeout(connectionTimeout);
    httpClientPolicy.setReceiveTimeout(receiveTimeout);
    httpClientPolicy.setConnection(ConnectionType.CLOSE);
    httpClientPolicy.setMaxRetransmits(1);

    http.setClient(httpClientPolicy);

    ((BindingProvider) port).getRequestContext().putAll(of(
            USERNAME_PROPERTY, username,
            PASSWORD_PROPERTY, password,
            ENDPOINT_ADDRESS_PROPERTY, "https://mywebaddress/"));
    return port;

来自myweb.wsdl

<wsdl:service name="MyWebService">
    <wsdl:port binding="tns:MyWebServiceSoapBinding" name="MyWebPort">
        <soap:address location="https://mywebaddress/"/>
    </wsdl:port>
</wsdl:service>

尝试在网络上找不到的修复程序:

//    AuthorizationPolicy authorizationPolicy = new AuthorizationPolicy();
//    authorizationPolicy.setUserName(username);
//    authorizationPolicy.setPassword(password);
//    authorizationPolicy.setAuthorizationType("Basic");
//    http.setAuthorization(authorizationPolicy);

//    Authenticator myAuth = new Authenticator()
//    {
//        @Override
//        protected PasswordAuthentication getPasswordAuthentication()
//        {
//            return new PasswordAuthentication(username, password.toCharArray());
//        }
//    };
//    Authenticator.setDefault(myAuth);

1 个答案:

答案 0 :(得分:5)

在这里找到一个工作解决方案http://techpolesen.blogspot.se/2007/08/using-ssl-with-xfirecxf-battling.html,它会覆盖TrustManager,使其接受连接而不存在证书:

    String targetAddr = http.getTarget().getAddress().getValue();
    if (targetAddr.toLowerCase().startsWith("https:")) {
        TrustManager[] simpleTrustManager = new TrustManager[] { new X509TrustManager() {
            public void checkClientTrusted(
                    java.security.cert.X509Certificate[] certs, String authType) {
            }

            public void checkServerTrusted(
                    java.security.cert.X509Certificate[] certs, String authType) {
            }
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        } };
        TLSClientParameters tlsParams = new TLSClientParameters();
        tlsParams.setTrustManagers(simpleTrustManager);
        tlsParams.setDisableCNCheck(true);
        http.setTlsClientParameters(tlsParams);
    }