<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    零全零美(www.zzgwt.com)
    生活中的很多事情,并不像If...Else那么簡單!
    posts - 96,comments - 52,trackbacks - 0
     在系統(tǒng)開發(fā)中,與用戶交互的地方,例如表單輸入,瀏覽器URL傳參都是系統(tǒng)安全的敏感地帶。傳統(tǒng)的客戶端JavaScript驗證只能擋君子而不能攔小人,因為用戶一旦將JS禁用,我們就無能為力。于是人們說最安全的方式還是在服務(wù)器端驗證。但是這種最安全的方式卻是很麻煩的做法!因為我們無法只單單的在服務(wù)器端驗證,我們還需要做客戶端傳統(tǒng)驗證,這樣一來同一套驗證,客戶端一次,服務(wù)器端一次,暫且不考慮執(zhí)行的效率,單單是開發(fā)的效率就很讓人抓狂了!尤其是對URL傳參的驗證,難道我們對每一個URL傳遞參數(shù)的地方都必須寫一堆的驗證代碼嗎?
     如果有這樣一種方法能夠通過一個過濾器能夠一次性的攔截獲取所有的用戶輸入,那么我們就可以只通過這個過濾器來做基礎(chǔ)的安全性驗證,例如我們可以過濾SQL語句,過濾非安全字符等等,而把業(yè)務(wù)規(guī)則驗證留給程序員去實現(xiàn),就將大大的加快開發(fā)效率,同時也可以構(gòu)建一個通用的用戶輸入驗證框架,減少與程序的緊耦合!
     例如我們將所有用戶輸入中的"<"改為"&lt;",將所有的">"改為"&gt;"
     本文試圖尋找一種方法來解決這個問題!
     
     關(guān)于對裝飾模式的具體說明,可以自行Google一下,或者可以查看此文:裝飾Servlet Request對象,建議想了解原理的讀者先閱讀一下這篇文章!
     首先我們創(chuàng)建一個filter,讓它可以攔截所有的請求!
     <filter>
      
    <filter-name>userInputFilter</filter-name>
      
    <filter-class>
       com.djwl.core.security.UserInputFilter
      
    </filter-class>
     
    </filter>
     
    <filter-mapping>
      
    <filter-name>userInputFilter</filter-name>
      
    <url-pattern>/*</url-pattern>
     
    </filter-mapping>

    package com.djwl.core.security;

    import java.io.IOException;

    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;

    /**
     * 功能描述:過濾用戶輸入的危險字符,及SQL語句<BR>
     * 
    @author 楊凱 <BR>
     * 時間:Jun 9, 2009 1:22:03 PM <BR>
     
    */

    public class UserInputFilter implements javax.servlet.Filter {

        
    public void destroy() {
            
        }


        
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest request 
    = (HttpServletRequest)servletRequest;
            request.setCharacterEncoding(
    "gbk");
            
            
    //重點是這句,該處我們運用裝飾模式構(gòu)建一個自己的ServletRequest類
            chain.doFilter(new UserInputFilterHttpServletRequestWrapper(request), servletResponse);
        }


        
    public void init(FilterConfig filterConfig) throws ServletException {
            
        }


    }


    package com.djwl.core.security;

    import java.util.HashMap;
    import java.util.Map;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;

    import com.djwl.core.utils.V;

    public final class UserInputFilterHttpServletRequestWrapper extends HttpServletRequestWrapper {

        
    public final static Map characterMap = new HashMap();
        
        
    //對于一些我們不想讓該類驗證的值,例如我使用Tapestry開發(fā),那么這些Tapestry框架自己的東西,我們忽略掉!
        static{
            characterMap.put(
    "formids""");
            characterMap.put(
    "seedids""");
            characterMap.put(
    "submitmode""");
            characterMap.put(
    "sp""");
            
        }

        
        
    //構(gòu)造函數(shù)
        public UserInputFilterHttpServletRequestWrapper(HttpServletRequest request) {
            
    super(request);
        }

        
        
    //驗證從頁面上提取單個值的情況,包括URL傳參
        @Override
        
    public String getParameter(String name) {
            
    return  V.validate(super.getParameter(name));
        }

        
        
    //驗證從頁面上一次性獲取多個值的情況
        @Override
        
    public String[] getParameterValues(String name) {
            
    //忽略一些我們的設(shè)定
            if (characterMap.containsKey(name)) {
                
    return super.getParameterValues(name);
            }

            String[] userinputs 
    = super.getParameterValues(name);
            
    if (userinputs == null{
                
    return null;
            }

            
    //逐一判斷
            String[] results = new String[userinputs.length];
            
    int i=0;
            
    for (String string : userinputs) {
                results[i] 
    = V.validate(string);
                i
    ++;
            }

            
    return results;      
        }

    }


     
    package com.djwl.core.utils;

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    import org.apache.commons.lang.StringUtils;

    import com.djwl.core.MisException;

    public class V {
        
        
    /**
         * 功能描述:改變用戶輸入<BR>
         * 
    @param str
         * 
    @return
         * 
    @author:楊凱<BR>
         * 時間:Nov 24, 2009 12:07:57 PM<BR>
         
    */

        
    private static String escape(String str){
    //        str = StringEscapeUtils.escapeSql(str);
    //        str = StringEscapeUtils.escapeHtml(str);
    //        //str = StringEscapeUtils.escapeJavaScript(str);
    //        str = str.replaceAll("#", "");
            str = str.replaceAll("<""&lt;").replaceAll(">""&gt;");
            str 
    = str.replaceAll("\r\n""<BR>");
            str 
    = str.replaceAll("null"" ");
            
    return str;
        }

        
        
    /**
         * 功能描述:截取危險字符<BR>
         * 
    @param str
         * 
    @return
         * 
    @author:楊凱<BR>
         * 時間:Nov 24, 2009 12:08:08 PM<BR>
         
    */

        
    private static Boolean contains(String str){
            
    //這里我們可以根據(jù)自己的邏輯,編寫適當(dāng)?shù)恼齽t表達(dá)式判斷
            String regexp = "\\b(drop|delete|update|insert|select|call|exec|set|declare|script|link)\\b";
            Matcher matcher 
    = Pattern.compile(regexp).matcher(str.toLowerCase());
            
    if (matcher.find()) {
                
    throw new MisException("用戶輸入中含有非法字符");
            }
     else {
                
    return true;
            }

        }

        
        
    /**
         * 功能描述:驗證字符串<BR>
         * 
    @param str
         * 
    @return
         * 
    @author:楊凱<BR>
         * 時間:Jun 9, 2009 5:09:31 PM<BR>
         
    */

        
    public static String validate(String str){
            
    if (StringUtils.isNotBlank(str) && contains(str)) {
                
    return escape(str);
            }

            
    return null;
        }

        
        
    }


         需要說明的一點是,如果表單中有文件上傳的控件,意思是說如果from標(biāo)簽中enctype="multipart/form-data" ,則該過濾器如果獲取用戶輸入,需要自行驗證,當(dāng)然一個系統(tǒng)中有文件上傳的地方畢竟不多!所以造成的麻煩是很小的!
     

           文章原創(chuàng),轉(zhuǎn)載請以鏈接方式著名出處!【原創(chuàng)】運用裝飾模式截取用戶輸入構(gòu)建通用驗證
    posted on 2009-11-24 12:15 零全零美 閱讀(1227) 評論(2)  編輯  收藏 所屬分類: 設(shè)計模式

    FeedBack:
    # re: 【原創(chuàng)】運用裝飾模式截取用戶輸入構(gòu)建通用驗證
    2009-11-24 12:42 | 羅萊價格
    統(tǒng)中有文件上傳的地方畢竟不多  回復(fù)  更多評論
      
    # re: 【原創(chuàng)】運用裝飾模式截取用戶輸入構(gòu)建通用驗證
    2009-11-24 17:04 | 零全零美
    暈啊,都是做廣告的!  回復(fù)  更多評論
      
    主站蜘蛛池模板: 37pao成人国产永久免费视频| 亚洲国产国产综合一区首页| 很黄很黄的网站免费的| 成人免费777777被爆出| 国产亚洲综合视频| 亚洲日本va一区二区三区| 久久亚洲AV成人出白浆无码国产| 中文字幕亚洲日本岛国片| 国产gav成人免费播放视频| 成年女人毛片免费视频| 日韩中文字幕精品免费一区| 久久久久久久岛国免费播放| 你是我的城池营垒免费看| 午夜免费国产体验区免费的| 亚洲Av无码国产一区二区| 亚洲看片无码在线视频| 亚洲电影唐人社一区二区| 亚洲视频一区调教| 亚洲人成依人成综合网| 亚洲AV无码1区2区久久| 亚洲成AV人片在线观看无码| 亚洲精品国产字幕久久不卡| 久久久久亚洲精品男人的天堂| 亚洲Av无码乱码在线znlu| 免费v片在线观看| 免费一级特黄特色大片在线观看| 日本大片在线看黄a∨免费| 超pen个人视频国产免费观看| 久久电影网午夜鲁丝片免费| 99久久综合国产精品免费| A在线观看免费网站大全| 成人免费在线视频| 在线免费视频一区| 国产成人在线观看免费网站| 免费看一级做a爰片久久| 免费A级毛片在线播放不收费| 亚洲成aⅴ人片久青草影院| 亚洲av无码成人精品区| 精品国产亚洲一区二区在线观看| 国产亚洲成av片在线观看 | 亚洲熟妇AV乱码在线观看|