Thursday 19 January 2012

Setting up a database based authentication realm in Tomcat 7.0.0

Setting up an authentication module is one of the primary tasks that come across a web-developer's canvas when coding a web-application.In this post, I'll detail the basic steps needed to set up a database backed authentication realm and outline the configuration files that need to be updated when using a Tomcat 7.0.0 servlet container. This post is NOT about security or securing the web-app context so please if you do implement these steps, please do some more research on what is required to secure your web-application.It is also important to note that this post pertains to Tomcat version 7.0.0 and some steps may not be required in more recent versions.
Tomcat 7.0.0 implements the Servlet 3.0 specification (JSR 315) which provide login / logout methods to be invoked on the HttpServletRequest. 
Step 1: Create the user and user-roles table in your database using the sql scripts described here. Insert a couple of records in each table.
Step 2: Set up Tomcat to connect to the database realm
(a) In the context.xml(located in server/conf directory), set up the datasource  
    
(b) In server.xml (located in server/conf directory) add the following snippets in the correct location within the xml file. This will set up the connection between the datasource and the authentication mechanism :


.......

..........








Step 3: Download the jdbc driver based on your database & the tomcat-jdbc jar to set up the JDBC Connection Pool (You do not need to download the tomcat-jdbc jar if you are using Tomcat version 7.0.19 and above).


Step 4: Write the logic for passing the login & password from the user form to the backing bean.
 public String login() {  
          FacesContext context = FacesContext.getCurrentInstance();  
          HttpServletRequest request = (HttpServletRequest) context  
                                             .getExternalContext().getRequest();  
             
          try 
          {  
               request.login(username, password);  

          } catch (ServletException e) {  
            e.printStackTrace();
               context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Login   failed!", null));  
               return "failed-login";  
          }  
             
 //You can fetch user from database for authenticated principal and do some action  
          Principal principal = request.getUserPrincipal();  
          log.info("Authenticated user: " + principal.getName());  
             
             
          if(request.isUserInRole("administrator")) {  
            setLoginSectionVisible(false);
            setUploadSectionVisible(true);
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Login successful!", null));  
               return "admin-login";  
          } else {  
               return "user-login";  
          }  
     }