Caucho Technology
  • resin 4.0
  • basic security and resin's xmlauthenticator


    This tutorial covers the basics of JSP and Servlet security and the use of Resin's XmlAuthenticator.

    Demo

      Files in this example

      FILEDESCRIPTION
      WEB-INF/web.xmlThe main JSP/Servlet configuration file
      index.jspThe home page for the website
      login.jspThe JSP page containing the login form
      logout.jspA JSP page that causes a logout
      home.jspThe home page for authenticated users.
      professors/index.jspThe more specific home page for Professor's, available only to users in role 'professor'
      students/index.jspThe more specific home page for Student's, available to users in role 'student' or in role 'professor'
      staff/index.jspThe more specific home page for Staff, available to users in role 'staff' or in role 'professor'
      inc/buttonbar.jspfAn include file to render a button bar
      inc/footer.jspfAn include file to render a footer
      inc/nobrowsercache.jspfAn include file to stop the browser from caching pages

      Specifying roles

      Each user belongs to one or more roles. These roles are similar to groups in Unix. The possible roles are specified in web.xml.

      In this example, a user is either a professor, a student, or a staff. They can also optionally have an additional role of gryffindor, slytherin, hufflepuf, or ravenclaw, indicating which house they belong to (or none at all).

      Specifying secure areas

      You can limit areas of the website to users in a certain role. You specify url patterns in web.xml and the role that is required. In JSP/Servlet terminology, this is called Declarative Security.

      Declarative Security in web.xml
      <web-app xmlns="http://caucho.com/ns/resin"
              xmlns:resin="urn:java:com.caucho.resin">
              
        <resin:Allow url-pattern="/professors/*">
          <resin:IfUserInRole role="professor"/>
        </resin:Allow>
      
      </web-app>
      

      Making a login form

      A login form can be used to retrieve the username and password from the user. The same form or a seperate form can be used when the login fails.

      In this example the login form and the error form are in the same JSP file. If the form is being redisplayed because of an error the login_error request parameter is set to '1'.

      login-config: Getting Resin to use the login form
      <web-app xmlns="http://caucho.com/ns/resin"
              xmlns:resin="urn:java:com.caucho.resin">
              
        <resin:FormLogin>
            <login-page>/login.jsp</login-page> 
            <error-page>/login.jsp?login_error=1</error-page>
        </resin:FormLogin>
      
          ...
      </web-app>
      
      An example login form
      <form action='j_security_check' method='POST'>
        <table>
          <tr><td>User:</td><td><input type='text' name='j_username'></td></tr>
          <tr><td>Password:</td><td><input type='password' name='j_password'></td></tr>
      
          <tr><td colspan='2'><input type=submit></td></tr>
        </table>
      
        <!--
          -  In case the user got here without a session, redirect
          -  successful requests to the home page for authenticated
          -  users.  (This is a non-standard, but useful field.)
          -->
        <input type='hidden' name='j_uri' value='/home.jsp'/>
      </form>
      

      Causing a login to occur

      Resin will cause a login to occur when a url that points to a secure area is used. You do not make a url directly to the jsp page that contains the login form.

      In this example, home.jsp is in a secure area, so an unauthenticated user trying to access it will first be presented with the login form.

      Accessing a jsp in a secure area causes the login to occur
      <web-app xmlns="http://caucho.com/ns/resin"
              xmlns:resin="urn:java:com.caucho.resin">
      
        <resin:Allow url-pattern="/home.jsp">
          <!-- 
            '*' for a <role-name> means "authenticated user with any role"
            The user must be logged in with some kind of role to access
            the home page.  
          -->
          <resin:IfUserInRole role="*"/>
        </resin:Allow>
        
      </web-app>
      
      Making a link to cause a login
      <a href="<c:url value='/home.jsp'/>">login</a>
      

      Determining if the user is authenticated

      If the user has done a successfull login, we say that they have been authenticated. request.getUserPrincipal() returns null if the user has not been authenticated.

      In this example it is used to determine whether a 'login' or a 'logout' link should be presented.

      Determining if the user is authenticated
      <c:choose>
        <c:when test="${empty pageContext.request.userPrincipal}">
          <a href="<c:url value='home.jsp'/>">login</a>
        </c:when>
        <c:otherwise>
          <a href="<c:url value='logout.jsp'/>">logout</a>
        </c:otherwise>
      </c:choose>
      

      Getting the current username

      Getting the current username
      Welcome <c:out value="${pageContext.request.remoteUser}"/>.
      

      Doing different things for different roles

      You can also determine if a user is in a certain role in the body of the page using request.isUserInRole("role"). In JSP/Servlet terminology, this is called Programmatic Security.

      In this example, the home.jsp redirects the user to a more specific home page if the user is a professor, student, or staff.

      Programmatic Security using Java code
      <%
        /** redirect to a more specific homepage if one is available */
      
        String home_url = null;
      
        if (request.isUserInRole("professor")) {
            home_url = "professors/";
        } else if (request.isUserInRole("staff")) {
            home_url = "staff/";
        } else if (request.isUserInRole("student")) {
            home_url = "students/";
        }
      
        if (home_url != null) {
            home_url = response.encodeRedirectUrl(home_url);
            response.sendRedirect(home_url);
            return; // don't do any more of the page
        }
      %>
      

      Stop the browser from caching pages

      Pages with information that changes depending on whether or not there is a known user should not be cached by the browser.

      In this example an include file inc/nobrowsercache.jspf is used to send the HTTP headers that stop the browser from caching the page. It is used for each page that shows the button bar at the top, because the button bar changes depending on whether or not the user is logged in.

      Java code to stop the browser from caching the page
      <%-- stop the browser from caching the page --%>
      
      <%
        response.setHeader("Cache-Control","no-cache,post-check=0,pre-check=0");
        response.setHeader("Pragma","no-cache");
        response.setHeader("Expires","Thu,01Dec199416:00:00GMT");
      %>
      
      Using inc/nobrowsercache.jsp
      <%@ include file="/inc/nobrowsercache.jspf" %>
      

      Causing a logout

      A user can be logged out by invalidating the session. This causes all of the information stored in the session to be lost. It is especially important to make sure that the logout page is not cached by the browser.

      Causing a logout with session.invalidate()
      <%@ include file="/inc/nobrowsercache.jspf" %>
      
      <%-- invalidating the session causes a loss of all session
           information, including the identity of the user
           --%>
      
      <% session.invalidate(); %>
      

      Using XmlAuthenticator

      Resin provides an authenticator com.caucho.http.security.XmlAuthenticator which is useful for sites which have minimal security requirements. The developer places entries for users in the authenticator configuration, or in an xml file, or both.

      The example below uses digest passwords. Digest passwords avoid the storage of passwords in cleartext, and are discussed under the security section of the Resin documentation.

      Specifying the XmlAuthenticator as the authenticator to use
      <web-app xmlns="http://caucho.com/ns/resin"
               resin:xmlns="urn:java:com.caucho.resin">
      
        <!-- Resin-specific XmlAuthenticator configuration -->
        <resin:XmlAuthenticator>
            <!-- Optionally put user information here.  -->
            <user>pince:Txpd1jQc/xwhISIqodEjfw==:staff,website</user>
            <user>filch:KmZIq2RKXAHV4BaoNHfupQ==:staff</user>
      
            <!-- You can also use an external file --> 
            <path>WEB-INF/password.xml</path>
        </resin:XmlAuthenticator>
        
      </web-app>
      
      An XML file with usernames, passwords, and roles
      <!-- password.xml -->
      <authenticator>
        <!-- professors -->
        <user name='snape' password='I7HdZr7CTM6hZLlSd2o+CA==' roles='professor,slytherin'/>
        <user name='mcgonagall' password='4slsTREVeTo0sv5hGkZWag==' roles='professor,gryffindor'/>
      
        <!-- students -->
        <user name='harry' password='uTOZTGaB6pooMDvqvl2Lbg==' roles='student,gryffindor'/>
        <user name='dmalfoy' password='yI2uN1l97Rv5E6mdRnDFwQ==' roles='student,slytherin'/>
      
        <!-- alumni -->
        <user name='lmalfoy' password='sj/yhtU1h4LZPw7/Uy9IVA==' roles='alumni,gryffindor'/>
      </authenticator>
      

      Documenting Roles

      <web-app xmlns="http://caucho.com/ns/resin">
      
      <security-role>
        <role-name>professor</role-name>
      </security-role>
      
      </web-app>
      

      Demo


      Copyright © 1998-2011 Caucho Technology, Inc. All rights reserved.
      Resin ® is a registered trademark, and Quercustm, Ambertm, and Hessiantm are trademarks of Caucho Technology.