SSL(TLS) Authentication:Web Services and Java

In this article we will talk about the SSL(TLS) authentication implementation as required when say calling a web serivce or making an HTTP get call using Java. SSL authentication can be either one way or mutual - where both consumer and provider must authenticate themselves. Lets first start with consumer of a web service. For a web service consumer, there are two major entities that you will be working with The Service endpoint interface(port) and the Service class itself. Lets look at how you obtain the port

This method will return you the port of the service you are trying to consume when the address is provided

JaxWsProxyFactoryBean beanFactory = new JaxWsProxyFactoryBean();
beanFactory.setServiceClass(KtipServiceSoap.class);
beanFactory.setAddress("http://localhost:port/KtipService/xxxx");
return (KtipServiceSoap)beanFactory.create();

Listing I

The SSL authenticaion parameters are passed in through the org.apache.cxf.transport.http.HTTPConduit. (Please note instead of passing SSL parameters through the configuration file, we are passing in through the code ). To get the conduit we must first get the org.apache.cxf.endpoint.Client fromthe port we just obtained. This is done as shown in Listing II.

KtipServiceSoap port = ...// obtained using the code from Listing I
org.apache.cxf.endpoint.Client client = ClientProxy.getClient(port);
HTTPConduit conduit = (HTTPConduit)client.getConduit();
conduit.setTlsClientParameters(fillTLSParameters());

Listing II

Now we will look at how we actually set the TLS parameters for the conduit. We can call a method that will populate the required parameters. The method will look as shown below in Listing III.

org.apache.cxf.configuration.jsse.TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setSecureSocketProtocol("SSL");
tlsParams.setDisableCNCheck(true);
KeyStore keyStore;
    
// Add trust managers (to authenticate the service)
keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(new File("jks file location")), new String("password").toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(keyStore);
TrustManager[] trustMgr = trustFactory.getTrustManagers();
tlsParams.setTrustManagers(trustMgr);
         
// Add key managers (to authenticate the client)
keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream(new File("pfx file location")), new String("password").toCharArray());
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyFactory.init(keyStore, new String("customerInfoSys").toCharArray());
KeyManager[] keyMgr = keyFactory.getKeyManagers();
tlsParams.setKeyManagers(keyMgr);

FiltersType filter = new FiltersType();
filter.getInclude().add(".*_EXPORT_.*");
filter.getInclude().add(".*_EXPORT1024_.*");
filter.getInclude().add(".*_WITH_DES_.*");
filter.getInclude().add(".*_WITH_NULL_.*");
filter.getExclude().add(".*_DH_anon_.*");
tlsParams.setCipherSuitesFilter(filter);
return tlsParams;

Listing III

So when you build your consumer, you should be provided .jks and .pfx files (and passwords for each) for mutual authentication. If there is only one way authentication to be performed by the service only and not the client, this would be done as shown in Listing IV.

org.apache.cxf.configuration.jsse.TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setSecureSocketProtocol("SSL");
tlsParams.setDisableCNCheck(true);
KeyStore keyStore;
    
// Add trust managers (to authenticate the client)
keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream(new File("pfx file location")), new String("password").toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(keyStore);
TrustManager[] trustMgr = trustFactory.getTrustManagers();
tlsParams.setTrustManagers(trustMgr);

FiltersType filter = new FiltersType();
filter.getInclude().add(".*_EXPORT_.*");
filter.getInclude().add(".*_EXPORT1024_.*");
filter.getInclude().add(".*_WITH_DES_.*");
filter.getInclude().add(".*_WITH_NULL_.*");
filter.getExclude().add(".*_DH_anon_.*");
tlsParams.setCipherSuitesFilter(filter);
return tlsParams;
    
Listing IV

In this part I will show how to write a simple Java method to make a HTTP GET/POST when the caller has to be authenticated

String getHTMLData(String address) throws Exception{
    String response = null;
    URLConnection connection =  new URL(address).openConnection();
    HttpsURLConnection sslConnection = null;
    HttpURLConnection nonsslConnection = null;
        
    if(connection instanceof HttpsURLConnection){
        sslConnection = (HttpsURLConnection)connection;
        sslConnection.setSSLSocketFactory(createSocketFactory());
        sslConnection.setRequestMethod("GET");
        if(sslConnection.getResponseCode() == HttpsURLConnection.HTTP_INTERNAL_ERROR ){
            throw new AdServerException("Problem calling ad server...");
        }
    }else if(connection instanceof HttpURLConnection){
        nonsslConnection = (HttpURLConnection)connection;
        nonsslConnection.setRequestMethod("GET");
    }
        
    BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    StringBuilder data = new StringBuilder(150);
    String line;
    while ((line = rd.readLine()) != null)    data.append(line);
    rd.close();
    response = data.toString();
   
    if(connection instanceof HttpsURLConnection) sslConnection.disconnect();
    else if(connection instanceof HttpURLConnection) nonsslConnection.disconnect();
    
    return response;
}

Listing V
    
To create the HTTPS connection with the right SSL parameters, you use the javax.net.ssl.SSLSocketFactory. As shown in listing VI

SSLSocketFactory createSocketFactory() throws Exception {

      KeyStore keyStore;

       // This is a one-way authentication
       keyStore = KeyStore.getInstance("PKCS12");
       keyStore.load(new FileInputStream(new File("pfx file location")),
                 new String("pfx password").toCharArray());
        TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustFactory.init(keyStore);
        TrustManager[] tm = trustFactory.getTrustManagers();

        SSLContext context = SSLContext.getInstance("SSLv3");
        context.init(null, tm, null);
        SSLSocketFactory socketFactory = context.getSocketFactory();
        return socketFactory;
}

Listing VI


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值