jueves, 28 de octubre de 2021

Java Servlet Filters

Java Servlet Filters

 
  Let´s try filters on servlets, this sample takes three filters, the filter_3 clean the value of the parameter named dangerousParamName. The order of flow is determined accord the order in the web.xml file.
The request pass the parameters to and the servlet process them, but the request pass first through the filter_1 then filter_2 and finally the filter_3 that clean the value of the dangerousParamName.

Project structure

The servlet run on Apache8 server

The web.xml file with filters order 1 --> 2 --> 3

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>servlet-and-filters</display-name>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

       <filter>
        <filter-name>Filter_1</filter-name>
        <filter-class>com.bext.filter.Filter_1</filter-class>
        <init-param>
            <param-name>Filter_1_InitParam</param-name>
            <param-value>Filter_1_InitParam-value-123</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>Filter_1</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>Filter_2</filter-name>
        <filter-class>com.bext.filter.Filter_2</filter-class>
        <init-param>
            <param-name>Filter_2_InitParam</param-name>
            <param-value>Filter_2_InitParam-value-345</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>Filter_2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>Filter_3</filter-name>
        <filter-class>com.bext.filter.Filter_3</filter-class>
        <init-param>
            <param-name>Filter_3_InitParam</param-name>
            <param-value>Filter_3_InitParam-value-333</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>Filter_3</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>com.bext.servlet.TestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/test</url-pattern>
    </servlet-mapping>
</web-app>


TestServlet.java

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

    private static final long serialVersionUID = -2063502095847255667L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        PrintWriter out = resp.getWriter();
        out.println("<b>=== TestServlet running. doGet ===</b><br/>");
        Enumeration<String> parameterNames = req.getParameterNames();
        if (parameterNames.hasMoreElements()) {
            while (parameterNames.hasMoreElements()) {
                String name = parameterNames.nextElement();
                String value = req.getParameter(name);
                out.println("name: " + name + ", value: " + value + "<br/>");
            }
        } else {
            out.println("--- TestServlet Has Not Parameters ---<br/>");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }

    private void performTask(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<b>=== TestServlet running. doPost ===</b><br/>");
        Enumeration<String> parameterNames = request.getParameterNames();
        if (parameterNames.hasMoreElements()) {
            while (parameterNames.hasMoreElements()) {
                String name = parameterNames.nextElement();
                String value = request.getParameter(name);
                out.println("name: " + name + ", value: " + value + "<br/>");
            }
        } else {
            out.println("--- TestServlet Has Not Parameters ---<br/>");
        }
    }
}

Filter_1.java and Filter_2.java

package com.bext.filter;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

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;

public class Filter_1 implements Filter {

    FilterConfig filterConfig = null;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
        String param = filterConfig.getInitParameter("Filter_1_InitParam");
        System.out.println("Init param: " + param);
    }
    
    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
       String name = "";
       response.setContentType("text/html");
       PrintWriter out = response.getWriter();
       out.println("<b>Filter_1</b> <br/>InitParam: " + filterConfig.getInitParameter("Filter_1_InitParam"));
       out.println("<br/><br/>Filter_1 Parameters:<br/>");
       Enumeration<String> parameterNames = request.getParameterNames();
       if (parameterNames.hasMoreElements()) {
           while (parameterNames.hasMoreElements()) {
               name = parameterNames.nextElement();
               String value = request.getParameter(name);
               out.println("Param Name: " + name + ", Value: " + value + "<br/>");
           }
       } else {
           out.println("--- Filter_1 Has Not Parameters ---<br/>");
       }
       
       out.println("<br><b>Filter_1</b> Before doFilter(req, resp)</br><hr/>");
       chain.doFilter(request, response);
       out.println("<hr/><br><b>Filter_1</b> After doFilter(req, resp)</br>");
    }

}

Filter_3.java

package com.bext.filter;

import java.io.IOException;
import java.io.PrintWriter;

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;

public class Filter_3 implements Filter {

    static class FilteredRequest extends HttpServletRequestWrapper {

        /* These are the characters allowed by the Javascript validation */
        static String allowedChars = "+-0123456789#*";

        public FilteredRequest(HttpServletRequest request) {
            super((HttpServletRequest) request);
        }

