5 Replies Latest reply on Jun 18, 2010 4:47 PM by Chris Russell

    JBOSS 5.1.0GA + EJB/JNDI over HTTPS

    Jo Vandermeeren Newbie

      Hi there,

       

      I am trying to tunnel EJB and JNDI operations over a single HTTP(S) port by using the unified invoker.

       

      The client application is a Swing GUI launched via webstart.

      The server is the stock "default" JBoss 5.1.0GA application server.

       

      I have walked through the UnifiedInvoker guide (http://docs.jboss.org/jbossas/unified_invoker/UnifiedInvoker_guide.html#d0e63), the JBoss Remoting 2.5 documentation, and JBoss In Action.

       

      Basic HTTPS configuration went fine, but to get the tunneling part to work (and debug the network traffic more easily), I switched back to plain HTTP.

       

      Attempts:

      When I change the transport to http and use the use the mentioned Un/Marshallers as mentioned in the UnifiedInvoker guide, and change the client properties for the initial context, I get a server-side stack overflow error in the marshaller (http://pastebin.com/hST03ZFE).

      When I deploy the ServerInvokerServlet as mentioned in a wiki post (http://community.jboss.org/wiki/EJB3overHTTPHTTPSinJBossAS-5), communication still happens via socket 4446, not the desired port.

       

      Any help on getting this to work is greatly appreciated.

       

      Thanks in advance,

      Jo

        • 1. Re: JBOSS 5.1.0GA + EJB/JNDI over HTTPS
          wouter na Newbie

          +1

          Same issue, the configuration is a real pain in the ***!

          Is there any documentation on how to use remoting with https in JBOSS 5?

           

          regards

          • 2. Re: JBOSS 5.1.0GA + EJB/JNDI over HTTPS
            Chris Russell Newbie

            As per http://community.jboss.org/message/518953#518953

            And  http://community.jboss.org/wiki/EJB3overHTTPHTTPSinJBossAS-5

             

            I am able to make it work in both 5.0.1GA and 5.0.0EAP and 5.0.1SOA.

             

            I use iptables to block everything except 8443 then use wire shark and all communication takes place over 8443.

            I have only every used the @RemoteBinding method however not the xml config file.

             

            Here is the abreviated config and code

             

            The bean

            {code}

            @RemoteBinding(clientBindUrl = "https://10.0.0.75:8443/servlet-invoker/SSLServerInvokerServlet/?timeout=300000&invokerDestructionDelay=300000")
            public class AgencyManagerProxyBean implements AgencyManagerProxyRemote, AgencyManagerProxyLocal {

            {code}

             

            The thick client connection part looks like this

            {code}

                 securityClient = SecurityClientFactory.getSecurityClient();       
                    securityClient.setVmwideAssociation(true);

             

                    boolean loggedIn=false;
                    int tryCount=0;
                    while (!loggedIn) {
                    try {
                        tryCount++;
                   
                        // Ask for username and password this sets AgencyManagerPrefs values       
                        new LoginDialog(agencyManagerFrame);
                       
                       
                        //The username and password were set in the LoginDialog
                        String username = AgencyManagerPrefs.getProperty(AgencyManagerConstants.USERNAME_KEY);
                        String password = AgencyManagerPrefs.getProperty(AgencyManagerConstants.PASSWORD_KEY); 
                        //NOTE all this does is set some variables no actual login occurs
                        //that happens in the jndi lookup and initial ejb invocation level.
                        securityClient.setSimple(username, password);       
                        securityClient.login();        
                        logger.info("SecurityClient data set");
                       
                       
                        Properties props = new Properties();
                        props.put("java.naming.factory.initial", "org.jboss.naming.HttpNamingContextFactory");

             

                        String providerUrl = "https://"+AgencyManagerPrefs.getProperty(AgencyManagerConstants.AMPROXY_HOST_KEY)+":8443/invoker/JNDIFactory";
                       
                        props.put("java.naming.provider.url", providerUrl);
                       
                        //JBOSS claims we need this rather than security client.
                        props.put(Context.SECURITY_PRINCIPAL, username);
                        props.put(Context.SECURITY_CREDENTIALS, password);

             

                        props.put("java.naming.factory.url.pkgs", "org.jboss.naming");

             

                        Context ctx = new InitialContext(props);
                       
                        logger.info("Created context");
                        logger.info(ctx);
                        //logger.info(props);
                        logger.info("End Created context");
                       
                        logger.info("Lookup amproxyservice");       
                        AgencyManagerProxyInterface bean = (AgencyManagerProxyInterface) ctx.lookup("sec-amproxyservice/AgencyManagerProxyBean/remote");
                        logger.info("Got reference to bean");

            {code}

             

             

            The jboss 5.1 ga, 5.0eap, 5.0.1soa config changes

             

            == Open the SSL socket ==
            {noformat}
            edit server/default/deploy/jbossweb.sar/server.xml
            uncomment section "SSL/TLS Connector" to enable Connector port="8443"
            replace keystoreFile="${jboss.server.home.dir}/conf/chap8.keystore" with  your keystore name
            replace keystorePass="rmi+ssl" sslProtocol = "TLS" /> with keystorePass="<your new secure password>" sslProtocol = "TLS" />
            {noformat}

             

            == Expose JNDI Naming service via HTTPS ==
            Edit /opt/java/jboss/server/default/deploy/http-invoker.sar/META-INF/jboss-service.xml
            It needs to contain the following 2 entries. '''NOTE''' the http one below is commented out and should replace
            the '''matching un-commented''' one that is in the file by default.

            {code:xml}

            <pre>
               <!-- Expose the Naming service interface via HTTP
               <mbean code="org.jboss.invocation.http.server.HttpProxyFactory"
                  name="jboss:service=invoker,type=http,target=Naming">
                  <attribute name="InvokerName">jboss:service=Naming</attribute>
                  <attribute name="InvokerURLPrefix">http://</attribute>
                  <attribute name="InvokerURLSuffix">
                    <value-factory bean="ServiceBindingManager" method="getStringBinding">
                       <parameter>jboss.web:service=WebServer</parameter>
                       <parameter>:${port}/invoker/JMXInvokerServlet</parameter>
                    </value-factory>
                  </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>
               -->

             

               <!-- Expose the Naming service interface via HTTPS -->
               <mbean code="org.jboss.invocation.http.server.HttpProxyFactory"
                  name="jboss:service=invoker,type=http,target=Naming">
                  <attribute name="InvokerName">jboss:service=Naming</attribute>
                  <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>

             

            </pre>

            {code:xml}


            == Add the Servlet Invoker ==
            This will add the servlet invoker that allows us to do https jndi lookups and ejb invocations from clients over https.
            {noformat}
            $ cd /opt/java/jboss/server/default/deploy
            {noformat}
            Then create a file servlet-invoker-service.xml and a directory and file servlet-invoker.war/WEB-INF/web.xml
            The contents of these are as follows
            '''servlet-invoker-service.xml'''

            {code:xml}

            <pre>
            <?xml version="1.0" encoding="UTF-8"?>
            <!DOCTYPE web-app PUBLIC
               "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
               "http://java.sun.com/dtd/web-app_2_3.dtd">
            <web-app>
                <servlet>
                    <servlet-name>ServerInvokerServlet</servlet-name>
                    <description>The ServerInvokerServlet receives requests via HTTP
                       protocol from within a web container and passes it onto the
                       ServletServerInvoker for processing.
                    </description>
                    <servlet-class>org.jboss.remoting.transport.servlet.web.ServerInvokerServlet</servlet-class>
                    <init-param>
                        <param-name>locatorUrl</param-name>
                        <param-value>servlet://${jboss.bind.address}:8080/servlet-invoker/ServerInvokerServlet</param-value>
                        <description>The servlet server invoker</description>
                    </init-param>
                    <load-on-startup>1</load-on-startup>
                </servlet>

             

                <servlet>
                    <servlet-name>SSLServerInvokerServlet</servlet-name>
                    <description>The ServerInvokerServlet receives requests via HTTPS
                       protocol from within a web container and passes it onto the
                       ServletServerInvoker for processing.
                    </description>
                    <servlet-class>org.jboss.remoting.transport.servlet.web.ServerInvokerServlet</servlet-class>     
                    <init-param>
                        <param-name>locatorUrl</param-name>
                        <param-value>sslservlet://${jboss.bind.address}:8443/servlet-invoker/SSLServerInvokerServlet</param-value>
                        <description>The servlet server invoker</description>
                    </init-param>
                    <load-on-startup>2</load-on-startup>
                </servlet>
              
                <servlet-mapping>
                    <servlet-name>ServerInvokerServlet</servlet-name>
                    <url-pattern>/ServerInvokerServlet/*</url-pattern>
                </servlet-mapping>

             

                <servlet-mapping>
                    <servlet-name>SSLServerInvokerServlet</servlet-name>
                    <url-pattern>/SSLServerInvokerServlet/*</url-pattern>
                </servlet-mapping>
              
            </web-app>
            {code:xml}


            '''servlet-invoker.war/WEB-INF/web.xml'''

            {code:xml}
            <?xml version="1.0" encoding="UTF-8"?>
            <server>
              <mbean code="org.jboss.remoting.transport.Connector" name="jboss.remoting:service=connector,transport=servlet"
                display-name="Servlet transport Connector">
                <attribute name="InvokerLocator">servlet://${jboss.bind.address}:8080/servlet-invoker/ServerInvokerServlet</attribute>
                <attribute name="Configuration">
                  <handlers>
                    <handler subsystem="AOP">org.jboss.aspects.remoting.AOPRemotingInvocationHandler</handler>
                  </handlers>
                </attribute>
              </mbean>

             

              <mbean code="org.jboss.remoting.transport.Connector" name="jboss.remoting:service=connector,transport=sslservlet"
                display-name="Servlet transport Connector">
                <attribute name="InvokerLocator">sslservlet://${jboss.bind.address}:8443/servlet-invoker/SSLServerInvokerServlet</attribute>
                <attribute name="Configuration">
                  <handlers>
                    <handler subsystem="AOP">org.jboss.aspects.remoting.AOPRemotingInvocationHandler</handler>
                  </handlers>
                </attribute>
              </mbean>
            </server>

             

            {code:xml}

             

            == FIX EAP 5.0==
            If you dont do this clients will get the dreaded
            Caused by: java.net.ProtocolException: Server redirected too many  times (20)

             

            As per [http://community.jboss.org/thread/146840 Jira CR created]

             

            So to fix this particular issue I edited

             

            '''server/default/deploy/http-invoker.sar/invoker.war/WEB-INF/web.xml'''

             

            And commented out the url-pattern stuff at the bottom.

             

            Note I did try just setting the roles.properties to have my user have a HttpInvoker role but that did not work.
            {code:xml}
               <!-- An example security constraint that restricts access to the HTTP invoker
               to users with the role HttpInvoker Edit the roles to what you want and
               configure the WEB-INF/jboss-web.xml/security-domain element to reference
               the security domain you want.
               -->
               <security-constraint>
                  <web-resource-collection>
                     <web-resource-name>HttpInvokers</web-resource-name>
                     <description>An example security config that only allows users with the
                        role HttpInvoker to access the HTTP invoker servlets
                     </description>
                     <url-pattern>/restricted/*</url-pattern>
                 <!-- COMMENT OUT THIS AND 5.0 EAP works.
                     <url-pattern>/JNDIFactory/*</url-pattern>
                     <url-pattern>/EJBInvokerServlet/*</url-pattern>
                     <url-pattern>/JMXInvokerServlet/*</url-pattern>
                 -->
                     <http-method>GET</http-method>
                     <http-method>POST</http-method>
                  </web-resource-collection>
                  <auth-constraint>
                     <role-name>HttpInvoker</role-name>
                  </auth-constraint>
               </security-constraint>
            </pre>

            {code:xml}

            1 of 1 people found this helpful
            • 3. Re: JBOSS 5.1.0GA + EJB/JNDI over HTTPS
              Chris Russell Newbie

              Sorry for the markup goofups..not entirely used to the jboss wiki editor.

              Note that these directions assume a valid cert.

               

              If you create a self signed cert, then you will need to create a client.truststore file form the self signed cert

              and use some additional command line args when starting the thick client.

               

              e.g.

              -Dorg.jboss.security.ignoreHttpsHost=true -Djavax.net.ssl.trustStore=client.truststore -Djavax.net.ssl.trustStorePassword=foobar

               

              Note also that only the sun and bea jvms handle the ssl connections properly.

              The default java on most linuxes do not (or at least I dont know how) handle ssl properly.

              • 4. Re: JBOSS 5.1.0GA + EJB/JNDI over HTTPS
                Jo Vandermeeren Newbie

                Thanks for your response Chris.

                 

                However,  I did not get it to work with the unified invoker.

                So I decided to switch back to the JBoss 4.x way using the HTTP invoker directly and this worked fine.

                • 5. Re: JBOSS 5.1.0GA + EJB/JNDI over HTTPS
                  Chris Russell Newbie

                  Never tried the unified invoker.

                  Only the servlet invoker which worked well. Performance not that bad.

                  All of our calls are long running and so we thread those invocations and show

                  status dialogs so no particular issue on invocation performance.

                   

                  Let us know how the unified works out if you persue further.

                   

                  Wax Nostalgic:

                  What ever happened to the (Steven's unix programming) style books which lay out fully formed examples rather than

                  code snippits and esoteric references. A good programmer can come in on a new technology and pick up all the neuances in short order

                  but only if there are complete examples which fill in the blanks on what you normally use and or how to transition to the new tech.

                   

                  I agree there is not nearly enough documentation on how the invokers work, the

                  ack, nacks et all. It is stuck in someones head rather than laid out in documents as it should be.

                  (Yes I could go spend a week deciphering the code but cant because of reality and bills)

                   

                  I am also shocked that more people are not confused by the diff invoker capabilities and

                  which is best of breed. Which will prevail?

                  rmi over ssl

                  hhtps via servlet

                  unified (any) over ssl or https.

                  OpenSSO for the SOA platform (long shot client inclusion).

                   

                  I think too many people never make it past the demos to consider this.

                   

                  Good luck.