1

我在使用 Apache CFX 调用 SOAP Web 服务并与我们的公司 NTLM 代理进行身份验证时遇到了一些麻烦。我必须使用JCFS,因为我们的安装程序使用 Java 5。应用程序服务器是 Glassfish 2.1.1。

public Client() {

        final String username = USERNAME;
        final String password = PASSWORD;
        final String url = CONNECTION_URL;


        final JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        logger.debug("JaxWSProxy Factory created");


        // Basic authentication
        factory.setUsername(username);
        logger.debug("Set SOAP username");
        factory.setPassword(password);
        logger.debug("Set SOAP password");


        final GZIPInInterceptor gzipInterceptor = new GZIPInInterceptor();
        factory.getInInterceptors().add(gzipInterceptor);
        final FIStaxInInterceptor fastInfoSetIn = new FIStaxInInterceptor();
        factory.getInInterceptors().add(fastInfoSetIn);
        final FIStaxOutInterceptor fastInfoSetOut = new FIStaxOutInterceptor();
        factory.getOutInterceptors().add(fastInfoSetOut);
        logger.debug("Interceptors initialized");


        // Configure WS-Security Header
        // Connnection to SOAP endpoint - only possible with security header
        Map properties = new HashMap();

        WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(properties);

        factory.getOutInterceptors().add(wssOut);
        factory.getOutInterceptors().add(new SAAJOutInterceptor());

        properties.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.TIMESTAMP);

        // Specify username
        properties.put(WSHandlerConstants.USER, username);

        // Password type :plain text
        properties.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);

        // Callback used to retrieve password for given user
        properties.put(WSHandlerConstants.PW_CALLBACK_REF, new ClientPasswordHandler(password));

        // Set interface class
        factory.setServiceClass(FeedInterface.class);

        // Set url
        factory.setAddress(url);

        this.Feed = (FeedInterface) factory.create();

         //Set the jcifs properties
        jcifs.Config.setProperty("jcifs.smb.client.domain", "domain");
        jcifs.Config.setProperty("jcifs.netbios.wins", "xxx.xxx.xxx.xx");
        jcifs.Config.setProperty("jcifs.smb.client.soTimeout", "300000");
        jcifs.Config.setProperty("jcifs.netbios.cachePolicy", "1200");
        jcifs.Config.setProperty("jcifs.smb.client.username", " username ");
        jcifs.Config.setProperty("jcifs.smb.client.password", " password ");

        //Register the jcifs URL handler to enable NTLM
        jcifs.Config.registerSmbURLHandler();

        //Turn off chunking so that NTLM can occur
        Client client = ClientProxy.getClient(this.Feed);
        HTTPConduit http = (HTTPConduit) client.getConduit();
        HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
        httpClientPolicy.setConnectionTimeout(36000);
        httpClientPolicy.setAllowChunking(false);
        http.setClient(httpClientPolicy);



        logger.debug("Client created");


    }


    /**
     * Gets the Service web service client. <p>
     * <p/>
     * @return Returns the feed.
     */
    public FeedInterface getfeed() {
        return Feed;
    }

    /**
     * Private class to handle setting the client password on the WS-Security envelope.
     */
    class ClientPasswordHandler implements CallbackHandler {

        private String password = null;


        public ClientPasswordHandler(String password) {
            this.password = password;
        }


        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {

            WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
            // set the password for the outbound message.
            pc.setPassword(this.password);
        }

    }
}

我也测试了这个解决方案:

