12 Replies Latest reply on May 11, 2006 2:19 PM by chris griffith

    Get list of users from JBoss AS?

    Jeff Storck Newbie

      I'll preface this post by saying that I'm new to J2EE. My problem is that some of our code that ran on Tomcat 5.0.28 doesn't work on JBoss 4.0.3CR2.

      Principal p = request.getUserPrincipal();


      This code in Tomcat 5.0.28 returned a principle that we could use to reflectively invoke 'getRealm' to get the LDAP config info that was stored in our webapp's context.xml. In JBoss 4.0.3CR2, it returns a SimplePrinciple which doesn't have the 'getRealm' method. This is the root of the problem, but it's not really what I want to fix. I want to remove the LDAP dependency from our code and just query JAAS or the app server itself, whichever is the more proper J2EE way to do it.

      There's a servlet that gets a list of users in a specific role, which are added to a combo box in a JSP. Here's the code that sets up the connection to LDAP:

      Object r = p.getClass().getMethod("getRealm", null).invoke(p, null);
      
      // The hashtable to hold the LDAP details to setup the connection
      Hashtable env = new Hashtable ();
      
      // Pull all the relevant data out of the realm with reflection
      String connectionFactory = (String) r.getClass().getMethod("getContextFactory", null).invoke (r, null);
      String connectionName = (String) r.getClass().getMethod("getConnectionName", null).invoke (r, null);
      String connectionPassword = (String) r.getClass().getMethod("getConnectionPassword", null).invoke (r, null);
      String connectionURL = (String) r.getClass().getMethod ("getConnectionURL", null).invoke (r, null);
      String authentication = (String) r.getClass().getMethod("getAuthentication", null).invoke (r, null);
      String protocol = (String) r.getClass().getMethod("getProtocol", null).invoke (r, null);
      String referrals = (String) r.getClass().getMethod ("getReferrals", null).invoke (r, null);
      
      String userBase = (String) r.getClass().getMethod ("getUserBase", null).invoke (r, null);
      String roleBase = (String) r.getClass().getMethod ("getRoleBase", null).invoke (r, null);


      This code may be "bad" because I'm sure there are much better ways to do this. I didn't write it but I'm looking to replace it with something not dependent on LDAP.

      I know what this code is doing, pulling out the LDAP config information that Tomcat read from the context.xml (which is where database connections and Realms were defined in Tomcat 5.0.28), and then using that to set up the JNDI lookup to reconnect to the LDAP server.

      Here's the question though: Shouldn't there be a way to query the application server for this information instead of going directly to LDAP? This creates a dependency I don't want in the code. If we take away LDAP and switch JBoss to a JAAS policy using file-based authentication for some reason, the code trying to get to LDAP will fail.

      If I switched out the LDAP lookups to JAAS lookups, that would work. Or if it's more "proper" to query the app server in some other way, I'd like to find out how.

      Sorry for a bit of a jumbled post. I hope someone can point me in the right direction. Using google up until now has been an exercise in information overload for me. :)

      - Jeff


        • 1. Re: Get list of users from JBoss AS?
          chris griffith Expert

          Hey Jeff,

          Well I can't seem to get thru to tomcat's website right now to look up something, but I will give a go anyway. First off, I would have to say this is the most perverted use of Reflection I have seen.

          The specification for container managed authentication which is implemented by Tomcat does not allow an application to query the authentication service to find users. It's purpose is to authenticate/authorize the one current user and it is supposed to be external from the application. So, what you are asking for is something that should be handled by your application. As such, you can perform an LDAP lookup from within your servlet. If you want to externalize the parameters of the lookup, use env-ref or context parameters.

          let me know if does not make sense or if you need more details.
          later, cgriffith

          • 2. Re: Get list of users from JBoss AS?
            Jeff Storck Newbie

            cgriffith,

            I agree that the use of reflection there is really bad. As I said, I didn't write it, and wouldn't. It works in Tomcat, but it seems really wrong.

            It sounds like you are saying that web apps shouldn't be able to get a list of users that are in a specific role from the application server or JAAS, that's disappointing.

            Let me put it into more specific terms though. Basically we're assigning tasks to users. The "admin" comes in, creates tasks, and assigns them to users.

            It's a bonus if the user list can be displayed to the admin in a combo box or list. I have already written "better" code to pull the list of users out of LDAP (Active Directory, really), but I don't want that LDAP dependency in there.

            Is it possible to query JAAS the same way one queries LDAP? That way all the specifics of where the user list comes from is abstracted out of the application -- it's all handled by the JAAS policies.

            Sorry if I seem thick-headed in this... it would seem very odd to me if there's no good J2EE abstract way to get the user list...

            Thanks for your reply!

            - Jeff

            • 3. Re: Get list of users from JBoss AS?
              chris griffith Expert

              Hello Jeff,

              Just to be clear, I never said an application should not have access to the list of users. In fact there is good reason to have such a function as you described. What I am saying is that no web application (i.e. servlet, jsp, etc...) should be able to directly access the container managed security implementation. In your case, your application should not be talking with the realm. The notion of a realm should not even be accessible to your application.

              That said, your usecase is valid, so the question remains. How to allow an administrator access to user accounts. The answer is to provide this function as part of your application. To be more clear. Develop your application to access the store of user data. You mention that you do not want your application to be dependant on LDAP directly. So don't let it be. That's the beauty of OOD. Develop a layer between your web application and the actual LDAP code. Your web application get account info from this layer; which in turn talks to the your persistent store du jour. What should be obvious to anyone reading this, that what you need is to develop some EJB's that do this. That is what JBoss is for. Again, if you need more detail, let me know.

              happy ejb'in, cgriffith

              • 4. Re: Get list of users from JBoss AS?
                Jeff Storck Newbie

                cgriffith,

                I would like my web app to get the usernames from JAAS, so that no matter what the policy in use at the time the web app is running, it will use whatever policy is set. If I do what you said, and create a layer between the app and LDAP, I'm still going directly to LDAP. That's what I'm trying to avoid. The layer that you're suggesting I create is already there -- JAAS. I just don't know if I can use it that way, and the seaching I've done on Google hasn't really shed any light.

                Even creating EJBs seems to be the wrong answer. I don't know EJB at all, but I am guessing that I would have to create a different set of EJBs for LDAP, file-based, and database user stores -- along with any other way that admins would want to store their users' accounts. This seems like a bad idea, and not very efficient. JAAS already has the ability to access a large set of resources for athenticating/authorizing user accounts, so I would think I could tap into JAAS to get my userlist.

                I'll keep looking, but if you think I'm way off-base on this let me know. Like I said, I am new to all this stuff, so I wouldn't be surprised if I'm not getting the whole picture...

                - Jeff

                • 5. Re: Get list of users from JBoss AS?
                  Anil Saldanha Master

                  JAAS is not the answer for your current requirements. Just because Tomcat allowed you a way of doing reflective seek of the users per role, does not mean that it will be a portable solution.

                  As Chris suggested, you should try to build a layer that will go to ldap and does basic JNDI to get users in a particular role.

                  That will be the right solution to the problem you are facing.

                  • 6. Re: Get list of users from JBoss AS?
                    chris griffith Expert

                    Jeff,

                    I hate to be blunt, but you are way off base. JAAS is an API whose sole purpose is to externalize the authentication/authorization (A/A) from the application as well as make it pluggable. JAAS is not a service/API that can be used to gain info about or modify a set of users (a.k.a a realm.)

                    If you want to have a service that can provide CRUD actions on a realm then you need to create such a beast. This is not what JAAS is for. My comments about how to do this then are still valid.

                    later, cgriffith

                    • 7. Re: Get list of users from JBoss AS?
                      Jeff Storck Newbie

                      So there is no way to avoid having webapp code explicitly pointing at LDAP?

                      I was thinking of a workaround where I would store the LDAP connect info in the web.xml somewhere, and then read that into an object and bind it to some JNDI address, but I still don't like that solution. I'd still have to create classes to handle getting user lists from different sources, and that seems backwards to me.

                      Isn't it the point of J2EE to abstract this stuff away from the webapps so that developers can write portable solutions with less code?

                      • 8. Re: Get list of users from JBoss AS?
                        chris griffith Expert

                        You are correct about the purpose of J2EE, and yet you are not listening to me. I have told you that you do not want your web application to access LDAP directly. I have advised that you should develop a layer that abstracts this from your web application. I have even suggested that this layer should be implemented using EJBs. If this still does not make sense, then you really need to do more reading on J2EE.

                        May I suggest http://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html.

                        • 9. Re: Get list of users from JBoss AS?
                          Jeff Storck Newbie

                          It makes sense, I just don't have time to learn EJB right now. I don't like the fact that I'll have to create different EJBs to incorporate different user stores (realms), but if that's how it has to be done, we'll get to it eventually.

                          I agree that, since JAAS can't be used, creating the EJBs is the next best thing, and I'm probably making a mountain out of a molehill due to my ignorance of J2EE.

                          For now I am going to implement the LDAP connection directly in the code so that it is working. We're eventually going to be migrating our application over to EJB3, and at that point, this will get cleaned up.

                          Thanks for the help and being patient with me, thanks for all the replies!

                          • 10. Re: Get list of users from JBoss AS?
                            Anil Saldanha Master

                             

                            "j2ee_junkie" wrote:
                            You are correct about the purpose of J2EE, and yet you are not listening to me. I have told you that you do not want your web application to access LDAP directly. I have advised that you should develop a layer that abstracts this from your web application. I have even suggested that this layer should be implemented using EJBs. If this still does not make sense, then you really need to do more reading on J2EE.


                            Why do you need EJBs for this? What happened to a good old POJO that used JNDI to talk to ldap?

                            • 11. Re: Get list of users from JBoss AS?
                              chris griffith Expert

                              You are correct. I am still behind on that technology. Maybe on my next project I could use it.

                              thank you for setting me straight, cgriffith

                              • 12. Re: Get list of users from JBoss AS?
                                chris griffith Expert

                                Opps, I may have misunderstood you Anil. I thought you were refering to EJB3 (since it supports POJO). Sure that would be good too.

                                cgriffith