1 Reply Latest reply on Jan 2, 2004 12:49 PM by Viet

    Howto: Calling EJB:s using EJB security and nukes userdefini

    Per-Erik Lindskog Newbie

      Hi all!

      Here is how to call EJB:s from Nukes, using EJB security with Nukes User- database. I have tested this using Jboss 3.2.2 and MySQL.

      Step 1: Define a JBoss security domain using Nukes security definitions.

      This is to tell JBoss EJB-layer how to access Nukes user database. Insert the following xml-fragment into the file %JBOSS_HOME%/server/default/conf/login-config.xml. There are already a number of security domains defined in that file, and this code should be inserted anywhere among the other definitions.

       <application-policy name = "nukes">
       <authentication>
       <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "required">
       <module-option name="unauthenticatedIdentity">guest</module-option>
       <module-option name="dsJndiName">java:/NukesDS</module-option>
       <module-option name="principalsQuery">select pn_pass from nuke_users where pn_uname=?</module-option>
       <module-option name="rolesQuery">select grp.pn_name, 'Roles' from nuke_groups grp, nuke_users usr, nuke_group_membership mem where usr.pn_uname=? and grp.pn_gid=mem.pn_gid and mem.pn_uid=usr.pn_uid</module-option>
       </login-module>
       </authentication>
       </application-policy>
      


      Step 2: Declare security in the EJB.

      You probably use Xdoclet or some other tool to make these definitions, but I give you here the resulting xml-files in the ejb-jar.

      In the ejb-jar.xml:
      Nothing JBoss- or Nukes specific here.
      Declare the security roles in the assembly-descriptor-tag. These should be the same as your Nukes Groups.
       <security-role>
       <role-name>Admins</role-name>
       </security-role>
       <security-role>
       <role-name>Users</role-name>
       </security-role>
      


      Declare the method-permissions in the assembly-descriptor-tag. I suggest that you, in addition to you business methods, declare the method "ejbCreate" as unchecked.
       <method-permission >
       <unchecked/>
       <method >
       <ejb-name>MyEjb</ejb-name>
       <method-intf>Home</method-intf>
       <method-name>create</method-name>
       <method-params />
       </method>
       </method-permission>
      


      In jboss.xml:

      Set the security-domain and the unauthenticated-principal tags as in the following example. We defined both of those values in Step 1 above.
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 2.4//EN" "http://www.jboss.org/j2ee/dtd/jboss_2_4.dtd">
      
      <jboss>
       <security-domain>java:/jaas/nukes</security-domain>
       <unauthenticated-principal>guest</unauthenticated-principal>
      
       <enterprise-beans>
       <session>
       <ejb-name>MyEjb</ejb-name>
       <jndi-name>ejb/MyEjbHome</jndi-name>
       </session>
       </enterprise-beans>
      </jboss>
      

      Deploy the ejb.

      Step 3: Write the module or block.

      Here is the complete code of a sample module that calls a secured ejb an displays the result.
      /*
       * Created on 2004-jan-02
       *
       */
      package com.wizlog.demo.modules;
      
      import javax.ejb.CreateException;
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      import javax.security.auth.callback.Callback;
      import javax.security.auth.callback.CallbackHandler;
      import javax.security.auth.callback.NameCallback;
      import javax.security.auth.callback.PasswordCallback;
      import javax.security.auth.callback.UnsupportedCallbackException;
      import javax.security.auth.login.LoginContext;
      import javax.security.auth.login.LoginException;
      
      import org.jboss.nukes.html.Page;
      import org.jboss.nukes.module.ModuleSupport;
      
      import com.wizlog.demo.interfaces.MyEjb;
      import com.wizlog.demo.interfaces.MyEjbHome;
      
      /**
       * Sample module.
       *
       * @author Per-Erik Lindskog, Wizlog AB
       */
      public class MyModule extends ModuleSupport {
      
       /**
       * @param name
       */
       public MyModule(String name) {
       super(name);
       }
      
       public void main(Page page) {
      
       // Transfer the login information to the client-login LoginContext
       String username = null;
       String password = "";
       LoginContext loginctx = null;
       if (this.getApi().userLoggedIn()) {
       username = this.getApi().currentUser().getUserName();
       password = this.getApi().currentUser().getPassword();
       CallbackHandler callbackHandler = null;
       callbackHandler = new UserPasswordHandler(username, password);
       try {
       String module = "client-login";
       loginctx = new LoginContext(module, callbackHandler);
       loginctx.login();
       } catch (LoginException e1) {
       e1.printStackTrace();
       }
       }
      
       // Make the ejb call
       InitialContext context;
       MyEjbHome home;
       MyEJb myejb;
       try {
      
       context = new InitialContext();
       home = (MyEjbHome) context.lookup("ejb/MyEjbHome");
       myejb = home.create();
      
       // Execute the call
       String result = myejb.myMethod();
      
       // Display the result
       page.print("The result is: " + result);
      
       } catch (java.io.IOException e) {
       e.printStackTrace();
       } catch (NamingException e) {
       e.printStackTrace();
       } catch (CreateException e) {
       e.printStackTrace();
       }
      
       // Clear the LoginContext
       if (loginctx != null) {
       try {
       loginctx.logout();
       } catch (LoginException e1) {
       }
       }
       }
      
       /**
       * Simple JAAS callback handler that provides username and password.
       */
       private class UserPasswordHandler implements CallbackHandler {
       private String username;
       private char[] password;
      
       /**
       * Constructs a callback handler.
       */
       UserPasswordHandler(String username, String password) {
       this.username = username;
       this.password = password.toCharArray();
       }
      
       /**
       * Handles the JAAS callbacks.
       */
       public void handle(Callback[] callbacks)
       throws UnsupportedCallbackException {
       for (int i = 0; i < callbacks.length; i++)
       if (callbacks instanceof NameCallback)
       ((NameCallback) callbacks).setName(username);
       else if (callbacks instanceof PasswordCallback)
       ((PasswordCallback) callbacks).setPassword(password);
       else
       throw new UnsupportedCallbackException(callbacks);
       }
       }
      
       }
      


      A part of this code is written and published by Peter Dornbush (http://www.luminis.nl/publications/websecurity.html)

      A big thanks to him, and to all you people out there that makes all of this possible.

      Good luck!

      Brgds / Perre