<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 零全零美 閱讀(1227) 評論(2)  編輯  收藏 所屬分類: 設計模式

    FeedBack:
    # re: 【原創】運用裝飾模式截取用戶輸入構建通用驗證
    2009-11-24 12:42 | 羅萊價格
    統中有文件上傳的地方畢竟不多  回復  更多評論
      
    # re: 【原創】運用裝飾模式截取用戶輸入構建通用驗證
    2009-11-24 17:04 | 零全零美
    暈啊,都是做廣告的!  回復  更多評論
      
    主站蜘蛛池模板: 95老司机免费福利| 国产成人3p视频免费观看| 亚洲人成影院午夜网站| 日本特黄特色免费大片| baoyu116.永久免费视频| 久久亚洲精品中文字幕| 日韩黄色免费观看| 嫩草在线视频www免费看| 亚洲AV日韩综合一区尤物| 亚洲中文字幕丝袜制服一区| 51在线视频免费观看视频| 在线亚洲精品视频| 少妇中文字幕乱码亚洲影视| 国产一级淫片a免费播放口之| 免费网站观看WWW在线观看| 亚洲精品又粗又大又爽A片| 亚洲AV综合色区无码另类小说| 日韩激情淫片免费看| 久久成人无码国产免费播放| 精品视频免费在线| 亚洲乱码一二三四区麻豆| 亚洲情XO亚洲色XO无码| 日本免费人成黄页网观看视频| 日韩精品内射视频免费观看| 一级a性色生活片久久无少妇一级婬片免费放| 91亚洲精品视频| 亚洲中文字幕无码永久在线| 成人免费看片又大又黄| 99久久免费中文字幕精品| WWW国产成人免费观看视频| 亚洲男同gay片| 亚洲图片激情小说| 亚洲v高清理论电影| 色噜噜AV亚洲色一区二区| 俄罗斯极品美女毛片免费播放| 丁香花免费完整高清观看| 无码国产精品一区二区免费模式 | 国产免费变态视频网址网站| 人与禽交免费网站视频| 另类免费视频一区二区在线观看| 美女黄色免费网站|