How to resolve TLS version issue due to Salesforce disabling TLS 1.0 : SOAP API

As most of you may know Salesforce has disable supporting TLS 1.0 from June 25, 2016 on their sandbox environment. They will apply this change to their production environments on March 4, 2017, at 9:30 AM PST (17:30 UTC). Because of this change authentication can be failed by giving the following error when you use their SOAP API.
TLS 1.0 has been disabled in this organization. Please use TLS 1.1 or higher when connecting.

Salesforce has given couple of solutions to overcome this problem and they can be found in the below link.
https://help.salesforce.com/apex/HTViewSolution?id=000221207

But if you are a developer who does not use Java 8 and if you are one of the people like me who does not want to set this as a system property(System.setProperty("https.protocols", "TLSv1.1,TLSv1.2")) you can use the below mechanism to overcome this problem.

This is a two step process.

  • Create a custom Transporter by extending com.sforce.ws.transport.JdkHttpTransport.
 public class SalesforceHttpTransport implements Transport {  
 ......  
 public static HttpURLConnection createConnection(ConnectorConfig config, URL url,  
       HashMap<String, String> httpHeaders, boolean enableCompression) throws IOException {  
     if (config.isTraceMessage()) {  
       config.getTraceStream().println( "WSC: Creating a new connection to " + url + " Proxy = " +  
           config.getProxy() + " username " + config.getProxyUsername());  
     }  
     HttpURLConnection connection = (HttpURLConnection) url.openConnection(config.getProxy());  
     connection.addRequestProperty("User-Agent", VersionInfo.info());  
     /*  
      * Add all the client specific headers here  
      */  
     if (config.getHeaders() != null) {  
       for (Entry<String, String> ent : config.getHeaders().entrySet()) {  
         connection.setRequestProperty(ent.getKey(), ent.getValue());  
       }  
     }  
     if (enableCompression && config.isCompression()) {  
       connection.addRequestProperty("Content-Encoding", "gzip");  
       connection.addRequestProperty("Accept-Encoding", "gzip");  
     }  
     if (config.getProxyUsername() != null) {  
       String token = config.getProxyUsername() + ":" + config.getProxyPassword();  
       String auth = "Basic " + new String(Base64.encode(token.getBytes()));  
       connection.addRequestProperty("Proxy-Authorization", auth);  
       connection.addRequestProperty("Https-Proxy-Authorization", auth);  
     }  
     if (httpHeaders != null) {  
       for (Map.Entry<String, String> entry : httpHeaders.entrySet()) {  
         connection.addRequestProperty(entry.getKey(), entry.getValue());  
       }  
     }  
     if (config.getReadTimeout() != 0) {  
       connection.setReadTimeout(config.getReadTimeout());  
     }  
     if (config.getConnectionTimeout() != 0) {  
       connection.setConnectTimeout(config.getConnectionTimeout());  
     }  
     if (connection instanceof HttpsURLConnection) {  
       HttpsURLConnection secureConnection = (HttpsURLConnection) connection;  
       try {  
        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");  
        sslContext.init(null, null, new java.security.SecureRandom());  
        SSLSocketFactory sf = sslContext.getSocketFactory();  
        secureConnection.setSSLSocketFactory(sf);  
        return secureConnection;  
       } catch (Exception e) {  
        throw new IOException("Error occured during setting the TLS version");  
       }  
     }  
     return connection;  
   }  
 ...  
 }  


  • Use the created Transporter to create the connection to execute web services.
           ConnectorConfig config = new ConnectorConfig();  
           config.setUsername(username);  
           config.setPassword(password);  
           config.setAuthEndpoint(authEndPoint);  
           //Set the Custom Transporter  
           config.setTransport(SalesforceHttpTransport.class);  
           connection = new EnterpriseConnection(config);  



Now you are good to go.

You can see the full source code from the following links.
SalesforceHttpTransport.java
SalesforceConnectionTestor.java

Comments

Ram Ramky said…
Thank you for this post!! I have just discovered your blog recently and I really like it! I will definitely try some of your insights.
Salesforce Admin Training in Chennai
Salesforce Administrator 201 Training in Chennai
Malar said…

This is an awesome post.Really very informative and creative contents. These concept is a good way to enhance the knowledge.I like it and help me to development very well.Thank you for this brief explanation and very nice information.Well, got a good knowledge.
Salesforce Training | Online Course | Certification in chennai | Salesforce Training | Online Course | Certification in bangalore | Salesforce Training | Online Course | Certification in hyderabad | Salesforce Training | Online Course | Certification in pune