public Client() {

        final String username = USERNAME;
        final String password = PASSWORD;
        final String url = CONNECTION_URL;


        final JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        logger.debug("JaxWSProxy Factory created");


        // Basic authentication
        factory.setUsername(username);
        logger.debug("Set SOAP username");
        factory.setPassword(password);
        logger.debug("Set SOAP password");


        final GZIPInInterceptor gzipInterceptor = new GZIPInInterceptor();
        factory.getInInterceptors().add(gzipInterceptor);
        final FIStaxInInterceptor fastInfoSetIn = new FIStaxInInterceptor();
        factory.getInInterceptors().add(fastInfoSetIn);
        final FIStaxOutInterceptor fastInfoSetOut = new FIStaxOutInterceptor();
        factory.getOutInterceptors().add(fastInfoSetOut);
        logger.debug("Interceptors initialized");


        // Configure WS-Security Header
        // Connnection to  SOAP endpoint - only possible with security header
        Map properties = new HashMap();

        WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(properties);

        factory.getOutInterceptors().add(wssOut);
        factory.getOutInterceptors().add(new SAAJOutInterceptor());

        properties.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.TIMESTAMP);

        // Specify username
        properties.put(WSHandlerConstants.USER, username);

        // Password type :plain text
        properties.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);

        // Callback used to retrieve password for given user
        properties.put(WSHandlerConstants.PW_CALLBACK_REF, new ClientPasswordHandler(password));

        // Set interface class
        factory.setServiceClass(FeedInterface.class);

        // Set url
        factory.setAddress(url);

        final String authUser = "username";
        final String authPassword = "password";
        Authenticator.setDefault(new Authenticator() {

        public PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(authUser, authPassword.toCharArray());
        }

        });

        System.setProperty("http.proxySet", "true");
        System.setProperty("https.proxyHost", "xxxx.xxxx");
        System.setProperty("https.proxyPort", "8080");

        this.Feed = (FeedInterface) factory.create();



        logger.debug("Client created");


    }


    /**
     * Gets the Service web service client. <p>
     * <p/>
     * @return Returns the feed.
     */
    public FeedInterface getfeed() {
        return Feed;
    }

    /**
     * Private class to handle setting the client password on the WS-Security envelope.
     */
    class ClientPasswordHandler implements CallbackHandler {

        private String password = null;


        public ClientPasswordHandler(String password) {
            this.password = password;
        }


        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {

            WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
            // set the password for the outbound message.
            pc.setPassword(this.password);
        }

    }
}

我总是收到此连接被拒绝异常:

    2013-04-23 16:52:34 SessionCron [ERROR] Exception encountered running SessionCron. For stack trace see debug log.
2013-04-23 16:52:34 SessionCron [DEBUG] Stack trace: 
javax.xml.ws.soap.SOAPFaultException: Connection refused
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:156)
    at com.sun.proxy.$Proxy103.getXXXX(Unknown Source)
    at xxx.yyyyyy..SessionAgent.updateXXXXData(SessionAgent.java:260)
    at xxx.yyyyyy..SessionAgent.checkForUpdates(SessionAgent.java:143)
    at xxx.yyyyyy.util.SessionCron.run(SessionCron.java:40)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:204)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    at java.lang.Thread.run(Thread.java:680)
Caused by: com.sun.xml.stream.XMLStreamException2
    at com.sun.xml.stream.writers.XMLStreamWriterImpl.writeStartElement(XMLStreamWriterImpl.java:1363)
    at org.apache.cxf.staxutils.StaxUtils.writeStartElement(StaxUtils.java:586)
    at org.apache.cxf.staxutils.StaxUtils.copy(StaxUtils.java:525)
    at org.apache.cxf.staxutils.StaxUtils.copy(StaxUtils.java:513)
    at org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor.handleMessage(SAAJOutInterceptor.java:210)
    at org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor.handleMessage(SAAJOutInterceptor.java:171)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:535)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:465)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:368)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:321)
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:88)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
    ... 13 more
Caused by: java.net.ConnectException: Connection refused
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
    at java.net.Socket.connect(Socket.java:529)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:158)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:388)
    at sun.net.www.http.HttpClient$3.run(HttpClient.java:451)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.net.www.http.HttpClient.privilegedOpenServer(HttpClient.java:433)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:514)
    at sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:272)
    at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:329)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:172)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:949)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:158)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1014)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1368)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1310)
    at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:42)
    at org.apache.cxf.io.AbstractThresholdOutputStream.unBuffer(AbstractThresholdOutputStream.java:89)
    at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:79)
    at com.sun.xml.stream.writers.UTF8OutputStreamWriter.write(UTF8OutputStreamWriter.java:107)
    at com.sun.xml.stream.writers.XMLStreamWriterImpl.openStartTag(XMLStreamWriterImpl.java:1588)
    at com.sun.xml.stream.writers.XMLStreamWriterImpl.writeStartElement(XMLStreamWriterImpl.java:1322)
    ... 25 more
4

0 回答 0