<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
     在系統開發中,與用戶交互的地方,例如表單輸入,瀏覽器URL傳參都是系統安全的敏感地帶。傳統的客戶端JavaScript驗證只能擋君子而不能攔小人,因為用戶一旦將JS禁用,我們就無能為力。于是人們說最安全的方式還是在服務器端驗證。但是這種最安全的方式卻是很麻煩的做法!因為我們無法只單單的在服務器端驗證,我們還需要做客戶端傳統驗證,這樣一來同一套驗證,客戶端一次,服務器端一次,暫且不考慮執行的效率,單單是開發的效率就很讓人抓狂了!尤其是對URL傳參的驗證,難道我們對每一個URL傳遞參數的地方都必須寫一堆的驗證代碼嗎?
     如果有這樣一種方法能夠通過一個過濾器能夠一次性的攔截獲取所有的用戶輸入,那么我們就可以只通過這個過濾器來做基礎的安全性驗證,例如我們可以過濾SQL語句,過濾非安全字符等等,而把業務規則驗證留給程序員去實現,就將大大的加快開發效率,同時也可以構建一個通用的用戶輸入驗證框架,減少與程序的緊耦合!
     例如我們將所有用戶輸入中的"<"改為"&lt;",將所有的">"改為"&gt;"
     本文試圖尋找一種方法來解決這個問題!
     
     關于對裝飾模式的具體說明,可以自行Google一下,或者可以查看此文:裝飾Servlet Request對象,建議想了解原理的讀者先閱讀一下這篇文章!
     首先我們創建一個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");
            
            
    //重點是這句,該處我們運用裝飾模式構建一個自己的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開發,那么這些Tapestry框架自己的東西,我們忽略掉!
        static{
            characterMap.put(
    "formids""");
            characterMap.put(
    "seedids""");
            characterMap.put(
    "submitmode""");
            characterMap.put(
    "sp""");
            
        }

        
        
    //構造函數
        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) {
            
    //忽略一些我們的設定
            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){
            
    //這里我們可以根據自己的邏輯,編寫適當的正則表達式判斷
            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標簽中enctype="multipart/form-data" ,則該過濾器如果獲取用戶輸入,需要自行驗證,當然一個系統中有文件上傳的地方畢竟不多!所以造成的麻煩是很小的!
     

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

    FeedBack:
    # re: 【原創】運用裝飾模式截取用戶輸入構建通用驗證
    2009-11-24 12:42 | 羅萊價格
    統中有文件上傳的地方畢竟不多  回復  更多評論
      
    # re: 【原創】運用裝飾模式截取用戶輸入構建通用驗證
    2009-11-24 17:04 | 零全零美
    暈啊,都是做廣告的!  回復  更多評論
      
    主站蜘蛛池模板: 在线视频亚洲一区| 中文有码亚洲制服av片| 亚洲AV永久无码精品一百度影院| 免费一级毛片在线播放放视频| 日韩成人在线免费视频| 亚洲AV成人无码天堂| 国产精品视频免费一区二区| 亚洲综合色7777情网站777| 69视频免费在线观看| 亚洲校园春色小说| 亚洲国产精品免费观看| 午夜一级免费视频| 亚洲高清一区二区三区| 狠狠久久永久免费观看| 青青免费在线视频| 久久久久一级精品亚洲国产成人综合AV区| 亚洲αⅴ无码乱码在线观看性色| 日韩激情无码免费毛片| 一级做a爰片久久毛片免费看| 亚洲色图综合在线| 国产精品白浆在线观看免费| 自拍偷区亚洲国内自拍| 特级毛片爽www免费版| 免费黄色毛片视频| 欧洲乱码伦视频免费国产| 亚洲人成人无码网www电影首页| 日本在线看片免费人成视频1000 | aa级毛片毛片免费观看久| 亚洲av无码精品网站| 青青草a免费线观a| 美女黄色免费网站| 亚洲欧洲第一a在线观看| 久久不见久久见免费影院| 特级aaaaaaaaa毛片免费视频| 久久精品夜色噜噜亚洲A∨| 57pao一国产成视频永久免费| 色偷偷噜噜噜亚洲男人| 亚洲乱色熟女一区二区三区丝袜| 成人免费观看一区二区| jizz免费在线影视观看网站| 亚洲成a人片在线观看播放|