Accessing EJB through HTTPS Invoker...
benoitx Aug 2, 2005 12:14 PMHello
I am stuck on a problem with accessing an EJB through a firewall via HTTP tunnelling.
Our client application is accessing the JNDI service using HTTPS and I seem to get the HOME interface. Unfortunately when I call create() on it to create the remote interface, I get the following exception:
java.rmi.ConnectException: Connection refused to host: myServer.com; nested exception is: java.net.ConnectException: Connection refused: connect at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574) at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185 ) at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:94) at org.jboss.invocation.jrmp.server.JRMPInvoker_Stub.invoke(Unknown Source) at org.jboss.invocation.jrmp.interfaces.JRMPInvokerProxy.invoke(JRMPInvo kerProxy.java:118) at org.jboss.invocation.InvokerInterceptor.invokeInvoker(InvokerIntercep tor.java:227) at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.jav a:167) at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor. java:46) ....
Which PORT is it trying to use? Only port 8443 is open! I have assumed, may be incorrectly, that by using JNDI over HTTPs, the EJB references would also go through the same port??? Is it the case?
How is a client supposed to be access the EJBs via HTTPs? Could anyone post an example? end-to-end? Many thanks!!!
Here my client code:
When I run it, I can see:
About to connect to JNDI HTTPS Got the HOME interface
but not "Got the REMOTE interface"!
System.out.println("Connect HTTPS"); Properties prop = System.getProperties(); prop.put("java.naming.factory.initial","org.jboss.naming.HttpNamingContextFactory"); prop.put("org.jboss.security.ignoreHttpsHost","true"); final int newPort = ConsoleMenu.getInt("Enter the port (current:" + 8443 +")", 8443); prop.put("java.naming.provider.url","https://"+host+":"+newPort+"/invoker/JNDIFactory"); // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { } } }; // Install the all-trusting trust manager try { SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (Exception e) { } try { System.err.println("About to connect to JNDI HTTPS"); InitialContext context = new InitialContext(prop); final Object objref = context.lookup("RefBean"); EJBHome anEJBHome = (EJBHome) PortableRemoteObject .narrow(objref, RefBean.class); System.err.println("Got the HOME interface"); remote = anEJBHome.create(); System.err.println("Got the REMOTE interface"); } catch (NamingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (CreateException e) { // TODO Auto-generated catch block e.printStackTrace(); }
The server expose the Naming service via http, here is the config for jboss-4.0.3RC1/server/default/deploy/http-invoker.sar/META-INF/jboss-service.xml
<!-- Expose the Naming service interface via HTTPS --> <mbean code="org.jboss.invocation.http.server.HttpProxyFactory" name="jboss:service=invoker,type=http,target=Naming"> <!-- The Naming service we are proxying --> <attribute name="InvokerName">jboss:service=Naming</attribute> <!-- Compose the invoker URL from the cluster node address --> <attribute name="InvokerURLPrefix">https://</attribute> <attribute name="InvokerURLSuffix">:8443/invoker/JMXInvokerServlet</attribute> <attribute name="UseHostName">true</attribute> <attribute name="ExportedInterface">org.jnp.interfaces.Naming</attribute> <attribute name="JndiName"></attribute> <attribute name="ClientInterceptors"> <interceptors> <interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor> <interceptor>org.jboss.proxy.SecurityInterceptor</interceptor> <interceptor>org.jboss.naming.interceptors.ExceptionInterceptor</interceptor> <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor> </interceptors> </attribute> </mbean>
and Tomcat is configured to have a https connector in jboss-4.0.3RC1/server/default/deploy/jbossweb-tomcat55.sar/server.xml
<!-- SSL/TLS Connector configuration using the admin devl guide keystore --> <!-- see http://www.huihoo.com/jboss/online_manual/3.2.3/Chap8.html --> <Connector port="8443" address="${jboss.bind.address}" maxThreads="100" strategy="ms" maxHttpHeaderSize="8192" emptySessionPath="true" scheme="https" secure="true" clientAuth="false" keystoreFile="${jboss.server.home.dir}/conf/chap8.keystore" keystorePass="rmi+ssl" sslProtocol = "TLS" />
Furthermore, JBoss is started with the following properties:
-Djava.rmi.server.hostname=myServer.com -Djava.rmi.server.useLocalHostname=false
This is to ensure that the server responds with its external address.
The main question is must I open extra ports in the firewall?, is there any way to use only HTTP over 8443?
How to access the EJB via https?
Any help would be greatly appreciated!
Thanks
Benoit