6 Replies Latest reply on Jul 5, 2006 1:24 PM by smokingapipe

    Best way to handle logins using JSF + EJBs

    smokingapipe

      I thought this would be a FAQ, but I can't find a good answer here.

      In the Servlet / JSP system, when I would implement an application, I would do it like this:

      I create a User object, that holds things like the user's password, email address, and various data the user can change, like his shoe size or favorite color.

      I create a login Servlet, which takes parameters (username and password). It looks in the DB for a user that corresponds to the username and password. If it finds such a user, it uses the data from the DB to create a new User object. It puts the User object into the HttpSession. It then sends a redirect to /members/index.html.

      I create a filter, and map it to /members/*. This filter is the authorization filter, and all it does is check the HttpSession to make sure there is a User object in there. If not, it sends a redirect out to a login page.

      Of course there is also a Signup servlet which creates new Users and stores them in the DB, there's a Logout servlet which removes a User from the HttpSession, and that's the framework for every application I write.

      Now I want to move entirely to the JSF + EJB + JBoss world. What do I do?

      I have a User EJB. That's fine and that works well. I have a signup form in JSF with a backing bean. That works well, and it does all the necessary validation, then it creates a new User EJB and persists it, etc. That's good.

      But what do I do about the login and auth. filter?

      I can easily set up a JSF backing bean that checks a username / password by doing an EJB query to see if there's a user that matches. Ok, that's no problem. But now that I have this user within my backing bean, how do I put that user into an HttpSession? And once that is there, do I just use a Filter just like before?

      And finally: How do I handle persistence transactions within this application? In a typical case, a user is logged in, and decides to change his favorite color from "blue" to "azure". There's a form, and a backing bean to handle that. The backing bean would (presumably) get the User object out of the HttpSession, and then do user.setFavoriteColor("azure"). What do I need to do on the EJB side to make sure that that change persists?

      Thanks for any hints on this. I'm trying to figure it out and it's new to me.

        • 1. Re: Best way to handle logins using JSF + EJBs
          smokingapipe

          Does anyone have an answer? Is there a way to put a EJB into an HttpSession from within a JSF backing bean?

          I now have my backing bean able to load the EJB from persistence, as it needs to, I just can't find any way to put that into the HttpSession scope.

          Surely this is something people need to do in every real-world web application?

          • 2. Re: Best way to handle logins using JSF + EJBs
            anders.hedstrom

            Take a look at Seam http://jboss.com/products/seam

            • 3. Re: Best way to handle logins using JSF + EJBs
              smokingapipe

              Thanks for the reference to Seam. I will definitely check it out. However, I'm almost there with my application and I don't want to launch into learning another system. Is there some simple way around this?

              Looking at "JavaServerFaces in Action", by Kito Mann, it recommends (on page 507):

              application.createValueBinding("...").setValue(facesContext, user);
              


              which is now deprecated apparently, and looks mighty clunky.

              What I am trying to do must be a component of every single real-world JSF application out there, so... how do I do it?


              • 4. Re: Best way to handle logins using JSF + EJBs
                smokingapipe

                It looks like one thing I could do would be to make my LoginBackingBean have a session scope. Then it could load the User object, which I could then reference as loginBackingBean.user.email (to get the email address, etc). I guess that would work, but it seems like it would be better to just put the user EJB directly into the session.

                Although maybe there are advantages to having a Visit backing bean. I guess that could keep a connection to a EJB stateless session bean that would do things like persist changes to the user. I guess if I had a bean like Visit I would use it in more places.

                Is this the best way to go?

                It seems like such an everyday thing, it's strange that there is so little information about the best way to do this.

                • 5. Re: Best way to handle logins using JSF + EJBs
                  anders.hedstrom

                  Perhaps this is what you're looking for

                  HttpSession ses = (HttpSession) facesContext.getExternalContext();
                  ses.getSession(true).setAttribute("user", user);



                  • 6. Re: Best way to handle logins using JSF + EJBs
                    smokingapipe

                    Ok, that looks like a straightforward way to do it. Is that the "best practice" way to go?