This discussion is archived
0 Replies Latest reply: Feb 5, 2013 10:51 AM by 877774 RSS

Create a JAX-RPC client to call a WS over SSL

877774 Newbie
Currently Being Moderated
Hi everyone!

I've only worked with WL for a couple of years and until now I managed solve every problem I've had. But I guess there's always the first one.

So... I got a web application, that must call a WS and display response on a web page. This WS is written in PHP and uses RPC. Because web app is programmed in a generic way (you just add WS details in an XML and it builds clients and calls methods by itself) it can only "consume" JAX-WS web services that use RMI. Because I don't want to fundamentally change my webApp I decided to wrap the RPC WS in RMI WS. Now here comes the problem. To communicate with the RPC WS you must use SSL. With a little help from my coworker I managed to implement everything, to make the new WS call a method on a RPC WS and return response. However, this worked only as a standalone app (I made a main() method and called the service), but when I deployed it on a WebLogic (btw I'm using 12c) nothing worked anymore. So, for a test I tried to deploy it to GlassFish (3.1.2.1), where it worked just fine. I looked at WL logs and discovered, that the problem are "conflicts" between native Java libs and weblogic specific libs.
After hours of googling I actually managed to get the WS working on WL, but I had to add a certain JAR (saaj-impl.jar) to classpath + I had to add an startup option to JVM (-DUseSunHttpHandler=true). But I can mess with startup script on my dev server, while production is a different story.

This is the code, that works on GlassFish:

RPCCallHandler.java:

import com.sun.xml.rpc.client.StubBase;
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
import ws.rpc.wifree.ListSCE;
import ws.rpc.wifree.MyRpcService;
import ws.rpc.wifree.MyRpcServicePortType;
import ws.rpc.wifree.MyRpcService_Impl;

public class RPCCallHandler {

private MyRpcServicePortType port = null;

public RPCCallHandler() {
try {
System.setProperty ("javax.xml.soap.MessageFactory",
"com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl");
System.setProperty("javax.xml.soap.SOAPConnectionFactory",
                    "weblogic.wsee.saaj.SOAPConnectionFactoryImpl");

MyRpcService service = new MyRpcService_Impl();

port = service.getMyRpcServicePort();

               StubBase sBase=(StubBase) port;
               sBase._setTransportFactory(new MyClientTransportFactory());
} catch (ServiceException e) {
e.printStackTrace();
}
}

public ListSCE[] getActiveSCE(String mac, String ip, String pckgId) {
ListSCE[] sceList = null;

try {
sceList = port.getActiveSCE(mac, ip, pckgId);
} catch(RemoteException re) {
re.printStackTrace();
}

return sceList;
}

public static void main(String[] args) {
RPCCallHandler rpc = new RPCCallHandler();
ListSCE[] list = rpc.getActiveSCE(null, null, null);
for (int i = 0; i < list.length; i++)
printRecord(list);
}

public static void printRecord(ListSCE record) {
System.out.println("MAC: " + record.getMAC());
System.out.println("IP: " + record.getIP());
System.out.println("PackageId: " + record.getPackageId());
System.out.println("Start: " + record.getStart());
System.out.println("Update: " + record.getUpdate());
}
}


NaiveTrustManager.java:

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;

/**
* This Trust Manager is "naive" because it trusts everyone.
*
*/
public class NaiveTrustManager implements X509TrustManager {

/**
* Doesn't throw an exception, so this is how it approves a certificate.
*
* @see
* javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[],
* String)
*
*/
public void checkClientTrusted(X509Certificate[] cert, String authType)
throws CertificateException {
}

/**
* Doesn't throw an exception, so this is how it approves a certificate.
*
* @see
* javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[],
* String)
*
*/
public void checkServerTrusted(X509Certificate[] cert, String authType)
throws CertificateException {
}

/**
* @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
*
*/
public X509Certificate[] getAcceptedIssuers() {
return null; // I've seen someone return new X509Certificate[ 0 ];
}
}


MyClientTransportFactory.java:


import com.sun.xml.rpc.client.ClientTransport;
import com.sun.xml.rpc.client.ClientTransportFactory;

public class MyClientTransportFactory implements ClientTransportFactory {

public ClientTransport create() {
return new MyClientTransport();
}
}


MyClientTransport.java:


import com.sun.xml.rpc.soap.message.SOAPMessageContext;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;

