zoukankan      html  css  js  c++  java
  • struts2拦截器来防止sql注入

    SQL注入攻击能得逞是因为在原有SQL语句中加入了新的逻辑

    比如:原sql="select * from user where userid='"+userid+"'";

    如果,我们把userid="' or 1='1";

    这样拼接的sql="select * from user where userid='' or 1='1'";

    这样的sql就可列出表里的所有记录

    对于一个好的程序员来说,编写高质量的代码,可以防止sql注入

    比如使,用PreparedStatement来代替Statement来执行SQL语句,其后只是输入参数

    SQL注入攻击手段将无效,这是因为PreparedStatement不允许在不同的插入时间改变查询的逻辑结构 

    大部分的SQL注入已经挡住了

    有时候我们的sql语句是拼接,这样如果再重构我们的数据库操作的话,会很麻烦的

    为此我们需要对表单中的非法字符进行过滤

    当然,我们可以用Filter来实现,对提交到servlet的表单进行验证

    但是,对于Struts2框架来说,似乎不起作用

    这就需要用到struts2的拦截器来实现同样的功能

    拦截器使用就不再介绍,网上很多

    现在就我的实现代码贴出来供大家参考

    IllegalCharacterInterceptor.java

    import java.util.Iterator;
    import java.util.Map;
    import java.util.Map.Entry;

    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
    import com.opensymphony.xwork2.util.ValueStack;
    import com.sun.imageio.plugins.common.I18N;

    public class IllegalCharacterInterceptor extends AbstractInterceptor {

     @Override
     public String intercept(ActionInvocation invocation) throws Exception {
      //通过核心调度器invocation来获得调度的Action上下文
      ActionContext actionContext = invocation.getInvocationContext();
      //获取Action上下文的值栈
      ValueStack stack = actionContext.getValueStack();
      //获取上下文的请求参数
      Map valueTreeMap = actionContext.getParameters();
      //获得请求参数集合的迭代器
      Iterator iterator = valueTreeMap.entrySet().iterator();
      //遍历组装请求参数
      while(iterator.hasNext()){
       //获得迭代的键值对
       Entry entry = (Entry) iterator.next();
       //获得键值对中的键值
       String key = (String) entry.getKey();
       //原请求参数,因为有可能一键对多值所以这里用的String[]
       String[] oldValues = null;
       //对参数值转换成String类型的
       if(entry.getValue() instanceof String){
        oldValues = new String[]{entry.getValue().toString()};
       }else{
        oldValues = (String[])entry.getValue();
       }
       //处理后的请求参数
       String newValueStr = null;
       //对请求参数过滤处理
       if(oldValues.length>1){
        newValueStr = "{" ;
        for(int i=0 ;i<oldValues.length; i++){
         //替换掉非法参数,这里只替换掉了',如有其他需求,可以专门写一个处理字符的类
         newValueStr+=oldValues[i].toString().replaceAll("'","");
         if(i!=oldValues.length-1){
          newValueStr+=",";
         }
        }
        newValueStr+="}";
       }else if(oldValues.length==1){
        //替换掉非法参数,这里只替换掉了',如有其他需求,可以专门写一个处理字符的类
        newValueStr = oldValues[i].toString().replaceAll("'","");

       }else{
        newValueStr = null;
       }
       //处理后的请求参数加入值栈中
       stack.setValue(key, newValueStr);
      }
      String result = null;
      try {
       // 调用下一个拦截器,如果拦截器不存在,则执行Action 
       result = invocation.invoke();
      } catch (Exception e) {
       e.printStackTrace();
      }
      return result;
     }

    }

    拦截器写好后,就可以使用了

    在struts.xml中配置自定义拦截器时,需把默认拦截器加上

    不然默认拦截器会不起作用的

    <interceptors>
        <interceptor name="illegalCharacter" class="com.ainong.interceptor.IllegalCharacterInterceptor"/>
        <interceptor-stack name="myStack">
         <interceptor-ref name="defaultStack"></interceptor-ref>
         <interceptor-ref name="illegalCharacter"></interceptor-ref>
        </interceptor-stack>
       </interceptors>

    这样就可使用myStack来拦截了

    如果我们对于对每个Action都配置<interceptor-ref name="myStack"/>比较麻烦

    我们也可把上面的拦截器栈,设置为默认拦截器栈,这样可以对package中的所有Action起作用

    而不需要我们配置

    <default-interceptor-ref name="myStack"></default-interceptor-ref>

  • 相关阅读:
    VMware coding Challenge: Coin Toss Betting
    Lintcode: k Sum II
    Lintcode: Interleaving Positive and Negative Numbers
    Lintcode: Insert Node in a Binary Search Tree
    Amazon OA
    Leetcode: Best Time to Buy and Sell Stock IV
    Leetcode: Reverse Words in a String II
    Leetcode: Repeated DNA Sequence
    Leetcode: Rotate Array
    VMware coding Challenge:Date of Weekday
  • 原文地址:https://www.cnblogs.com/qixing/p/interceptor.html
Copyright © 2011-2022 走看看