如何在Java7中为Axis1 webservice客户端

时间:2016-07-01 03:36:25

标签: salesforce java-7 salesforce-communities

摘要:Salesforce.com最近为其沙盒实例(test.salesforce.com)禁用了TLSv1,并且只能支持TLSv1.1及更高版本的入站和出站请求的API集成。

我正在使用带有JDK 7.0的Java Axis1.0客户端代码(通过webservice soap)连接到salesforce.com。我得到例外“UNSUPPORTED_CLIENT:此组织中已禁用TLS 1.0。使用https连接到Salesforce时,请使用TLS 1.1或更高版本。” With Java7.0 Supported Protocols:SSLv2Hello, SSLv3, TLSv1, TLSv1.1, TLSv1.2 Enabled Protocols: TLSv1

`使用Java8.0 当我尝试使用java8客户端连接到salesforce.com时,连接成功。

支持的协议:SSLv2Hello,SSLv3,TLSv1,TLSv1.1,TLSv1.2 启用协议:TLSv1,TLSv1.1,TLSv1.2`

我必须使用Java 7,因为我们的应用程序正在使用它。 我试过设置vm args: -Dhttps.protocols = TLSv1.1,TLSv1.2 -Ddeployment.security.SSLv2Hello = false -Ddeployment.security.SSLv3 = false -Ddeployment.security.TLSv1 = false -Ddeployment.security.TLSv1.1 = true -Ddeployment.security .TLSv1.2 =真” 但没有成功。

你能帮我找一下Java7中的设置来启用TLSv1.1吗?

2 个答案:

答案 0 :(得分:2)

来自Salesforce documentation

Java 7:使用HttpsURLConnection的https.protocols Java系统属性启用TLS 1.1和TLS 1.2。要在非HttpsURLConnection连接上启用TLS 1.1和TLS 1.2,请在应用程序源代码中的已创建的SSLSocket和SSLEngine实例上设置启用的协议。

答案 1 :(得分:2)

当Axis传输是默认的HTTPSender时,上面的解决方案很有效。此外,知道新的套接字工厂不仅可以替换为AxisProperties,而且还可以替换为系统属性,这可以在命令行上传递,如下所示:

-Dorg.apache.axis.components.net.SecureSocketFactory=your.package.TLSv12JSSESocketFactory

以下是我的TLSv12JSSESocketFactory的代码:

package your.package;

import java.util.Hashtable;
import java.io.IOException;
import java.net.Socket;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import org.apache.axis.components.net.JSSESocketFactory;
import org.apache.axis.components.net.BooleanHolder;

public class TLSv12JSSESocketFactory extends JSSESocketFactory {

    private final String TLS_VERSION_1_2 = "TLSv1.2";

    public TLSv12JSSESocketFactory( @SuppressWarnings("rawtypes") Hashtable attributes ) {
        super(attributes);
    }

    @Override
    protected void initFactory() throws IOException {
        SSLContext context;
        try {
            context = SSLContext.getInstance( TLS_VERSION_1_2 );
            context.init( null, null, null );
            sslFactory = context.getSocketFactory();
        } catch ( Exception e ) {
            throw new IOException( "Could not init SSL factory with TLS context: " + TLS_VERSION_1_2, e );
        }
    }

    @Override
    public Socket create( String host, int port, StringBuffer otherHeaders, BooleanHolder useFullURL ) throws Exception {

        Socket s = super.create( host, port, otherHeaders, useFullURL );
        ((SSLSocket) s).setEnabledProtocols( new String[] { TLS_VERSION_1_2 } );

        return s;
    }
}

在我的情况下,我不得不使用Apache Commons HttpClient作为传输来更改Axis 1.4。这涉及创建一个实现接口SecureProtocolSocketFactory的类。这是我的代码:

package your.package;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import javax.net.ssl.SSLSocket;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;


public class TLSv12HttpsSocketFactory implements SecureProtocolSocketFactory
{
    private static final String TLS_VERSION_1_2 = "TLSv1.2";
    private final SecureProtocolSocketFactory base;

    public TLSv12HttpsSocketFactory( ProtocolSocketFactory base )
    {
        if ( base == null || !(base instanceof SecureProtocolSocketFactory) ) throw new IllegalArgumentException();
        this.base = (SecureProtocolSocketFactory) base;
    }

    private Socket acceptOnlyTLS12( Socket socket )
    {
        if ( socket != null && (socket instanceof SSLSocket) ) {
            ((SSLSocket) socket).setEnabledProtocols( new String[] { TLS_VERSION_1_2 } );
        }

        return socket;
    }

    @Override
    public Socket createSocket( String host, int port ) throws IOException
    {
        return acceptOnlyTLS12( base.createSocket(host, port) );
    }

    @Override
    public Socket createSocket( String host, int port, InetAddress localAddress, int localPort ) throws IOException
    {
        return acceptOnlyTLS12( base.createSocket(host, port, localAddress, localPort) );
    }

    @Override
    public Socket createSocket( String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params ) throws IOException
    {
        return acceptOnlyTLS12( base.createSocket(host, port, localAddress, localPort, params) );
    }

    @Override
    public Socket createSocket( Socket socket, String host, int port, boolean autoClose ) throws IOException
    {
        return acceptOnlyTLS12( base.createSocket(socket, host, port, autoClose) );
    }
}

但我还必须修改org.apache.axis.transport.http.CommonsHTTPSender类(编译时生成一些类文件),如下所示:

// import the new socket factory
import your.package.TLSv12HttpsSocketFactory;
...
// add this at the end of the initialize() method
// setup to our custom TLSv1.2 socket factory
String scheme = "https";
Protocol baseHttps = Protocol.getProtocol( scheme );
int defaultPort = baseHttps.getDefaultPort();

ProtocolSocketFactory baseFactory = baseHttps.getSocketFactory();
ProtocolSocketFactory customFactory = new TLSv12HttpsSocketFactory( baseFactory );

Protocol customHttps = new Protocol( scheme, customFactory, defaultPort );
Protocol.registerProtocol( scheme, customHttps );