Java Servlet & JSP Cookbook

Problem

You want to set up the web application so that only a controller servlet has access to certain servlets.

Solution

Create a security-role that does not have any users mapped to it, then specify in the security-constraint element the servlets that you want to preserve for the controller.

Discussion

This recipe shows how you can create a security-constraint element that forbids any requests from reaching specified URL patterns.

The servlets mapped to those URL patterns are forwarded requests only from one or more controller servlets that use an object that implements the javax.servlet.RequestDispatcher interface. Recipe 3.7 includes an example controller servlet that forwards a request to another servlet using a RequestDispatcher . Example 3-17 shows how you can set up the security-constraint element for an example servlet with the registered name "Weather".

Example 3-17. A security-constraint that allows only RequestDispatcher.forward- related requests

<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-application_2_3.dtd"> <web-app> <!-- configure the Weather servlet; it receives requests from a controller servlet --> <servlet> <servlet-name>Weather</servlet-name> <servlet-class> com.jspservletcookbook.Weather </servlet-class> </servlet> <servlet-mapping> <servlet-name>Weather</servlet-name> <url-pattern>/weatherurl-pattern> </servlet-mapping> <!-- this element prevents the Weather servlet from directly receiving requests from users, because no users are mapped to the 'nullrole' role--> <security-constraint> <web-resource-collection> <web-resource-name>Weather </web-resource-name> <url-pattern>/weather</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>nullrole</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> <role-name>nullrole</role-name> </security-role> </web-app>

The next step in protecting the Weather servlet is to make sure that the tomcat-users .xml file does not map any users to the "nullrole" security role. The security-role element looks like this:

<security-role> <role-name>nullrole</role-name> </security-role>

Here is what a typical <Tomcat-installation-directory>/conf/tomcat-users.xml file looks like:

<?xml version='1.0' encoding='utf-8'?> <tomcat-users> <role rolename="manager"/> <role rolename="tomcat"/> <role rolename="developer"/> <user username="tomcat" password="tomcat" roles="tomcat,manager"/> <user username="bruce" password="bruce1957" roles="tomcat,manager,developer"/> </tomcat-users>

In web applications configured in the manner of Example 3-17, any direct request to the URL pattern /weather receives a response in the category of "HTTP Status 403 ”Access to the requested resource has been denied ." However, a controller servlet can still use the RequestDispatcher.forward(request,response) method to forward a request to the /weather URL for processing. Recipe 3.7 and Example 3-10 show a servlet that uses this forward method, so I won't repeat that code here.

Make sure to configure friendly error pages for the users who make requests to restricted servlets. Chapter 9 describes how to designate error pages for certain HTTP response codes in the web application's deployment descriptor. You may want to provide automatic refreshes after a specified interval from the error page to the controller or any login pages.

See Also

Chapter 1 on web.xml ; Recipe 3.1-Recipe 3.9; Chapter 11 of the Servlet v2.3 and 2.4 specifications on mapping requests to servlets; the Core J2EE Blueprints page: http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html.

Категории