1 2 Previous Next 20 Replies Latest reply on Jan 31, 2005 11:41 PM by Agam Aviananta

    securing a remote client for a simple session bean

    Dave Haas Newbie

      I ran into the same problem. As a workaround I included all the
      %JBOSS_HOME%\lib\*.jar in my CLASSPATH and was able to run the
      program. Example

      set JBOSS_HOME=C:\jboss-4.0.0DR2
      set CLASSPATH=%JBOSS_HOME%\lib\bcel.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\commons-httpclient.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\concurrent.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\dom4j.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\getopt.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\gnu-regexp.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\javassist.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\jboss-aop.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\jboss-boot.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\jboss-common.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\jboss-jmx.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\jboss-remoting.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\jboss-system.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\jdom.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\log4j-boot.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\trove.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\webdavlib.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\xercesImpl.jar;%CLASSPATH%
      set CLASSPATH=%JBOSS_HOME%\lib\xml-apis.jar;%CLASSPATH%

        • 1. Re: securing a remote client for a simple session bean
          Thomas Cherel Novice

          With JAAS, there is really two security context to configured. One on the server and one on the client.
          According to your email it seems that you configured the one on the server correctly.

          On the client, you need to perform a JAAS login that will use the org.jboss.security.ClientLoginModule JAAS module. This module will actually be the one doing the association with the server context (make sure that credentials are passed down to the server automatically for the authentication process).
          Take a look at the JDK JAAS tutorial to see the code to write in your client to do the JAAS login.
          From a configuration point of view, the easiest thing to do is to create a file called auth.conf with the following content:

          client-login {
           org.jboss.security.ClientLoginModule required;

          and to run your client JVM with the following option:

          -Djava.security.auth.login.config=[path to auth.conf]

          In you code, you will have to make sure that, when you are building the LoginContext, the first argument is a string matching the one in the auth.conf (identifying which set of JAAS modules to use):

          LoginContext lc = new LoginContext("client-login", handler);


          • 2. Re: securing a remote client for a simple session bean
            spoonman464 Newbie

            It looks like several of us are all working on the same problem and having the same difficulties. I have seen many partial answers and many partial code examples and I have read just about everything there is on this topic yet I cannot get it to work either.

            As I understand that there are 2 ways for getting a Java client in another JVM to authenticate so that it can access public, secured methods of an EJB running on JBoss. 1) use the LoginContext way OR 2) use the slick, but not J2EE-standard, JNDI way. It appears in either case, the path is treacherous notwithstanding all the effort that has gone into trying to produce a very simple, complete, durable, useful, and correct example of each technique.

            The LoginContext way:

            The LoginContext way is technically the "proper" JAAS way to do the login. You need two primary lines of code

            LoginContext lc = new LoginContext(String clientLoginModuleName,new UsernamePasswordHandler(String username, char[] password));

            Those lines being a bit generic, here are the real ones I'm using. They are based on the exact same security domain configuration as the "jmx-console" domain that ships with JBoss:

            LoginContext lc = new LoginContext("spoonware",new UsernamePasswordHandler("admin","admin".toCharArray()));

            The new LoginContext() is expecting to be told the name of the client login module and the username/password credentials in a CallbackHandler of some sort. (There have been several different ones presented in several examples but I still can't get them working which continues to suggest that I've got something configured incorrectly or not at all on the client.)

            With a little new LoginContext() and a login() method call, the examples say that you should get logged in. Or do they? It seems that you don't really get logged in. Instead, your credentials get associated with the thread your program is running on. Any subsequent calls you make to an EJB will present those credentials so that the security-domain configured for that EJB will be consulted to see if those credentials match the user.properties file. If so, a Principal is created (I think) and its roles are granted and off the client goes on its merry way interacting with the EJBs to the limit of its access.

            The JNDI way:

            Not being much of a Java programmer to begin with, I look for the "configuration-oriented" approach to avoid writing code. Although the JNDI approach is not J2EE spec, it's handy and at the moment I'd be happy with ANY method of authentication that works and I'll stand on ceremony later. By studying this approach I have found that the following code example should work but does not.

            In my client code, I have the following:

            Properties props = new Properties();
            props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.security.jndi.LoginInitialContextFactory");
            props.put(Context.PROVIDER_URL, "localhost:1099");
            props.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
            Context ctx = new InitialContext(props);

            One important point that is easy to overlook is that the name of the INITIAL_CONTEXT_FACTORY changes when you are trying to use the JNDI approach to logging in. It changes from

            (This point is not trivial either as the LoginInitialContextFactory is not in any of the jboss client JARs but is found in the server JARs in jbosssx.jar. It would have taken you some time to find it....)

            My test environment is strong:

            I believe that the environment I am working in is valid for this experiment. I have an ejb-jar deployed with 4 entity beans. I have a separate web-app with JSPs that correspond to the 4 beans so that I can add, update, delete, and display data from these 4 beans. Each pair of beans is in a relationship. For 2 months I have been using these beans from the JSPs and from a Lotus Notes client running Notes agents written in Java. Everything works great. I even got the beans and the JSPs working under a single security domain I called "spoonware". That domain is configured in the server's login-config.xml file as follows:

            <application-policy name = "spoonware">
             <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
             flag = "required" >
             <module-option name = "unauthenticatedIdentity">guest</module-option>

            There are two files, roles.properties and users.properties in the WEB-INF\classes folder in the WAR for the web app with the JSPs. These files have the name=password and name=roles settings to establish who the users are and what their passwords are, etc. For the web app and the secured EJBs, those users and roles work perfectly.

            So, I am convinced that the spoonware domain works correctly for EJBs and Web Apps. It will probably also work for my Lotus Notes apps once I can get logged in.

            Now it gets difficult:

            Regardless if one uses either of the two approaches to logging in, there is still something very important going on configuration-wise on the client that nobody's talking about. (Maybe they are but I'm not finding what they are saying.) That word you use in the SECURITY_PROTOCOL field is really important!! It must related to some configuration by the same name, probably in the auth.conf file for the client BUT, I don't know where that file should go or how to get my Lotus Notes JVM to read it.

            The example client code in the JAAS How To shows the LoginContext thing as follows. I've left out the entire example to focus on the LoginContext part:

             AppCallbackHandler handler = new AppCallbackHandler(name, password);
             LoginContext lc = new LoginContext("TestClient", handler);
             System.out.println("Created LoginContext");
             catch (LoginException le)
             System.out.println("Login failed");

            It's got some high-zook CallbackHandler but it's just a a CallbackHandler. In this example, however, the name of the client login module is "TestClient". I can't find the word "TestClient" anywhere else in the entire JAAS HowTo so it's hard to tell exactly what that word refers to. (I really tried it. You know the little dog thing that searches in WinXP? It looks inside the files ifyou tell it to and there was no other reference to the word "TestClient", so we guess again..)

            Here's where I need help:
            What am I missing?
            What's up with the auth.conf file?
            Where does it go?
            How do I tell my JVM to look for it and use it?
            On the server in the login-config.xml file, there is the following application-policy declaration. When I put "client-login" as the first argument to my new LoginContext() OR when I use it as the value for the SECURITY_PROTOCOL field in the JNDI properties, does my Java client do anything at all with this server-based declaration? Probably not because the client JVM probably needs the auth.conf file.

            <application-policy name = "client-login">
             <login-module code = "org.jboss.security.ClientLoginModule"
             flag = "required">

            So, if I have an auth.conf file like the one below, does give meaning to the expression "client-login"?

            client-login {
             org.jboss.security.ClientLoginModule required;

            And, if this is the final piece, where does it go? <JAVA_HOME> somewhere? In the jvm\lib\lib directory with the jndi.properties file? In the jvm\lib\security directory with the java.security and java.policy files?
            Or does it go somewhere else? Or does it not really matter and I'm missing the boat entirely some other way?

            See how treacherous it is?


            • 3. Re: securing a remote client for a simple session bean
              Thomas Cherel Novice

              I am no JNDI authenticatione expert (except that I read somewhere that JBoss does not support it).
              For the JAAS one, the JAAS tutorial available with the standard JDK provides all the naswer you need, in particular about this auth.conf file that can be located anywhere as long as you provide a path to it using the -Djava.security.auth.login.config option at the startup of your JVM.

              You have other ways to provide this file as well. See http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/spec/com/sun/security/auth/login/ConfigFile.html and http://java.sun.com/j2se/1.4.2/docs/api/javax/security/auth/login/Configuration.html.

              See http://java.sun.com/j2se/1.4.2/docs/guide/security/jgss/tutorials/AcnOnly.html for more details.


              • 4. Re: securing a remote client for a simple session bean
                Dave Haas Newbie

                Hi all.

                I'm sooooo close to the solution to this ;) Maybe in a week or so I'll have it !!

                OK. So, here's my setup.

                Step 1)

                Configure JBoss with an application-policy in the login-config.xml file (which is located in $JBOSS_HOME/server/default)

                In said login-config.xml file I have the following ...

                 <application-policy name = "simpleSB">
                 <login-module code = "org.jboss.security.ClientLoginModule" flag = "required">
                 <module-option name="usersProperties">users.properties</module-option>
                 <module-option name="rolesProperties">roles.properties</module-option>

                which, as far as I understand it sets up a realm called simpleSB. In users.properties I have:


                and in roles.properties I have:


                which, as far as I understand it sets up the user 'david' with the password 'david' and the role 'tester'

                Step 2)

                Create a simple session bean. One method (ok, 2) that simply echo "Hello World". The class is called Printer.

                The class:

                package com.powder.ejb;
                import java.rmi.*;
                import javax.ejb.*;
                public class Printer implements SessionBean {
                 public void ejbActivate() {
                 public void ejbPassivate() {
                 public void ejbCreate() {
                 public void ejbRemove() {
                 public void setSessionContext(SessionContext ctx) throws EJBException, RemoteException {
                 // TODO store session context reference
                 // actual bean methods
                 public String printHello() {
                 return "Hello from inside the session bean!";
                 public String printHelloThere(String name) {
                 return "Hello there, " + name + ", from inside the session bean!";

                The Remote interface:

                package com.powder.ejb;
                import java.rmi.*;
                import javax.ejb.*;
                public interface PrinterRemote extends EJBObject {
                 public String printHello() throws RemoteException;
                 public String printHelloThere(String name) throws RemoteException;

                The Home interface:

                package com.powder.ejb;
                import java.rmi.*;
                import javax.ejb.*;
                public interface PrinterHome extends EJBHome {
                 PrinterRemote create() throws RemoteException, CreateException;

                Step 3)

                Configure the ejb-jar.xml descriptor to put in some security :


                Step 4)

                Set up the jboss.xml descriptor to use the proper jndi name and realm:


                Step 5)

                Start setting up the client end of things. To use the LoginContext idea you have to a) set up a callback handler that supplies the username and password, b) set up the authorization file to tell the client JVM which authorization proxy class is going to be used, and c) run the client JVM with the argument to show where the auth file is.

                NOTE (i changed square brackets in the code to parenthesis to get around formatting issues in this BB)


                package com.powder.ejb;
                import java.io.IOException;
                import javax.security.auth.callback.*;
                public class PrinterClientCallbackHandler implements CallbackHandler {
                 private String username;
                 private String password;
                 public PrinterClientCallbackHandler(String username, String password) {
                 this.username = username;
                 this.password = password;
                 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
                 for (int i=0; i<callbacks.length; i++) {
                 if (callbacks(i) instanceof NameCallback) {
                 NameCallback nc = (NameCallback)callbacks(i);
                 } else if (callbacks(i) instanceof PasswordCallback) {
                 PasswordCallback pc = (PasswordCallback)callbacks(i);
                 } else {
                 throw new UnsupportedCallbackException(callbacks(i), "unrecognized callback");


                I set up a file called auth.conf in the directory where my Eclipse project is running ( /home/davidh/eclipse/workspace/simpleSessionBean/auth.conf) and I supply the argument -Djava.auth.login.config=above-path when I start the JVM.

                The file looks like:

                simpleSB {
                 org.jboss.security.ClientLoginModule required;


                This is my client program:

                package com.powder.ejb;
                import java.util.*;
                import javax.naming.*;
                import javax.security.auth.login.*;
                public class PrinterClient {
                 public static void main(String[] args) {
                 try {
                 String username = "david";
                 String password = "david";
                 PrinterClientCallbackHandler ch = new PrinterClientCallbackHandler(username, password);
                 LoginContext lc = new LoginContext("simpleSB", ch);
                 System.out.println("Login context successfully created");
                 Properties prop = new Properties();
                 prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
                 prop.put(Context.PROVIDER_URL, "localhost:1099");
                 Context ctx = new InitialContext(prop);
                 Object objref = ctx.lookup("ejb/simple");
                 PrinterHome home = (PrinterHome) javax.rmi.PortableRemoteObject.narrow(objref, PrinterHome.class);
                 PrinterRemote printer = (PrinterRemote)home.create();
                 } catch (Exception e) {

                Now, when I run the client the login credentials are sent to the server but the proper role (tester) is not assigned to the principal as evidenced by the error message:

                java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
                 java.rmi.AccessException: SecurityException; nested exception is:
                 java.lang.SecurityException: Insufficient method permissions, principal=david, method=create, interface=HOME, requiredRoles=[tester], principalRoles=null

                Any thoughts?


                Dave Haas

                • 5. Re: securing a remote client for a simple session bean
                  Thomas Cherel Novice

                  I believe that what is wrong in your setup is the login module configured in your login-config.xml.
                  In order to use the user and role flat files, the login module to use (code attribute of the login-module element) is org.jboss.security.auth.spi.UsersRolesLoginModule and not org.jboss.security.ClientLoginModule.

                  You will also have to make sure that the users.properties and roles.properties files are in your classpath somewhere (if you package them in the jar file containing your ejb-jar.xml it should work).


                  • 6. Re: securing a remote client for a simple session bean
                    dminnigerode Newbie

                    I'd agree with tcherel.

                    I spent some time sorting out all these issues myself. Once I got it working I put together a doc about it. You might find it useful.


                    • 7. Re: securing a remote client for a simple session bean
                      Dave Haas Newbie


                      That was it. Serves me right for going too fast and not looking closely enough at the class being created to handle the parse of the XML file.

                      Many thanks Thomas!

                      • 8. So, did you get it working?
                        spoonman464 Newbie

                        Mine is still not. Like every other Java/J2EE puzzle, you just have to keep slugging it out until you get it. There's just no other way...

                        I'm increasingly more convinced that my problem is related to not having a way to tell my JVM where the auth.conf file is. Every reference I can find says to do it with -Djava.blah.blah.blah.... but there must also be another way.

                        One reference said something about assigning the
                        java.security.auth.login.config equal to a URL that points to the file and that is exactly what happens when one uses the -Djava approach. But, it didn't say what a java.security.auth.login.config is, which file it must be stated in, or how you address using it to point to the file location.

                        At the moment, I'm trying to use this approach:
                        In the jvm\lib\security directory of my JVM, there is a file called java.security. In that file, I guessed and added the following line:


                        and I put my auth.conf file in that /lib/security directory. The contents of the auth.conf file are as follows:

                        client-login {
                         org.jboss.security.ClientLoginModule required;

                        In my java client code, I have the following about the JNDI lookup.
                        Properties props = new Properties();
                        props.put Context.INITIAL_CONTEXT_FACTORY, "org.jboss.security.jndi.LoginInitialContextFactory");
                        props.put(Context.PROVIDER_URL, "localhost:1099");
                        props.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
                        Context ctx = new InitialContext(props);

                        That should be enough to get me an InitialContext with a LoginContext behind the scenes, but alas, it does not.

                        Anyone else have any ideas?


                        • 9. Re: securing a remote client for a simple session bean
                          Thomas Cherel Novice

                          Check the javadoc that I pointed out before (http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/spec/com/sun/security/auth/login/ConfigFile.html and http://java.sun.com/j2se/1.4.2/docs/api/javax/security/auth/login/Configuration.html).

                          They should really tell you everything that you need to know about providing this file.
                          Of course, if you do not have full control of the JVM environment and startup code (you mentioned Lotus note as a client earlier), then this might not work or require extra configurations. But this will be Lotus specific, not JAAS/J2EE/Java.


                          • 10. I looked at the stuff and it doesn't tell me
                            spoonman464 Newbie

                            Thanks so much for posting those URLs but there was almost nothing about the java.security.auth.login.config (i.e. mentioned only once)
                            and nothing at all about how to include a auth.conf file in any way other than using the -Djava approach.

                            Now, I realize that I'm maybe using a JVM that somehow limits me on what I can do but the thing I want to do is so absolutely core, basic, and essential to any application (security) that I can't imagine that there's no way to do it.

                            That java.security.auth.login.config goes in some file, somewhere with some predictable file name. It gets as a value some file location in some format, possibly even http://hostname/filename, assuming that there is some http server running with the task of hosting this file which seems a little odd even if the http server were local. An assumed alternative for the file location is an actual path and filename which is what I plan to try next.

                            At any rate, there is a file configuration parameter in some java configuration file that is standard for all JVMs that tells the JVM to look for and use a .conf file for security stuff. I believe it in my gut that the thing I seek exists and is the most simple of all things yet ellusive as all can be. Somebody knows....

                            Please tell me....


                            • 11. Inching ever closer
                              spoonman464 Newbie

                              To try to divide and conquer this problem some more, I've decided to attack the java.security and java.policy files in the jvm\lib\security directory of the Lotus Notes JVM. These files and their behaviors ought to be fairly normal for a JVM regardless of whether its running inside Notes or not, or not.

                              I have pared down the java.policy file to just this:

                              grant {
                               permission java.security.AllPermission;

                              My java.security file has an interesting addition that I found somewhere out on the internet...

                              That code is supposed to declare whose config file format I intend to use and the second line says where my config file is. It turns out that an auth.conf file is trickier to deal with than a simple java.login.config.
                              So, I made a config file with the following contents:
                              client-login {
                               org.jboss.security.ClientLoginModule required;

                              So now I'm expecting my client to work a little better. Here's the current version of my client:
                              Properties props = new Properties();
                              props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
                              props.put(Context.PROVIDER_URL, "localhost:1099");
                              props.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
                              LoginHandler lh = new LoginHandler("admin","admin");
                              LoginContext lc = new LoginContext("client-login",lh);
                              Context ctx = new InitialContext(props);

                              I get an exception about javax.xml.parsers.FactoryConfigurationError class not being found right when the client tries to do the new LoginContext(). I removed the out statements that confirm for me where it blows up. That error seems to be a symptom so I'm still heading in the same direction.
                              Assuming that my LoginHandler is OK, I still can't get a LoginContext.

                              Maybe I have to try something else.


                              • 12. Still trying more stuff to get this thing working.
                                spoonman464 Newbie

                                I've become a little bit suspect of something in my java.security file:

                                # Class to instantiate as the javax.security.auth.login.Configuration
                                # provider.

                                So it makes me wonder. Am I using the correct value for the login.configuration.provider?

                                Anybody know?


                                • 13. Re: securing a remote client for a simple session bean
                                  Thomas Cherel Novice

                                  This looks correct to me.
                                  com.sun.security.auth.login.ConfigFile is the default configturation provider that understands the auth.conf file format and location that you are defining.

                                  Without a stack trace, it is hard to further diagnose your problem.


                                  • 14. Here's stack trace
                                    spoonman464 Newbie

                                    Being the novice Java guy I am, I've never really been able to make much out of a stack trace but here you go. It's all of the System.out stuff including my silly little messages so that I know which line of code explodes.

                                    I tried putting a JAR file containing the javax.xml.parsers classes in the lib\ext directory of the Notes JVM. It made a different error about the class version not being up to date...

                                    About to create the LoginHandler
                                    About to get initial context!
                                    Got initial context!
                                    About the create the LoginContext
                                    java.lang.NoClassDefFoundError: javax/xml/parsers/FactoryConfigurationError
                                    at javax.security.auth.login.Configuration.getConfiguration(Configuration.java:39)
                                    at javax.security.auth.login.LoginContext$1.run(LoginContext.java:84)
                                    at java.security.AccessController.doPrivileged(Native Method)
                                    at javax.security.auth.login.LoginContext.<init>(LoginContext.java:87)
                                    at javax.security.auth.login.LoginContext.<init>(LoginContext.java:49)
                                    at PublishAuthors.NotesMain(PublishAuthors.java:76)
                                    at lotus.domino.AgentBase.runNotes(Unknown Source)
                                    at lotus.domino.NotesThread.run(NotesThread.java:215)

                                    So, is there some clue in this stack trace that tells you anything I could use to solve my problem?


                                    1 2 Previous Next