8 Replies Latest reply on Jan 19, 2010 11:15 AM by crussell42

    jboss AS 5.0.0.EAP ejb3 via https (servlet-invoker)

    crussell42

      Not sure if the community normaly answers questions about the jboss.com AS's but here goes

       

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

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

       

      I am able to access my ejb3's via the very execelent servlet-invoker from my swing client.

       

      Works great in AS 5.1.0.GA.

      Does not work in AS 5.0.0.EAP.

      Configured eap exactly the same way as ga.

      I do note that the remoting version of EAP is 2.5.2 and the version of remoting in the GA is 2.5.1

      which seems odd.

       

      java version "1.6.0_17"
      Java(TM) SE Runtime Environment (build 1.6.0_17-b04-248-10M3025)
      Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01-101, mixed mode)

       

       

      The exception thrown is

       

           [java] Looking up bean as user [ernie] pass[ernie]
           [java] SEEM TO BE LOGGED IN via SecurityClient
           [java] log4j:WARN No appenders could be found for logger (org.jboss.security.SecurityAssociation).
           [java] log4j:WARN Please initialize the log4j system properly.
           [java] javax.naming.NamingException: Failed to retrieve Naming interface for provider https://10.0.0.75:8443/invoker/JNDIFactory [Root exception is java.net.ProtocolException: Server redirected too many  times (20)]
           [java]     at org.jboss.naming.HttpNamingContextFactory.getInitialContext(HttpNamingContextFactory.java:96)
           [java]     at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
           [java]     at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
           [java]     at javax.naming.InitialContext.init(InitialContext.java:223)
           [java]     at javax.naming.InitialContext.<init>(InitialContext.java:197)
           [java]     at client.TestService.main(TestService.java:93)
           [java] Caused by: java.net.ProtocolException: Server redirected too many  times (20)
           [java]     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
           [java]     at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
           [java]     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
           [java]     at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
           [java]     at sun.net.www.protocol.http.HttpURLConnection$6.run(HttpURLConnection.java:1368)
           [java]     at java.security.AccessController.doPrivileged(Native Method)
           [java]     at sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.java:1362)
           [java]     at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1016)
           [java]     at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
           [java]     at org.jboss.naming.HttpNamingContextFactory.getNamingServer(HttpNamingContextFactory.java:209)
           [java]     at org.jboss.naming.HttpNamingContextFactory.getInitialContext(HttpNamingContextFactory.java:92)
           [java]     ... 5 more
           [java] Caused by: java.net.ProtocolException: Server redirected too many  times (20)
           [java]     at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1323)
           [java]     at sun.net.www.protocol.http.HttpURLConnection.getHeaderField(HttpURLConnection.java:2173)
           [java]     at java.net.URLConnection.getHeaderFieldInt(URLConnection.java:579)
           [java]     at java.net.URLConnection.getContentLength(URLConnection.java:474)
           [java]     at sun.net.www.protocol.https.HttpsURLConnectionImpl.getContentLength(HttpsURLConnectionImpl.java:378)
           [java]     at org.jboss.naming.HttpNamingContextFactory.getNamingServer(HttpNamingContextFactory.java:204)
           [java]     ... 6 more


        • 1. Re: jboss AS 5.0.0.EAP ejb3 via https (servlet-invoker)
          peterj

          You can always ask here about EAP questions, but if you have EAP you probably have a support contract (not quite sure what support one gets with an evaluation copy, though) and would get a quicker response by asking Red Hat support directly.

           

          I have never seen this error before. Could you perhaps post the code for TestService and hilghlight line 93.

           

          Also, you stated that you "Configured eap exactly the same way as ga." - exactly what did you do? Just deployed your EJBs with the same configuration? Or did you modify any of the configuration files in GA or EAP?

           

          Finally, which configuration(s) are you running? By default, GA uses the "default" configuration while EAP usues the "production" configuration.

          • 2. Re: jboss AS 5.0.0.EAP ejb3 via https (servlet-invoker)
            crussell42

            I use run.sh and so server is starting the default deployment.

            I can see where it is deploying my testservice.ear (which I deploy to default/deploy) so I'm pretty sure

            correct config is starting.

             

            I have dropped back to just a http rather than https test version so the ONLY config change I do is to add

            default/conf/users.properties and roles.properties

            ernie=ernie

            bert=bert

             

            ernie=participant

            bert=friend

             

            No other config changes needed as my ejbs use the "other" security domain.

            The TestService.java code is as follows

            All this works great if I run against 5.1.0GA

             

            package client;
            
            import com.hochheim.testservice.ejb.TestServiceInterface;
            
            import javax.naming.InitialContext;
            import javax.naming.Context;
            import javax.naming.NamingException;
            import java.util.Properties;
            import java.util.ArrayList;
            import java.util.Set;
            import javax.rmi.PortableRemoteObject;
            
            
            import javax.ejb.EJBAccessException;
            
            import org.jboss.security.client.SecurityClient;
            import org.jboss.security.client.SecurityClientFactory;
            
            
            
            public class TestService {
            
                public static void main(String[] args) {
                 String username="ernie";
                 String password="ernie";
                 SecurityClient securityClient=null;
                 try {
                     if (args.length>0) {
                          username = args[0];
                          if (args.length>1) {
                              password=args[1];
                          }
                     } else {
                          System.out.println("FORMAT ant run-test -Dusername=ernie -Dpassword=ernie");
                          System.exit(0);          
                     }
            
                     System.out.println("Looking up bean as user ["+username+"] pass["+password+"]");
            
            
                     //From http://msikora.typepad.com/michael_sikora_on_java_ee/2009/03/converting-to-jboss500ga-ejb3-security.html
            
                     try {
                      securityClient = SecurityClientFactory.getSecurityClient();
                      
                      securityClient.setSimple(username, password);
                      
                      securityClient.login(); 
            
                      System.out.println("SEEM TO BE LOGGED IN via SecurityClient");
                 
            
                            Properties props = new Properties();           
                      props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.HttpNamingContextFactory");
                      props.put(Context.PROVIDER_URL,"http://10.0.0.75:8080/invoker/JNDIFactory");
                      Context jndiContext = new InitialContext(props);
            
                      System.out.println("Created context");
                      System.out.println(jndiContext);
                      System.out.println(props);
                      System.out.println("End Created context");
            
                      TestServiceInterface bean = (TestServiceInterface)jndiContext.lookup("testservice/TestServiceBean/remote");
            
                      //RMI TestServiceInterface otherBean = (TestServiceInterface)jndiContext.lookup("testservice/OtherServiceBean/remotessl");
                      TestServiceInterface otherBean = (TestServiceInterface)jndiContext.lookup("testservice/OtherServiceBean/remote");
            
                      System.out.println("BEANS HAVE BEEN LOOKED UP");
            
                      System.out.println("TestService=====OUTPUT HERE IS FROM TestServiceBean.getInfo EJB call");
                      
                      try {
                          System.out.println(bean.getInfo());
                      } catch (Exception e1) {
                          //e1.printStackTrace();
                          System.out.println(e1.getMessage());
                      }
                      
                      System.out.println("TestService=====END OUTPUT FROM TestServiceBean.getInfo EJB call");
            
                      
                      //Client->EJB->OTHER-EJB
                      System.out.println("TestService=====OUTPUT HERE IS FROM TestServiceBean.getInfoOther");
            
                      try {
                          System.out.println(bean.getInfoOther());
                      } catch (Exception e2) {
                          //e2.printStackTrace();
                          System.out.println(e2.getMessage());
                      }
            
                      System.out.println("TestService=====END OUTPUT FROM TestServiceBean.getInfoOther()");
                      
            
            
                      //Client OTHER-EJB
            
                      System.out.println("TestService=====OUTPUT HERE IS FROM OtherServiceBean.getInfo EJB call");
                      
                      try {
                          System.out.println(otherBean.getInfo());
                      } catch (Exception e3) {
                          //e3.printStackTrace();
                          System.out.println(e3.getMessage());
                      }
                      
                      System.out.println("TestService=====END OUTPUT FROM OtherServiceBean.getInfo EJB call");
            
                      
            
            
                     } catch (Exception e) {
                      e.printStackTrace();
                      
                     } 
                     //finally {
                     //     securityClient.logout();
                     //     System.out.println("SecurityClient.logout()");
                     //
                     //}
            
            
            
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
                }
            }
            

             

            The ant target is

              <target name="run-test" depends="build-test">
                <java fork="true" classname="client.TestService">
                  <classpath>
                <pathelement location="built/classes/test"/>
                    </classpath>
                <classpath refid="test.classpath"/>
                <arg value = "${username}"/>
                <arg value = "${password}"/>
                </java>
               
              </target>


            • 3. Re: jboss AS 5.0.0.EAP ejb3 via https (servlet-invoker)
              crussell42

              EJB code very simple (here are ther pertinent parts)

               

              @Stateless
              @SecurityDomain("other")
              @RunAs("friend")
              public class TestServiceBean implements TestServiceRemote,TestServiceLocal {
              
                  @Resource SessionContext ctx;
              
                  @Resource(name="jaas/other", type=org.jboss.security.plugins.JaasSecurityManager.class,mappedName="java:/jaas/other") private JaasSecurityManager jaas;
              
              
               @RolesAllowed("participant")
                  public String getInfo() {
                   StringBuffer sb = new StringBuffer();
                   Principal caller = ctx.getCallerPrincipal();
                   log.info("TestServiceBean.getInfo caller ["+caller.getName()+"] and his roles");
              
                   Set rolesSet = jaas.getUserRoles(caller);
                   if (rolesSet!=null) {
                       Iterator it = rolesSet.iterator();
                       while (it.hasNext()) {
                        log.info("\nSECURITY ROLE FROM JAAS ["+it.next()+"]");
                       }
                   }
              
                      sb.append("\nHELLO FROM TestServiceBean.\n");
              
                   return(sb.toString());
                  }
              
              
              • 4. Re: jboss AS 5.0.0.EAP ejb3 via https (servlet-invoker)
                crussell42

                An interesting point is that if I am running the jboss-5.1.0.GA version and use a browser to

                access http://10.0.0.75:8080/invoker/JNDIFactory

                I get a message from the browser about what do I want to do with the result

                application/x-serialized-java-object.

                 

                When I do the same test against the jboss-eap-5.0 version I get a http access login page (authentication required)

                "The site says authentication required for JBoss HTTPInvoker."

                • 5. Re: jboss AS 5.0.0.EAP ejb3 via https (servlet-invoker)
                  crussell42

                  This turns out to be a security-domain defaulting to restrict access to invokers.

                  Found this resource in the Wiki

                   

                  http://community.jboss.org/wiki/HowToRunTheTestsuiteAgainstJBossEAP

                   

                  So to fix this particular issue I edited

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

                  And commented out the url-pattern stuff.

                  Note I did try just setting the roles.properties to have my user have a HttpInvoker role but that did not work.

                     <!-- 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>

                  • 6. Re: jboss AS 5.0.0.EAP ejb3 via https (servlet-invoker)
                    crussell42

                    Note that I attempted to add my user with role HttpInvoker to the props/jmx-console-users and roles.properties

                    but I get the same error.

                     

                    Not sure what teh disconnect is:

                    http-invoker.sar/invoker.war/WEB-INF/jboss-web.xml has security contenxt

                    <jboss-web>
                       <security-domain>java:/jaas/jmx-console</security-domain>
                    </jboss-web>

                     

                    And login-config has

                      <application-policy name="jmx-console">
                        <authentication>
                          <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
                            flag="required">
                            <module-option name="usersProperties">props/jmx-console-users.properties</module-option>
                            <module-option name="rolesProperties">props/jmx-console-roles.properties</module-option>
                          </login-module>
                        </authentication>
                      </application-policy>

                     

                    And I added my user to default/conf/props/jmx-console-users and roles.properties.

                    Yet I get the same error described above.

                    • 7. Re: jboss AS 5.0.0.EAP ejb3 via https (servlet-invoker)
                      jaikiran

                      Moving this to an appropriate forum.

                      • 8. Re: jboss AS 5.0.0.EAP ejb3 via https (servlet-invoker)
                        crussell42

                        The issue was that in my client I was not setting the SECURITY_PRINCIPAL and SECURITY_CREDENTIALS in the

                        naming context.

                         

                        So there was a confusion with the use of SecurityClient.

                        That is, with the following code, it works as expected:

                         

                                Properties props = new Properties();
                                props.put("java.naming.factory.initial", "org.jboss.naming.HttpNamingContextFactory");
                                props.put("java.naming.provider.url", "https://10.0.0.75:8443/invoker/JNDIFactory");

                         

                                props.put(Context.SECURITY_PRINCIPAL, username);
                                props.put(Context.SECURITY_CREDENTIALS, password);

                         

                                props.put("java.naming.factory.url.pkgs", "org.jboss.naming");
                                Context jndiContext = new InitialContext(props);

                         

                        I had assumed that with the new remoting code that the PRINCIPAL and CREDENTIALS

                        were no longer used in HttpNamingContextFactory but I believe that is only the case for

                        org.jboss.security.jndi.JndiLoginInitialContextFactory