        public String sanitize(String input) {
            String result = "";
            for (int i = 0; i < input.length(); i++) {
                if (allowedChars.indexOf(input.charAt(i)) >= 0) {
                    result += input.charAt(i);
                }
            }
            return result;
        }

        public String getParameter(String paramName) {
            String value = super.getParameter(paramName);
            if ("dangerousParamName".equals(paramName)) {
                value = sanitize(value);
            }
            return value;
        }

        public String[] getParameterValues(String paramName) {
            String values[] = super.getParameterValues(paramName);
            if ("dangerousParamName".equals(paramName)) {
                for (int index = 0; index < values.length; index++) {
                    values[index] = sanitize(values[index]);
                }
            }
            return values;
        }
    }
       
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<br><b>Filter_3</b> Before doFilter(req, resp)</br><hr/>");
        chain.doFilter(new FilteredRequest((HttpServletRequest) request), response);
        out.println("<hr/><br><b>Filter_3</b> After doFilter(req, resp)</br>");
    }


}


 Test Url
 
http://localhost:8080/servlet-and-filters/test?doGetParameter=323&anotherParam=Lucas&dangerousParamName=01thistextwillbedeletedgarbage2345garbage5?%C2%A1re678kdfs90
 
Browser output:
 
Filter_1
InitParam: Filter_1_InitParam-value-123

Filter_1 Parameters:
Param Name: doGetParameter, Value: 323
Param Name: anotherParam, Value: Lucas
Param Name: dangerousParamName, Value: kjgheiun123455?¡re34

Filter_1 Before doFilter(req, resp)

Filter_2
InitParam: Filter_2_InitParam-value-345

Filter_2: Parameters:
Param Name: doGetParameter, Value: 323
Param Name: anotherParam, Value: Lucas
Param Name: dangerousParamName, Value: kjgheiun123455?¡re34

Filter_2 Before doFilter(req, resp)


Filter_3 Before doFilter(req, resp)

=== TestServlet running. doGet ===
name: doGetParameter, value: 323
name: anotherParam, value: Lucas
name: dangerousParamName, value: 12345534


Filter_3 After doFilter(req, resp)


Filter_2 After doFilter(req, resp)


Filter_1 After doFilter(req, resp)
 
Changing the filter order 3 --> 2 --> 1
 
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>servlet-and-filters</display-name>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <filter>
        <filter-name>Filter_3</filter-name>
        <filter-class>com.bext.filter.Filter_3</filter-class>
        <init-param>
            <param-name>Filter_3_InitParam</param-name>
            <param-value>Filter_3_InitParam-value-333</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>Filter_3</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>Filter_2</filter-name>
        <filter-class>com.bext.filter.Filter_2</filter-class>
        <init-param>
            <param-name>Filter_2_InitParam</param-name>
            <param-value>Filter_2_InitParam-value-345</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>Filter_2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

       <filter>
        <filter-name>Filter_1</filter-name>
        <filter-class>com.bext.filter.Filter_1</filter-class>
        <init-param>
            <param-name>Filter_1_InitParam</param-name>
            <param-value>Filter_1_InitParam-value-123</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>Filter_1</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>com.bext.servlet.TestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/test</url-pattern>
    </servlet-mapping>
</web-app>

 
 
 Browser output:
Filter_3 Before doFilter(req, resp)

Filter_2
InitParam: Filter_2_InitParam-value-345

Filter_2: Parameters:
Param Name: doGetParameter, Value: 323
Param Name: anotherParam, Value: Lucas
Param Name: dangerousParamName, Value: 012345567890

Filter_2 Before doFilter(req, resp)

Filter_1
InitParam: Filter_1_InitParam-value-123

Filter_1 Parameters:
Param Name: doGetParameter, Value: 323
Param Name: anotherParam, Value: Lucas
Param Name: dangerousParamName, Value: 012345567890

Filter_1 Before doFilter(req, resp)

=== TestServlet running. doGet ===
name: doGetParameter, value: 323
name: anotherParam, value: Lucas
name: dangerousParamName, value: 012345567890


Filter_1 After doFilter(req, resp)


Filter_2 After doFilter(req, resp)


Filter_3 After doFilter(req, resp)
 
text

eot

No hay comentarios:

Publicar un comentario