0 Replies Latest reply on Aug 12, 2002 10:28 AM by toni

    JBoss Tomcat Role Realm Security

    toni

      Hello,

      We are trying to set up Tomcat and JBoss, and need some advice. We have written a very simple test application to find out if we can use important features of the JSEE platform, like JNDI lookups, and the Security Model for Enterprise Beans.

      We intend to install Tomcat in one, and JBoss in another directory, and are not using the mbean configuration which intergrates Tomcat into JBoss via using an mbean.

      In the end we would like to achieve the following goals:

      JNDI
      We would like to use the InitalContext of JBoss to look up Session and Entity Beans running in the JBoss container.

      It would be nice if we could use a simple “new InitalContext()” and get the JNDI tree of the JBoss server instead of the Tomcat supplied JNDI Context, which get created if one sets the “useNaming” property to “true” in the server.xml config file.

      Since we could not figure out how to “import” the JNDI tree of JBoss and make it accessible using a simple “new InitalContext” call inside a JSP file, we connect to the JBoss JNDI Service using the following piece of code:

      Properties env = new Properties();
      env.setProperty(InitialContext.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
      env.setProperty(InitialContext.PROVIDER_URL, "localhost:1099");
      env.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");
      InitialContext initial = new InitialContext(env);

      ENETRPRISE BEANS
      We want to be able to lookup Session and Entity Beans which reside in the JBoss container. This works fine, if we use the InitalContext from above to retrieve the EJB’s. The following code gets executed and returns the expected results, if we disable the security model.

      --------------- CODE -----------------
      Object object = initial.lookup("TestSessionBean");
      out.println("Lookup of TestSessionBean was successful");
      TestSessionBeanHome session = (TestSessionBeanHome) javax.rmi.PortableRemoteObject.narrow(object, TestSessionBeanHome.class);
      out.println("Narrowing of TestSessionBean was also successful");
      TestSessionBeanRemote testSession = session.create();
      out.println("Call to TestSessionBean was successful\n Return message is: " + testSession.remoteCall());
      ------------------------------------------


      SECURITY
      We would like to authenticate users against a tomcat realm and then make forward the role to JBoss, so that the container can use it to enforce the security constraints on the EJB’s.

      For test purposes we are using the simple tomcat-users.xml config file and basic authentification. The Browser asks us for a user name and password and if entered correctly we can proceed. Then the session bean is retrieved and the corresponding function gets executed.

      This works, if we disable the security manager inside JBoss by not adding any security constraints to the deployment descriptor. Then we can call the session beans remoteCall() function without running into any problems.

      However if we enable the security manager and add security constraints to our session bean, we get a security exception.

      What is also strange is that the “sessionContext.getCallerPrincipal()” function does not return the tomcat role but the one which is assigned to unauthenticated JBoss users and which we can set inside the jboss.xml configuration file.

      It seems not to be possible to enforce the security constraints on the EJB’s using the authentification mechanism of the tomcat servlet container. Somehow the servlet engine does not forward the role to tomcat.

      The following text shows the ejb deployment descriptor (ejb.jar & jboss.xml) and the java code of the session been as well as the JSP file and the web application deployment descriptor for tomcat (web.xml & server.xml). In the end you will the security exception which gets thrown if we enable security.

      --------------- web.xml -----------------
      <?xml version="1.0" encoding="ISO-8859-1"?>
      <!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>

      <!-- Define a Security Constraint on our simple Application -->
      <security-constraint>
      <web-resource-collection>
      <web-resource-name>Entire Application</web-resource-name>
      <url-pattern>/index.jsp</url-pattern>
      </web-resource-collection>

      <!-- This role should actually get forwarded to tomcat -->
      <auth-constraint>
      <role-name>jboss</role-name>
      </auth-constraint>
      </security-constraint>

      <!-- Define the Login Configuration for this Application -->
      <login-config>
      <auth-method>BASIC</auth-method>
      <realm-name>jboss</realm-name>
      </login-config>

      <!-- We have tried using a ejb-reg but could get it working, so just igore this ...
      <ejb-ref>
      This is a reference to a session bean. It can be looked up under the name "TestBean"
      <ejb-ref-name>ejb/TestSessionBean</ejb-ref-name>
      <ejb-ref-type>Session</ejb-ref-type>
      ejb.TestSessionBeanHome
      ejb.TestSessionBeanRemote
      <ejb-link>jndi://localhost:1099/TestSessionBean</ejb-link>
      </ejb-ref>
      -->

      </web-app>

      --------------- server.xml -----------------










      <!-- Here comes our simple webapplication -->








      --------------- tomcat-users.xml -----------------
      <tomcat-users>

      </tomcat-users>

      --------------- ejb-jar.xml -----------------
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN' 'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
      <ejb-jar>
      <display-name>Our simple test ejb</display-name>

      <enterprise-beans>


      <ejb-name>TestSessionBean</ejb-name>
      ejb.community.TestSessionBeanHome
      ejb.community.TestSessionBeanRemote
      <ejb-class>ejb.community.TestSessionBean</ejb-class>
      <session-type>Stateless</session-type>
      <transaction-type>Container</transaction-type>


      </enterprise-beans>

      <assembly-descriptor>

      <security-role>
      Jboss role
      <role-name>jboss</role-name>
      </security-role>

      <method-permission>
      <role-name>jboss</role-name>

      <ejb-name>TestSessionBean</ejb-name>
      <method-name>*</method-name>

      </method-permission>

      </assembly-descriptor>

      </ejb-jar>

      --------------- jboss.xml -----------------
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN' 'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>


      <!— THIS ROLE GETS RETURNED BY THE CALL TO THE SESSION CONTEXTS getUserPrincipal() -->
      <unauthenticated-principal>nobody</unauthenticated-principal>

      <enterprise-beans>

      <ejb-name>TestSessionBean</ejb-name>

      </enterprise-beans>

      <!-- IF WE TAKE THIS OUT THEN WE CAN CALL THE SESSION BEANS METODS FROM THE JSP FILE -->
      <container-configurations>
      <container-configuration>
      <container-name>Standard Stateless SessionBean</container-name>
      <security-domain>java:/jaas/other</security-domain>
      </container-configuration>
      </container-configurations>



      --------------- TestSessionBean.java -----------------
      package ejb.community;

      import javax.ejb.*;
      import javax.naming.*;

      public class TestSessionBean implements SessionBean
      {
      public SessionContext sessionContext = null;

      public void ejbCreate(){}

      public String remoteCall()
      {

      try
      {
      return sessionContext.getCallerPrincipal().toString();
      }
      catch (Exception e)
      {
      return e.toString();
      }
      }

      public void ejbActivate(){}
      public void ejbPassivate(){}
      public void ejbRemove(){}
      public void setSessionContext(SessionContext ctx){ sessionContext = ctx;}
      }

      --------------- TestSessionBeanRemote.java -----------------
      package ejb.community;

      import java.rmi.RemoteException;

      public interface TestSessionBeanRemote extends javax.ejb.EJBObject
      {
      public String remoteCall() throws RemoteException;
      }

      --------------- TestSessionBeanHome.java -----------------
      package ejb.community;

      import javax.ejb.EJBHome;
      import java.rmi.RemoteException;

      public interface TestSessionBeanHome extends EJBHome
      {
      public TestSessionBeanRemote create() throws RemoteException;
      }