Chapter 09 - Developing secure web applications (Programmatic Approach)

This web application shows how to fine tune the security aspects of a web application using the programmatic approach on top of the declarative approach.
Here, the servlet code uses the security related methods (ServletRequest.getRemoteUser() and ServletRequest.isUserInRole() ) to determine the output of the page. We still need to define the security constraints in the web.xml as explained in chapter09-declarative web application.

Note: To be able run this web application, you should have the user names and passwords configured in the tomcat-users.xml file as explained in section 9.2.5. For your convenience, we are giving sample values for this file. You can copy the following contents into conf/tomcat-users.xml:
<tomcat-users>
  <user name="tomcat" password="tomcat" roles="tomcat" />
  <user name="role1"  password="tomcat" roles="role1"  />
  <user name="both"   password="tomcat" roles="tomcat,role1" />

  <user name="john"   password="jjj" roles="employee" />
  <user name="mary"   password="mmm" roles="employee" />
  <user name="bob"   password="bbb" roles="employee, supervisor" />

</tomcat-users>

  1. This web application contains only one servlet named ProgramaticSecureServlet. All employees can make a GET request to this servlet and all employees are treated equally. To send a GET request, click on this hyperlink.
     
  2. For POST requests, the servlet generates different responses for managers and non-managers. To make a POST request, submit the form present on this page. The container will send the login page. If you enter a manager's username/password ( for example, bob/bbb ), you'll get the manager's page. If you enter a non-manager's username/password ( for example, john/jjj ), you'll get the employee's page.
    Observe the web.xml for this web application carefully.
    The code for the doPost() method of the servlet is as follows:
    public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException 
    {
    	PrintWriter pw = res.getWriter();
    	
    	System.out.println("remote user="+req.getRemoteUser());
    	System.out.println("user principal="+req.getUserPrincipal());
    	System.out.println("req.isUserInRole(\"manager\") = "+req.isUserInRole("manager"));
    	
    	pw.println("<html><head>");
    	pw.println("<title>Programatic Security Example</title>");
    	pw.println("</head>");
    	pw.println("<body>");
    
    	String username = req.getRemoteUser();
    	
    	if(username != null) pw.println("<h4>Welcome, "+username+"!</h4>");
    	
    	if(req.isUserInRole("manager"))
    	{
    		pw.println("<b>Manager's Page!</b>");
    	}
    	else
    	{
    		pw.println("<b>Employee's Page!</b>");
    	}
        
    	pw.println("</body></html>");
    	
    }
    

    Observe that in the tomcat-users.xml, we've configured the role 'supervisor' but in the servlet code we are using 'manager' as the role name. This mapping is specified in the web.xml using the following code:

     <servlet>
      <servlet-name>ProgramaticSecureServlet</servlet-name>
      <servlet-class>chapter9.ProgramaticSecureServlet</servlet-class>
      <security-role-ref>
        <role-name>manager</role-name>
        <role-link>supervisor</role-link>
      </security-role-ref> 
     </servlet>