jsfjakarta-eeauthenticationjaasj-security-check

Performing user authentication in Java EE / JSF using j_security_check


I'm wondering what the current approach is regarding user authentication for a web application making use of JSF 2.0 (and if any components do exist) and Java EE 6 core mechanisms (login/check permissions/logouts) with user information hold in a JPA entity. The Oracle Java EE tutorial is a bit sparse on this (only handles servlets).

This is without making use of a whole other framework, like Spring-Security (acegi), or Seam, but trying to stick hopefully with the new Java EE 6 platform (web profile) if possible.


Solution

  • After searching the Web and trying many different ways, here's what I'd suggest for Java EE 6 authentication:

    Set up the security realm:

    In my case, I had the users in the database. So I followed this blog post to create a JDBC Realm that could authenticate users based on username and MD5-hashed passwords in my database table:

    http://blog.gamatam.com/2009/11/jdbc-realm-setup-with-glassfish-v3.html

    Note: the post talks about a user and a group table in the database. I had a User class with a UserType enum attribute mapped via javax.persistence annotations to the database. I configured the realm with the same table for users and groups, using the userType column as the group column and it worked fine.

    Use form authentication:

    Still following the above blog post, configure your web.xml and sun-web.xml, but instead of using BASIC authentication, use FORM (actually, it doesn't matter which one you use, but I ended up using FORM). Use the standard HTML , not the JSF .

    Then use BalusC's tip above on lazy initializing the user information from the database. He suggested doing it in a managed bean getting the principal from the faces context. I used, instead, a stateful session bean to store session information for each user, so I injected the session context:

     @Resource
     private SessionContext sessionContext;
    

    With the principal, I can check the username and, using the EJB Entity Manager, get the User information from the database and store in my SessionInformation EJB.

    Logout:

    I also looked around for the best way to logout. The best one that I've found is using a Servlet:

     @WebServlet(name = "LogoutServlet", urlPatterns = {"/logout"})
     public class LogoutServlet extends HttpServlet {
      @Override
      protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       HttpSession session = request.getSession(false);
    
       // Destroys the session for this user.
       if (session != null)
            session.invalidate();
    
       // Redirects back to the initial page.
       response.sendRedirect(request.getContextPath());
      }
     }
    

    Although my answer is really late considering the date of the question, I hope this helps other people that end up here from Google, just like I did.

    Ciao,

    Vítor Souza