JFinal 如何进行XSS过滤(JFinal 的简单介绍到利用JFinal 的handler实现)

诸葛文博
2023-12-01

在此之前我们来谈谈JFinal

JFinal 是基于Java 语言的极速 web开发框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful。在拥有Java语言所有优势的同时再拥有ruby、python等动态语言的开发效率。
JFinal 采用微内核全方位扩展架构,全方位是指其扩展方式在空间上的表现形式。JFinal由Handler、Interceptor、Controller、Render、Plugin五大部分组成。

所以今天我们就讲讲其一:Handler。

JFinal的 Handler是 AOP + 责任链 模式的一个变种,JFinal对action及interceptor处理自身也是一个Handler名叫ActionHandler,可见其功能之强大。平时开发的时候一般不需要使用,当Action与Interceptor还不够用的时候可以考虑Handler上场。另外Handler可以替代Filter,你无需在web.xml 中再声明Filter了。

废话不多说了,赶紧进入正文

JFinal 是一个近乎零配置,基于spring MVC研发的框架,操作简单。节省代码,适用于所有web项目。适合中小型项目开发。10分钟写出一个页面的增删改查。。app,服务端也可以。只需一个简单的继承JFinalConfig 的配置类来配置JFinal所需的就行了。然后把它配置到web.xml中就可以了,其他的Interceptor、Controller、Handler只在该配置类里处理就行了,无需再在web.xml中配置了

下面是将该配置类配置到web.xml的示例:

    <filter>
        <filter-name>jfinal</filter-name>
        <filter-class>com.jfinal.core.JFinalFilter</filter-class>
        <init-param>
            <param-name>configClass</param-name>
            <param-value>com.uniasia.JFinalProjectConfigurer</param-value>
        </init-param>
    </filter>


下面简要说说JFinalProjectConfigurer.java 这个类 因为该类继承JFinal 框架的抽象 JFinalConfig 类,该类有5个抽象,所以要实现这5个抽象方法

    /**
     * Config constant
     */
    public abstract void configConstant(Constants me);

    /**
     * Config route
     */
    public abstract void configRoute(Routes me);

    /**
     * Config plugin
     */
    public abstract void configPlugin(Plugins me);

    /**
     * Config interceptor applied to all actions.
     */
    public abstract void configInterceptor(Interceptors me);

    /**
     * Config handler
     */
    public abstract void configHandler(Handlers me);

今天我们主要关注的是configHandler(Handlers me) 这个方法,这里是配置我们自己写的handler。
在该方法里面配置我们的handler的方法如下:

    /**
     * 配置处理器(这里添加了对html后缀的处理)如果不需要则默认为rest风格
     */
    public void configHandler(Handlers handler) {
        //handler.add(我们自定义handler的实例)
        handler.add(new XssHandler());
    }

下面开始定义我们的handler的。
创建一个XssHandler类,继承JFinal 的 Handler 实现handler()方法

public class XssHandler extends Handler{
    @Override
    public void handle(String target, HttpServletRequest request,
            HttpServletResponse response, boolean[] isHandled) {
        // 对于非静态文件,和非指定排除的url实现过滤
        //我这里过滤的是资源文件和网站后台
        if (target.indexOf(".") == -1&&!target.contains("manager")){
            request = new HttpServletRequestWrapper(request);
        }
        nextHandler.handle(target, request, response, isHandled);
    }
}

下面就是重写HttpServletRequestWrapper继承javax.servlet.http.HttpServletRequestWrapper

package com.uniasia.common.handler;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
/**
 * @desc 处理Xss漏洞
 * @author oneask
 * @time  2016年12月16日
 */
public class HttpServletRequestWrapper extends javax.servlet.http.HttpServletRequestWrapper{

    private HttpServletRequest request;

    public HttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
        this.request = request;
    }
    /**
     * 重写getParameter方法
     */
    @Override
    public String getParameter(String name) {
        String value = this.request.getParameter(name);
        if (value == null)
            return null;
        value = format(value);
        return value;
    }
    /**
     * 重写getParameterMap
     */
    @SuppressWarnings("unchecked")
    @Override
    public Map<String, String[]> getParameterMap() {
        HashMap<String, String[]> paramMap = (HashMap<String, String[]>) super.getParameterMap();
        paramMap = (HashMap<String, String[]>) paramMap.clone();

        for (Iterator iterator = paramMap.entrySet().iterator(); iterator.hasNext(); ) {
            Map.Entry<String, String[]> entry = (Map.Entry<String, String[]>) iterator.next();
            String [] values = entry.getValue();
            for (int i = 0; i < values.length; i++) {
                if(values[i] instanceof String){
                    values[i] = format(values[i]);
                }
            }
            entry.setValue(values);
        }
        return paramMap;
    }
    public String filter(String message) {
        if (message == null)
            return (null);
        message = format(message);
        return message;
    }
    /**
     *  @desc 统一处理特殊字符的方法,这里用的是apache的StringUtils.replaceEach  方法
     *  @org.apache.commons.lang.StringUtils.replaceEach 
     *  @author  oneask
     *  @time 2016年12月16日
     *  @param name 要替换的字符
     */
    private String format(String name) {
        //注意该方法,替换的字符前后数组长度要一一对应,我这里将特殊的字符要替换为空
        return StringUtils.replaceEach(name,//
                new String[]  {"%22","%27","%28","%29","%2B","%2b","%2F", "%2f","%2f","%25","%3E","%3E","%3E","%3D","%3d","%3C","%3c","%3b","%3B","%3B","%3E",
"%3E",":","\\","'","<",">","\"","/","%20","=",".","@"},             //
                new String[]{"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""});
    }
}

希望以上的内容能帮助到大家,这是我经过了两三次的踩坑得出来的。

 类似资料: