Filtering requests with the sample servlet filter

You can filter HTTP requests to reject or modify them before they are delivered to the WebSphere® MQ File Transfer Edition Web Gateway.

Before you begin

You need the Java™ Platform, Enterprise Edition (Java EE) libraries on your class path to compile the sample servlet filter file.

About this task

The sample servlet filter provided with WebSphere MQ File Transfer Edition shows you an example of how to filter HTTP requests. The sample filter file, SampleServletFilter.java, is located in the samples/web/filter directory of your WebSphere MQ File Transfer Edition installation. It is also reproduced at the bottom of this topic.

Procedure

  1. Compile the SampleServletFilter.java file to create the SampleServletFilter.class and RequestWrapper.class files.
  2. Put the compiled class files onto your application server classpath. The process for doing this is specific to the application server you are using. For example, if you are using WebSphere Application Server Version 7.0, put the class files into a JAR file, and copy the JAR file into the WAS_install_root/lib directory.
  3. Extract the module com.ibm.wmqfte.web.war from the Web Gateway EAR file, com.ibm.wmqfte.web.ear. The EAR file is located in the install-directory/web directory of your WebSphere MQ File Transfer Edition Server installation. To extract the com.ibm.wmqfte.web.war file, run the following command:
    jar -xf com.ibm.wmqfte.web.ear com.ibm.wmqfte.web.war
  4. Extract the web.xml file from the com.ibm.wmqfte.web.war file by running the following command:
    jar -xf com.ibm.wmqfte.web.war WEB-INF/web.xml
  5. Use a text editor to uncomment the following lines in the web.xml file:
    <filter>
      <filter-name>SampleServletFilter</filter-name>
      <filter-class>SampleServletFilter</filter-class>
    </filter>
    
    <filter-mapping>
      <filter-name>SampleServletFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
    Note: If you are writing your own servlet filter, change the <filter-name> and <filter-class> values in the web.xml file to match your servlet filter. Leave the url-pattern value as /*.
  6. Update the Web Gateway application with the modified WEB-INF/web.xml file, by running the following command:
    jar -uf com.ibm.wmqfte.web.war WEB-INF/web.xml
  7. Update the EAR file with the updated WAR file, by running the following command:
    jar -uf com.ibm.wmqfte.web.ear com.ibm.wmqfte.web.war
  8. Deploy the Web Gateway application to your application server. For instructions on deploying the application, see Deploying the WebSphere MQ File Transfer Edition Web Gateway.

Example

/*
 * 
 * Version: %Z% %I% %W% %E% %U% [%H% %T%]
 * 
 * Licensed Materials - Property of IBM
 * 
 * 5655-U80, 5724-R10
 * 
 * Copyright IBM Corp. 2010, 2018. All Rights Reserved.
 * 
 * US Government Users Restricted Rights - Use, duplication or
 * disclosure restricted by GSA ADP Schedule Contract with
 * IBM Corp. 
 * 
 */

import java.io.IOException;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

/**
 * A sample servlet filter implementation that demonstrates how an application
 * server administrator can filter (reject or modify) HTTP requests before they
 * are passed to the Web Gateway. The filter is called when a request
 * is received by the application server for any servlet which has this
 * class configured as a filter.
 * 
 * In this example implementation two parts of an HTTP request are checked before
 * the request is passed to the servlet:
 * 
 * 1 - If the x-fte-postdest header has been set, the request is rejected by 
 *     returning an HTTP 400 Bad Request in a response to the HTTP client.
 *     
 *     This demonstrates how an administrator can use servlet filters to reject
 *     WMQFTE HTTP requests that they don't want to reach the WMQFTE environment.
 *     In this example, the filter rejects any HTTP request that specifies a 
 *     command to execute after the transfer has completed.
 *     
 * 2 - If the destination agent that is specified in a file upload URI matches one 
 *     of the three aliases defined in this filter (ACCOUNTS, MARKETING and WAREHOUSE), 
 *     the destination alias is replaced with the actual destination agent and queue 
 *     manager values for that alias.
 *     
 *     This demonstrates how an administrator can use servlet filters to modify
 *     any part of a request before it is passed through to the WMQFTE
 *     environment. In this example, the destination agent is changed in the
 *     request URI if it matches one of a number of known aliases.
 * 
 public class SampleServletFilter implements Filter {

	/*
	 * (non-Javadoc)
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		
		Logger sampLogger = Logger.getLogger("SampleServletFilter");
		sampLogger.log(new LogRecord(Level.INFO, "WebSphere MQ File Transfer Edition Web Gateway - SampleServletFilter invoked"));
		
		RequestWrapper modifiedRequest = null;
		
		if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {			
			
			HttpServletRequest httpRequest = (HttpServletRequest) request;
			HttpServletResponse httpResponse = (HttpServletResponse) response;
			
			/******************************************************************
			 * The first part of the filter - reject any requests that attempt
			 * to run commands on the destination agent system
			 ******************************************************************/
			
			/*
			 *  Get any 'x-fte-postdest' headers which might have been set
			 */
			Enumeration<?> postDestCalls = httpRequest.getHeaders("x-fte-postdest");
			
			if (postDestCalls != null && postDestCalls.hasMoreElements()) {
				
				/*
				 * Because we want to filter out all requests that attempt to run commands
				 * on the destination agent system, if we find any values at all for the 
				 * x-fte-postdest header then we reject the request instead of proceeding.
				 */
				
				httpResponse.setContentType("text/html");
				httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Request rejected - an attempt to run commands was detected.");
			}
			
			/******************************************************************
			 * The second part of the filter - map our own aliases for WMQFTE 
			 * agents to the correct agent and queue manager pair
			 ******************************************************************/
			String requestURI = httpRequest.getRequestURI();
			
			if (requestURI.indexOf("/agent/ACCOUNTS") >= 0) {
				modifiedRequest = new RequestWrapper(httpRequest);
				modifiedRequest.changeDestinationAgent("/agent/ACCOUNTS", "/agent/ACTS.AGENT@ACTS.QM");
			} else if (requestURI.indexOf("/agent/MARKETING") >= 0) {
				modifiedRequest = new RequestWrapper(httpRequest);
				modifiedRequest.changeDestinationAgent("/agent/MARKETING", "/agent/MKTG.AGENT@MKTG.QM");
			} else if (requestURI.indexOf("/agent/WAREHOUSE") >= 0) {
				modifiedRequest = new RequestWrapper(httpRequest);
				modifiedRequest.changeDestinationAgent("/agent/WAREHOUSE", "/agent/WRHS.AGENT@WRHS.QM");
			} else {
				// Leave the original request URI in place
			}	
			
			/******************************************************************
			 * Finally call the next filter in the chain with the original
			 * request (or a new wrappered request if one has been created) and
			 * the original response.
			 ******************************************************************/
			if (modifiedRequest != null) {
				chain.doFilter(modifiedRequest, response);
			} else {
				chain.doFilter(request, response);
			}
		} else {
			chain.doFilter(request, response);
		}
	}

	/*
	 * (non-Javadoc)
	 * @see javax.servlet.Filter#destroy()
	 */
	public void destroy() {
		// Do nothing
	}

	/*
	 * (non-Javadoc)
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	public void init(FilterConfig config) throws ServletException {
		// Do nothing
	}

}

/**
 * A class to wrap an <code>HttpServletRequest</code> so we can modify parts of the request
 */
class RequestWrapper extends HttpServletRequestWrapper {
	
	private String originalDestination, newDestinationAgent;
	
	/*
	 * Constructor
	 */
	public RequestWrapper(HttpServletRequest request) {
		super(request);
	}
	
	/*
	 * 
	 * (non-Javadoc)
	 * @see javax.servlet.http.HttpServletRequestWrapper#getRequestURI()
	 */
	@Override
	public String getRequestURI() {
		String originalURI = super.getRequestURI();
		
		StringBuffer newURI = new StringBuffer();
		
		newURI.append(originalURI.substring(0, originalURI.indexOf(originalDestination)));
		newURI.append(newDestinationAgent);
		newURI.append(originalURI.substring(originalURI.indexOf(originalDestination) + originalDestination.length(), 
											originalURI.length()));
		
		return newURI.toString();
	}
	
	/**
	 * Change the original destination agent/queue manager set in the request by the
	 * HTTP client (or a previous filter) to a new destination agent/queue manager.
	 * 
	 * @param originalDestination
	 * @param newDestination
	 */
	protected void changeDestinationAgent(String originalDestination, String newDestination) {
		this.originalDestination = originalDestination;
		this.newDestinationAgent = newDestination;
	}
	
}

Task Task

Feedback

Timestamp icon Last updated: Tuesday, 30 January 2018
http://www.ibm.com/support/knowledgecenter/SSEP7X_7.0.4/com.ibm.wmqfte.doc/web_admin_servlet_filters.htm