public class MyClientTransport extends com.sun.xml.rpc.client.http.HttpClientTransport {

protected HttpURLConnection createHttpConnection(String s,
SOAPMessageContext ctx) throws IOException {
//PropertiesSingleton pSing = PropertiesSingleton.getInstance();
HttpsURLConnection httpURLConnection = (HttpsURLConnection) super
.createHttpConnection(s, ctx);

httpURLConnection.setReadTimeout(60 * 1000);
httpURLConnection.setConnectTimeout(60 * 1000);
httpURLConnection.setSSLSocketFactory(getSocketFactory());
return httpURLConnection;
}

private SSLSocketFactory getSocketFactory() {
SSLSocketFactory sslSocketFactory = null;
try {
TrustManager[] tm = new TrustManager[]{new NaiveTrustManager()};
SSLContext context = SSLContext.getInstance("SSL");
context.init(new KeyManager[0], tm, new SecureRandom());

sslSocketFactory = (SSLSocketFactory) context.getSocketFactory();

} catch (KeyManagementException e) {
System.out.println("No SSL algorithm support: " + e.getMessage());
//log.error("No SSL algorithm support: " + e.getMessage(), e);
} catch (NoSuchAlgorithmException e) {
System.out.println("Exception when setting up the Naive key management." + e.getMessage());
//log.error("Exception when setting up the Naive key management.", e);
}
return sslSocketFactory;
}
}


As you can see form above code I don't have to check certificates or anything. I just need "It's all good" so I can call the service and get response. If I deploy this code to WL (without the JAR and JVM option) I get the following exception:

java.rmi.RemoteException: HTTP transport error: java.lang.ClassCastException: weblogic.net.http.SOAPHttpsURLConnection cannot be cast to javax.net.ssl.HttpsURLConnection; nested exception is:
     HTTP transport error: java.lang.ClassCastException: weblogic.net.http.SOAPHttpsURLConnection cannot be cast to javax.net.ssl.HttpsURLConnection
     at ws.rpc.wifree.MyRpcServicePortType_Stub.activeSCE(MyRpcServicePortType_Stub.java:349)
     at data.proxy.RPCCallHandler.getActiveSCE(RPCCallHandler.java:137)
     at services.wifreedata.DataService.getActiveSCE(DataService.java:26)
     at services.wifreedata.DataService_r4j7fk_WSOImpl.__WL_invoke(Unknown Source)
     at weblogic.ejb.container.internal.WSOMethodInvoker.invoke(WSOMethodInvoker.java:23)
     at services.wifreedata.DataService_r4j7fk_WSOImpl.__WL_getActiveSCE_WS(Unknown Source)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
     at java.lang.reflect.Method.invoke(Method.java:597)
     at weblogic.wsee.server.ejb.WsEjb.invoke(WsEjb.java:54)
     at weblogic.wsee.jaxws.WLSEjbInstanceResolver$WLSEjbInvoker.invoke(WLSEjbInstanceResolver.java:196)
     at weblogic.wsee.jaxws.WLSInstanceResolver$WLSInvoker.invoke(WLSInstanceResolver.java:74)
     at com.sun.xml.ws.server.InvokerTube$2.invoke(InvokerTube.java:149)
     at com.sun.xml.ws.server.sei.SEIInvokerTube.processRequest(SEIInvokerTube.java:95)
     at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:892)
     at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:841)
     at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:804)
     at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:706)
     at com.sun.xml.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:430)
     at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:640)
     at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:265)
     at com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:163)
     at weblogic.wsee.jaxws.WLSServletAdapter.handle(WLSServletAdapter.java:171)
     at weblogic.wsee.jaxws.HttpServletAdapter$AuthorizedInvoke.run(HttpServletAdapter.java:708)
     at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
     at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
     at weblogic.wsee.util.ServerSecurityHelper.authenticatedInvoke(ServerSecurityHelper.java:103)
     at weblogic.wsee.jaxws.HttpServletAdapter$3.run(HttpServletAdapter.java:311)
     at weblogic.wsee.jaxws.HttpServletAdapter.post(HttpServletAdapter.java:336)
     at weblogic.wsee.jaxws.JAXWSServlet.doRequest(JAXWSServlet.java:99)
     at weblogic.servlet.http.AbstractAsyncServlet.service(AbstractAsyncServlet.java:99)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
     at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:242)
     at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:216)
     at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:132)
     at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:352)
     at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:235)
     at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3284)
     at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3254)
     at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
     at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
     at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
     at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2163)
     at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2089)
     at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2074)
     at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1512)
     at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254)
     at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
     at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
Caused by: HTTP transport error: java.lang.ClassCastException: weblogic.net.http.SOAPHttpsURLConnection cannot be cast to javax.net.ssl.HttpsURLConnection
     at com.sun.xml.rpc.client.http.HttpClientTransport.invoke(HttpClientTransport.java:140)
     at com.sun.xml.rpc.client.StreamingSender._send(StreamingSender.java:96)
     at ws.rpc.wifree.MyRpcServicePortType_Stub.activeSCE(MyRpcServicePortType_Stub.java:332)
     ... 49 more


I hope my description of a problem was thorough enough, if not feel free to ask additional questions.

What I'd like now is for somebody to tell me how to translate this code, so that it will work on WL as it does on Glassfish. In other words, I need to somehow ovrerride the SSL checking or somehow accomplish that checking always returns OK!

Regards Goran

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points