1 2 Previous Next 19 Replies Latest reply on Sep 11, 2008 12:29 AM by eefahs

    JAAS Authentication from stand alone client

    eefahs

      Hi,

      I am new to JBoss and JAAS authentication. If someone can help me in the following it will be of great help.

      I want to validate my username and password from the database table and these values are captured via Java Swing standalone client. I dont have a concept of Role, I just want to validate the usename and password.

      I have created my Loginmodule which implements javax.security.auth.spi.LoginModule and its login method will call my DAO class and will do the validation of the username and password. And in the java swing client, I will get the username and password from the user. and will create the LoginContext and will call the login method.
      In the client side jaas configuration file I configured my login module and in the server login-context.xml, I declared my security domain.

      But how to link the sever side and client side?
      Where do I have to keep the LoginModule files in the client or server?
      What are all the configurations required in the client side?
      What are all the configurations required in the server side?
      Without the concept of Roles can we do the authentication using JAAS, if yes how?

      There are somany examples/articles on declarative authetication, Is there any article or example available for complete programatic authetication From a STAND ALONE client?

      where should I start? I am using JBOSS jboss-4.2.2.GA and cleint side java Swing

      If someone can direct me to the right direction, it will be of great help...

        • 1. Re: JAAS Authentication from stand alone client
          eefahs

          No Help?

          I think I have to explain more..

          I have an already running application in weblogic and whose username, passowrd validation is done using jaas and all other role based autherisation checks are done programaatically and i want to port the application to JBoss. But in Jboss, it seems it support only declarative security and it always requires Roles.. Am I correct?
          I have a bean which will do the username and password verification with db and from my login module I want to call this bean rather than configuring query with the login module.

          Someone please respond....

          • 2. Re: JAAS Authentication from stand alone client
            ragavgomatam

            HI
            Quick answers :- Since it is java client
            (1) You would be using a callback handler on the client to connect to your Jaas Module.
            (2) Your CustomModule should be in a jar file under $HOME/server/default/lib
            (3) The classpath in run.sh or run.bat of jboss should be changed to include your jar
            (4) You would be useing an auth.config policy file as a part of your client start up & use this syntax, please check this out once again :-

            java -Djava.security.manager -Djava.security.auth.login.config==file:../conf/default/auth.conf

            watch that ==.
            (5) This auth.conf would be having the ClientLoginModule in addition to your module . The format should be as of a policy file.
            (6) Use jars from $HOME/jboss/client in your client classpath. There are many jars from this directory, I don't immediately recall. However if using jdk 1.6 use classpath wildcard to use all the jars.


            This should be good as a start. I will try to post more if this is insufficient

            • 3. Re: JAAS Authentication from stand alone client
              eefahs

              Hi,

              Thank you very much for the response, I think I need more help..

              Yes, I am using CallbackHandler.
              I think I need to explain my requirement little bit more....


              In my application initially it comes with a login screen and after user enters a username and password and presss login button it will create a LoginContext as follows
              new LoginContext("myJaas", subject, new MyCallbackHandler(UserId, Password, serverUrl));

              and then it will call loginContext.login()


              And in my client side I have created a jaas.config file as follows

              myJaas {
              org.jboss.security.ClientLoginModule required;
              com.my.security.jboss.db.DbLoginModuleImpl required debug=false authOnLogin=true;
              };


              SO it should internally call the login methods of each of these loginModules... (So For this we have to copy the LoginModule jar file to client side also right?)
              and my DbLoginModuleImpl is as follows and the login method will just validate the useid and password with the database column values. If both exists in db, the method will return true. and the jaas authentication ends there...

              Here is my LoginModule

              final public class DbLoginModuleImpl implements LoginModule {
              private Subject subject;
              private CallbackHandler callbackHandler;
              private boolean isloginSucceeded;
              private boolean isprincipalsInSubject;
              private boolean isException;
              private ArrayList principalsForSubject = new ArrayList();


              public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
              this.subject = subject;
              this.callbackHandler = callbackHandler;
              }

              public boolean login() throws LoginException {

              String userName = null;
              String passwordHave = null;
              String airlineCode = null;

              Callback[] callbacks = getCallbacks();
              String userValue = getUserName(callbacks);
              userName = userValue;
              if (userName.length() > 0) {
              passwordHave = getPasswordHave(userName, callbacks);
              }

              if (validateUser(userName, passwordHave)) {
              System.out.println("DbLoginModuleImpl.login() :: VALID USER");
              SessionPrincipal sessionPrincipal = new SessionPrincipal(userName);
              principalsForSubject.add(sessionPrincipal);
              isloginSucceeded = true;
              return true;
              } else {
              System.out.println("DbLoginModule.login() :: INVALID USER");
              throw new FailedLoginException("Invalid User");
              }
              } catch (SystemException systemException) {
              throw new FailedLoginException(systemException.getErrorCode());
              }
              } finally {
              System.out.println("DbLoginModule exiting login()");
              }

              }

              public boolean commit() throws LoginException {
              if (isloginSucceeded) {
              subject.getPrincipals().addAll(principalsForSubject);
              subject.getPublicCredentials().addAll(principalsForSubject);
              subject.getPrivateCredentials().addAll(principalsForSubject);
              isprincipalsInSubject = true;
              return true;
              } else {
              return false;
              }
              }

              public boolean abort() throws LoginException {
              if (isprincipalsInSubject) {
              subject.getPrincipals().removeAll(principalsForSubject);
              isprincipalsInSubject = false;
              }
              return true;
              }

              public boolean logout() throws LoginException {
              return true;
              }

              }



              But the problem with JBOSS is that, it will not execute the login method immediately when we called the logincontext.login() Am I correct?

              It will execute it only when we try to execute method on a EJB for which we define a <security-domain>java:/jaas/myJaas</security-domain>. Also for that EJB we have to declare <security-role-ref> attribute with the required roles.

              And in my case i dont have a role, if the LoginModule.login method validates the username and password successfully, it should be allowed to execute the above bean method also... how can I achieve this?

              Basically, I just want to validate the username and password with the JAAS authentication no roles nothing...

              Help me..

              • 4. Re: JAAS Authentication from stand alone client
                ragavgomatam

                2 issues here. Lets take the first one. You will have to change your login module to extend jboss AbstractServerLoginModule as follows :-

                Here is my LoginModule

                final public class DbLoginModuleImpl implements LoginModule {


                to

                final public class DbLoginModuleImpl implements AbstractServerLoginModule {


                There is a posting for this whole code somewhere earlier in this forum, on how to extend this jboss AbstractServerLoginModule & do a database authentication.

                Second issue :- You cannot use a JAAS module only for authentication. JAAS stands for Authentication & Authorization. So as a part of logging in you will have to authenticate & also provide roles. These roles are then used by container in conjunction with j2ee artifacts (web.xml & ejb-jar.xml) to provide role based declarative authorization.This whole process is intimately tied with Roles in j2ee security architecture. Thats why you have
                role
                elements in web.xml and ejb-jar.xml.


                If, however you want to provide default Roles, then go ahead, provide default roles & use these in your module and the web.xml and ejb-jar.xml. However you WILL have to provide roles.




                • 5. Re: JAAS Authentication from stand alone client
                  eefahs

                  Hi Ragav,

                  Thanks for the reply and Now I changed my LoginModule based on your reply. and decided to go with a default role for all users.

                  And I have created a jar file for my loginmodule and copied it to
                  server\{myDomain}\lib folder and when I tried to run the client I am getting the following exception in the server.log


                  **********************************************************

                  2008-08-26 10:14:07,811 TRACE [org.jboss.security.SecurityAssociation] getPrincipal, principal=MASTER#V1
                  2008-08-26 10:14:07,811 TRACE [org.jboss.security.plugins.JaasSecurityManager.myJaas] Begin isValid, principal:MASTER#V1, cache info: null
                  2008-08-26 10:14:07,811 TRACE [org.jboss.security.plugins.JaasSecurityManager.myJaas] defaultLogin, principal=MASTER#V1
                  2008-08-26 10:14:07,811 TRACE [org.jboss.security.auth.login.XMLLoginConfigImpl] Begin getAppConfigurationEntry(myJaas), size=9
                  2008-08-26 10:14:07,811 TRACE [org.jboss.security.auth.login.XMLLoginConfigImpl] End getAppConfigurationEntry(myJaas), authInfo=AppConfigurationEntry[]:
                  [0]
                  LoginModule Class: com.jboss.db.MyLoginModuleImpl
                  ControlFlag: LoginModuleControlFlag: required
                  Options:
                  2008-08-26 10:14:07,811 ERROR [org.jboss.ejb.plugins.LogInterceptor] Unexpected Error in method: public abstract com.security.controller.SecurityController com.security.controller.SecurityControllerHome.create() throws javax.ejb.CreateException,java.rmi.RemoteException
                  java.lang.NoClassDefFoundError: org/jboss/security/auth/spi/AbstractServerLoginModule at java.lang.ClassLoader.defineClass1(Native Method)
                  at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
                  at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
                  at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
                  at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
                  at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
                  at java.security.AccessController.doPrivileged(Native Method)
                  at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
                  at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
                  at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
                  at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
                  at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
                  at org.jboss.mx.loading.RepositoryClassLoader.loadClassLocally(RepositoryClassLoader.java:200)
                  at org.jboss.mx.loading.ClassLoadingTask$ThreadTask.run(ClassLoadingTask.java:131)
                  at org.jboss.mx.loading.LoadMgr3.nextTask(LoadMgr3.java:399)
                  at org.jboss.mx.loading.RepositoryClassLoader.loadClassImpl(RepositoryClassLoader.java:527)
                  at org.jboss.mx.loading.RepositoryClassLoader.loadClass(RepositoryClassLoader.java:415)
                  at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
                  at org.jboss.util.loading.DelegatingClassLoader.loadClass(DelegatingClassLoader.java:92)
                  at org.jboss.mx.loading.LoaderRepositoryClassLoader.loadClass(LoaderRepositoryClassLoader.java:90)
                  at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
                  at org.jboss.util.loading.DelegatingClassLoader.loadClass(DelegatingClassLoader.java:92)
                  at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
                  at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
                  at java.lang.Class.forName0(Native Method)
                  at java.lang.Class.forName(Class.java:242)
                  at javax.security.auth.login.LoginContext.invoke(LoginContext.java:731)
                  at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
                  at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683)
                  at java.security.AccessController.doPrivileged(Native Method)
                  at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
                  at javax.security.auth.login.LoginContext.login(LoginContext.java:579)
                  at org.jboss.security.plugins.JaasSecurityManager.defaultLogin(JaasSecurityManager.java:603)
                  at org.jboss.security.plugins.JaasSecurityManager.authenticate(JaasSecurityManager.java:537)
                  at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:344)
                  at org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityAssociation(SecurityInterceptor.java:211)
                  at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:135)
                  at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:132)
                  at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invokeHome(ProxyFactoryFinderInterceptor.java:107)
                  at org.jboss.ejb.SessionContainer.internalInvokeHome(SessionContainer.java:637)
                  at org.jboss.ejb.Container.invoke(Container.java:981)
                  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                  at java.lang.reflect.Method.invoke(Method.java:585)
                  at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
                  at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
                  at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
                  at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
                  at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
                  at org.jboss.invocation.local.LocalInvoker$MBeanServerAction.invoke(LocalInvoker.java:169)
                  at org.jboss.invocation.local.LocalInvoker.invoke(LocalInvoker.java:118)
                  at org.jboss.invocation.InvokerInterceptor.invokeLocal(InvokerInterceptor.java:209)
                  at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:195)
                  at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:61)
                  at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:70)
                  at org.jboss.proxy.ejb.HomeInterceptor.invoke(HomeInterceptor.java:184)
                  at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:100)
                  at $Proxy654.create(Unknown Source)
                  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                  at java.lang.reflect.Method.invoke(Method.java:585)

                  **********************************************************



                  1) Why NoClassDefFoundError: org/jboss/security/auth/spi/AbstractServerLoginModule Error? do I have to bundle jbosssx.jar with my loginmodule jarfile? Why it is not taking from the same folder? I tried by giving ClassPath entry in METAINF file also.

                  2) Do I have to copy my loginmodule jar file to the clients classpath?

                  Tanks in advance

                  • 6. Re: JAAS Authentication from stand alone client
                    eefahs

                    Hi,

                    With some changes atlast the call reached my LoginModule. Thanks for your help. But

                    How can I access an ejb which resides in another ear file from My LoginModule? For validating my user I want to use an existing EJB method call.
                    EJB is deployed as an application and MyLoginModule jar file is kept in the server/[mmyconf]/lib folder



                    • 7. Re: JAAS Authentication from stand alone client
                      ragavgomatam

                       

                      How can I access an ejb which resides in another ear file from My LoginModule? For validating my user I want to use an existing EJB method call.

                      Wouldn't that be a re-entrant call ? You are trying to secure a resource, but as a part of the login, you are trying to access the resource you are trying to protect !!!! It will be a circularity. To solve this , cut the ejb out of the picture from the LoginModule & use a simple, straight database call. Once authenticated, ejb's are protected by this Principal. Also LoginModule is for the entire server, not a particular EAR


                      • 8. Re: JAAS Authentication from stand alone client
                        eefahs

                        Hi,

                        Thanks for the reply and Now I changed my LoginModule to remove the ejb call and ti works perfectly . again few more clarifications will be helpfull


                        I have deployed my application as a folder, which contains multiple jar files. and I have specified <security-domain> for only one jar that is security.jar. Now the authentication is successfull and my commit method looks like below

                        
                        public boolean commit() throws LoginException {
                         if (isloginSucceeded) {
                         try{
                         Set principals = subject.getPrincipals();
                         principals.add(principal);
                         Group[] roleSets = getRoleSets();
                         for(int g = 0; g < roleSets.length; g ++) {
                         Group group = roleSets[g];
                         String name = group.getName();
                         Group subjectGroup = createGroup(name, principals);
                         if( subjectGroup instanceof NestableGroup ) {
                         SimpleGroup tmp = new SimpleGroup("Roles");
                         subjectGroup.addMember(tmp);
                         subjectGroup = tmp;
                         }
                         Enumeration members = group.members();
                         while( members.hasMoreElements() ) {
                         Principal role = (Principal) members.nextElement();
                         subjectGroup.addMember(role);
                         }
                         }
                         isprincipalsInSubject = true;
                         }catch(Exception e){
                         e.printStackTrace();
                         }
                         return true;
                         } else {
                         return false;
                         }
                        }
                        


                        Now, I want to lookup a ejb of my security.jar from another jar file. I added correct <security-role-ref> entries but I am getting the error as

                        Caused by: javax.security.auth.login.LoginException: Username not supplied.
                        at com.ibsplc.iRes.security.jboss.db.JDbLoginModuleImpl.throwLoginException(JDbLoginModuleImpl.java:322)
                        at com.ibsplc.iRes.security.jboss.db.JDbLoginModuleImpl.getUserName(JDbLoginModuleImpl.java:368)
                        at com.ibsplc.iRes.security.jboss.db.JDbLoginModuleImpl.login(JDbLoginModuleImpl.java:164)


                        So it is again calling CallBackHandler for getting the username and password. How can I avoid this? How can I cache the Callback details.


                        Thanks in advance


                        • 9. Re: JAAS Authentication from stand alone client
                          eefahs

                          More details..

                          My application is devided into different subsystems and each subsystem is a different jar.
                          and one of my jar is defined with a security domain and the initial call to this subsystem triggered the login method and it was successfull and user logged into the system.

                          And the same user was accessing an ejb from another subsystem which was internally refering the subsystem with security domain defined. again the login method triggered (why is it every call need a login call?) and it was trying to get the username, ofcourse it was null and the call failed.

                          I tried by defining the role security-role-ref for the calling subsystem ejb, but it fails in the login.. How to handle this situation?

                          Thanks in advance

                          • 10. Re: JAAS Authentication from stand alone client
                            ragavgomatam

                            Are you using a java client ?
                            How is this done ?

                            And the same user was accessing an ejb from another subsystem


                            Point is, if you using a java client then Authentication is per login. Which means , you login from your java client, access the secured ejb, do your work & log out. If you call a unsecured subsystem, then login has to happen before access is granted to the secured resource.

                            Hope this explains

                            • 11. Re: JAAS Authentication from stand alone client
                              eefahs

                              Hi ragav,

                              Yes I am using a java client, yes first the user will login to the system by accessing the secured subsystem and after that he can access any other subsystem without any authentication, that is my requirement.


                              But, after successfull login when the user trying to use a unsecured subsystem and an ejb from this unsecured subsystem wants to access a ejb from the secured subsystem the call fails with the error


                              Caused by: javax.security.auth.login.LoginException: Username not supplied.
                              at com.ibsplc.iRes.security.jboss.db.JDbLoginModuleImpl.throwLoginException(JDbLoginModuleImpl.java:322)
                              at com.ibsplc.iRes.security.jboss.db.JDbLoginModuleImpl.getUserName(JDbLoginModuleImpl.java:368)
                              at com.ibsplc.iRes.security.jboss.db.JDbLoginModuleImpl.login(JDbLoginModuleImpl.java:164)


                              user - accessing secured ejb - internall calls LoginModule.login() login successfull

                              - accessiing unsecured ejb - successfull

                              - accessing a unsecured ejb, which calls secured ejb - failes


                              So how this unsecured ejb can be enabled to call a secured ejb? I tried by defining the appropriate security-role-ref for the unsecured ejb also. But again the call from unsecured subsystem to the secured subsystem triggers the LoginModule.login() and the username is null;

                              Is something wrong in my logic?



                              • 12. Re: JAAS Authentication from stand alone client
                                ragavgomatam

                                 

                                user - accessing secured ejb - internall calls LoginModule.login() login successfull

                                - accessiing unsecured ejb - successfull

                                - accessing a unsecured ejb, which calls secured ejb - failes


                                Post the code that does this

                                • 13. Re: JAAS Authentication from stand alone client
                                  ragavgomatam

                                  Also I think here is where the problem lies

                                  - accessing a unsecured ejb, which calls secured ejb - failes

                                  Where is the jaas login done before you access a secured ejb ?

                                  • 14. Re: JAAS Authentication from stand alone client
                                    eefahs

                                    Hi ragav,

                                    While starting up my java client, it will ask for a username and password and entring the username and password, when the user enters the submit(login) button, it will create LoginContext and will call logon and then try to call the secured ejb and then will cal a unsecured ejb for logon auditing purpose... so all the calls will trigger from the single logon button click.


                                    Class homeClass = getEJBHomeClass(serviceName);
                                     context = (InitialContext) getNewInitialContext(serverName);
                                     EJBHome ejbHome = (EJBHome) context.lookup(ejbService.getJndiName());
                                     obj = PortableRemoteObject.narrow(ejbHome, homeClass);
                                     ejbObject = (EJBObject) obj.create();



                                    Above is the details of the call to the server. After login when we call the secured ejb, it will trigger the login and the login is successfull and the call to the secured ejb is also successfull. So aftre both these calls, server itself will create a jms message for audit and it will put in a queue and an MDB will pick the message and for processign this message MDB will try to call the secured EJB, then the problem comes... it is saying that the username is null so login failed and so the call will fail.

                                    hope the flow is clear now

                                    what should i do now?

                                    1 2 Previous Next