Testing secure code Howto

Last update : April 21 2002
Doc for : v1.3

About
  • What is Cactus ?
  • News
  • Changes
  • Features/Status
  • Goals
  • Roadmap/Todo
  • Contributors
  • Contributing
  • Cactus Users
  • Tested on ...
  • License


  • Downloads
  • Downloads


  • Documentation
  • How it works ?
  • Getting Started
  • Mock vs Container
  • Javadocs
  • FAQ


  • Howto Guides
  • Classpath Howto
  • Config Howto
  • Migration Howto
  • TestCase Howto
  • Security Howto
  • Ant Howto
  • HttpUnit Howto
  • Sample Howto
  • EJB Howto
  • IDE Howto
  • JUnitEE Howto


  • Support
  • Bug database
  • Mailing list


  • Misc.
  • Why the name ?
  • Logo Challenge
  • Resources
  • Stats


  • Developers
  • CVS
  • Coding Conventions
  • Build results


  • Introduction to testing secure code

    Beginning with version 1.3, Cactus is able to unit test Servlet code that uses the Servlet Security API (getRemoteUser(), isUserInRole(), getUserPrincipal()).

    The way to perform this is by securing a Servlet Redirector defined in your web.xml and then to specify user credentials in your beginXXX(), as defined below.

    Note The only currently supported authentication mechanism in Cactus 1.3 is the BASIC authentication.

    Note The Cactus sample application demonstrates how to unit test everything that is explained here.


    Step 1 : Passing credentials in beginXXX()

    Let's start with an example :

    public void beginBasicAuthentication(WebRequest theRequest)
    {
        theRequest.setRedirectorName("ServletRedirectorSecure");
        theRequest.setAuthentication(
            new BasicAuthentication("testuser", "testpwd"));
    }
    
    public void testBasicAuthentication()
    {
        assertEquals("testuser", request.getUserPrincipal().getName());
        assertEquals("testuser", request.getRemoteUser());
        assertTrue("User not in 'test' role", request.isUserInRole("test"));
    }
    

    There are several things to understand here :

    • The Servlet that is called on the server side is the Cactus redirector servlet and thus we'll need to secure it in our web.xml (see step 2 below).
    • WebRequest.setRedirectorName() is an API that lets you override the redirector defined in cactus.properties. This is needed here because we want to test both code that is not secured (i.e. for which we don't want to have to pass credentials) and code that is secured and thus we need 2 redirectors. The ServletRedirectorSecure redirector will be secured in step 2 below.
    • WebRequest.setAuthentication() is used to pass credentials to the server. It takes a parameter which is a BasicAuthentication object (the only type of authentication currently supported by Cactus).

    Step 2 : Securing the Cactus Redirector

    All calls to the server side go through the Cactus Servlet Redirector and thus it is that servlet that needs to be secured in web.xml. It is performed as follows (example) :

    [...]
    
    <web-app>
    
        <servlet>
            <servlet-name>ServletRedirector</servlet-name>
            <servlet-class>org.apache.cactus.server.ServletTestRedirector</servlet-class>
        </servlet>
    
        <servlet>
            <servlet-name>ServletRedirectorSecure</servlet-name>
            <servlet-class>org.apache.cactus.server.ServletTestRedirector</servlet-class>
        </servlet>
    
        [...]
    
        <servlet-mapping>
            <servlet-name>ServletRedirector</servlet-name>
            <url-pattern>/ServletRedirector</url-pattern>
        </servlet-mapping>
    
        <servlet-mapping>
            <servlet-name>ServletRedirectorSecure</servlet-name>
            <url-pattern>/ServletRedirectorSecure</url-pattern>
        </servlet-mapping>
    
        [...]
    
      	<!-- Start Authentication -->
    
      	<security-constraint>
         	<web-resource-collection>
            	<web-resource-name>SecurityRestriction</web-resource-name>
             	<description>Protect the Cactus redirector servlet.</description>
             	<url-pattern>/ServletRedirectorSecure</url-pattern>
             	<http-method>GET</http-method>
             	<http-method>POST</http-method>
         	</web-resource-collection>
         	<auth-constraint>
             	<description>Authorized Users Group</description>
             	<role-name>test</role-name>
         	</auth-constraint>
         	<user-data-constraint>
            	<transport-guarantee>NONE</transport-guarantee>
        	</user-data-constraint>
       	</security-constraint>
    
        <login-config>
        	<auth-method>BASIC</auth-method>
       	</login-config>
    
    	<security-role>
    		<description>Test role</description>
    		<role-name>test</role-name>
    	</security-role>
    
      	<!-- End Authentication -->
    
    </web-app>
    

    Step 3 : Map Users/Roles

    This step consists in defining authorized users and mapping them to the role defined in web.xml (e.g. in the example above, we have defined a test role).

    This step is completely container-dependent and there is no standard way of doing it. You'll have to learn how to do it for your container. For example, here is how you would do it for Tomcat 4.0 :

    • Create a tomcat-users.xml file that you put in your Tomcat configuration directory (where you have server.xml defined).

    Here is an example of tomcat-users.xml that matches the test we have defined in step 1 :

    <tomcat-users>
      <user name="testuser" password="testpwd" roles="test" />
    </tomcat-users>
    



    Copyright © 2000-2002 The Apache Software Foundation. All Rights Reserved.