1 Reply Latest reply on Sep 12, 2001 10:27 PM by Nick Ganju

    Serious Problems with JSSE in JBoss

    Nick Ganju Newbie

      Hi,

      I have been trying to implement authentication using JAAS in my Struts based application running on JBoss.
      The application consists of some servlets implemented using Struts, and some session EJB implementing the business logic. Both the
      servlets and EJBs are secured and need a authenticated user to access them.

      The authentication works I that the user is authenticated and the Principal set on logon. But then when I try to make an EJB call
      on the next Struts action, I get Principal=null exception:

      20:15:30,188 ERROR [SecurityInterceptor] Authentication exception, principal=null
      20:15:30,198 ERROR [LogInterceptor] EJBException, causedBy:
      java.lang.SecurityException: Authentication exception, principal=null

      It seems that the Principal and authentication information is lost somewhere between the login action, where the authentication
      occurs, and the next action, where a EJB call is done...

      I have been using the http://www.javaworld.com/javaforums/showflat.php?Cat=2&Board=JavaSecurity&Number=2500&page=0&view=collapsed&sb=5&o=&fpart=1> Complete configuration of JAAS on JBOSS and STRUTS

      The login code looks like this:

      public ActionForward execute(...) {
      
       // Some code removed for simplicity
      
       SecurityAssociationHandler handler = new SecurityAssociationHandler();
       SimplePrincipal user = new SimplePrincipal(j_username);
       handler.setSecurityInfo(user, new String(j_password));
       LoginContext loginContext = new LoginContext("notatbase", (CallbackHandler)handler);
      
       loginContext.login();
       Subject subject = loginContext.getSubject();
      
       session.setAttribute("subject", subject);


      Now I check that the Subject is indeed set, and that I can access the EJB layer with the following code

      logger.debug("Subject: "+SecurityAssociation.getSubject().toString());
      
       UserAdminHome userhome = (UserAdminHome)EjbLookupUtility.lookupHome(UserAdminHome.JNDI_NAME);
       UserAdminRemote userbean = userhome.create();
       userbean.getCurrentUserDTO();


      This code works. The Subject is set, and the EJB call is successful. The following is printed out:

      20:15:29,847 DEBUG [LoginAction] Subject: Subject:
      Principal: ke@objectnet.no
      Principal: Roles(members:Member)
      20:15:29,877 DEBUG [UserAdminEJB] Using caller ke@objectnet.no as current user

      But on the next (Struts) action when the following code is executed the EJB call fails with the above exception.

      public ActionForward execute(...) {
      
       // Some code removed for simplicity
      
       if (SecurityAssociation.getSubject() != null)
       logger.debug("Subject: "+SecurityAssociation.getSubject().toString());
       else
       logger.debug("Subject is null");
      
       UserAdminHome userhome = (UserAdminHome)EjbLookupUtility.lookupHome(UserAdminHome.JNDI_NAME);
       UserAdminRemote userbean = userhome.create();
       userbean.getCurrentUserDTO();
      

      Here the Subject is null, and the userhome.create() call will throw the following execption:

      20:15:30,188 DEBUG [SystemInfoAction] Subject is null

      20:15:30,188 ERROR [SecurityInterceptor] Authentication exception, principal=null
      20:15:30,198 ERROR [LogInterceptor] EJBException, causedBy:
      java.lang.SecurityException: Authentication exception, principal=null

      What am I doing wrong here? Is there a bug in JBoss?
      I have used many days on this problem and have all but given up. If sombody have any ideas, clues or downright solutions,
      please let me know...

      Regards,
      - Chris

      More details:
      I am using JBoss 3.2.4 with Tomcat 5.0. I have also used JBoss 3.2.5 with the same result. To give a more complete picture of my
      implementation I have attached the files necesary to implement the security features in JBoss.

      The application is packed as a EAR with a WAR for the servlets and a JAR for the EJBs. The deployment descriptors looks like the
      following:

      In jboss.xml and jboss-web.xml I have added the following line to secure the servlets and EJBs:

      <security-domain>java:/jaas/notatbase</security-domain>


      In the login-config.xml I have added the following security domain:

      <application-policy name="notatbase">
       <authentication>
       <login-module code="org.jboss.security.ClientLoginModule" flag="required" />
       <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
       <module-option name="managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=NotatbaseDS</module-option>
       <module-option name="dsJndiName">java:/NotatbaseDS</module-option>
       <module-option name="principalsQuery">Select passwd as Password from users where email=?</module-option>
       <module-option name="rolesQuery">select 'Member' as Role, 'Roles' as RoleGroup from users where email=?</module-option>
       </login-module>
       </authentication>
       </application-policy>


      The ejb-jar.xml is a very long file, generated by XDoclet. This is only the most interesting part:

      <security-role>
       <description>[CDATA[description not supported yet by ejbdoclet]]</description>
       <role-name>Member</role-name>
       </security-role>
       <method-permission >
       <description>[CDATA[description not supported yet by ejbdoclet]]</description>
       <role-name>Member</role-name>
       <method >
       <description>[CDATA[]]</description>
       <ejb-name>UserAdmin</ejb-name>
       <method-intf>Home</method-intf>
       <method-name>create</method-name>
       <method-params>
       </method-params>
       </method>
       </method-permission>
       <method-permission >
       <description>[CDATA[description not supported yet by ejbdoclet]]</description>
       <role-name>Member</role-name>
       <method >
       <description>[CDATA[Gets the UserDTO for the current user.]]</description>
       <ejb-name>UserAdmin</ejb-name>
       <method-intf>Remote</method-intf>
       <method-name>getCurrentUserDTO</method-name>
       <method-params>
       </method-params>
       </method>
       </method-permission>
      

      The web.xml:

      <!-- notatbase, fails in auth-constraint, does not recognize role,
       and is therefore calling <form-login-page> anyway -->
       <security-constraint>
       <web-resource-collection>
       <web-resource-name>notatbase</web-resource-name>
       <description>Security constraint for all resources</description>
       <url-pattern>*.do</url-pattern>
       <http-method>GET</http-method>
       <http-method>POST</http-method>
       </web-resource-collection>
       <!-- the role which can access these resources
       <auth-constraint>
       <role-name>Member</role-name>
       </auth-constraint> -->
       <user-data-constraint>
       <description>no description</description>
       <transport-guarantee>NONE</transport-guarantee>
       </user-data-constraint>
       </security-constraint>
       <login-config>
       <auth-method>FORM</auth-method>
       <form-login-config>
       <form-login-page>/login.do</form-login-page>
       <form-error-page>/logout.do</form-error-page>
       </form-login-config>
       </login-config>
       <security-role>
       <description>A user allowed to invoke Member methods</description>
       <role-name>Member</role-name>
       </security-role>