Beginning with version 1.3, Cactus is able to unit test Servlet code
that uses the Servlet Security API (getRemoteUser()
,
isUserInRole()
, getUserPrincipal()
).
Cactus supports the BASIC and FORM authentication methods.
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.
Let's start with an example:
public void beginBasicAuthentication(WebRequest theRequest) { theRequest.setRedirectorName("ServletRedirectorSecure"); theRequest.setAuthentication( new BasicAuthentication("testuser", "testpassword")); } 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:
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 an implementation of the
Authentication
interface as argument. In this example,
we pass in a BasicAuthentication
which corresponds to
the BASIC authentication method. Testing with form-based
authentication just involves using the
FormAuthentication
class instead of
BasicAuthentication
.
web.xml
. The required modifications to web.xml
are 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>
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:
tomcat-users.xml
file that you put in your
Tomcat configuration directory (where you have
server.xml
defined).
tomcat-users.xml
that matches the
test we have defined in step 1:
<tomcat-users> <user name="testuser" password="testpassword" roles="test" /> </tomcat-users>