OSDN Git Service

track
[luz/luz.git] / src / com / lavans / luz2 / http / session / AccessFilter.java
1 /* $Id: AccessFilter.java 411 2011-07-28 23:05:04Z dobashi $\r
2  * created: 2006/01/20\r
3  */\r
4 package com.lavans.luz2.http.session;\r
5 \r
6 import java.io.IOException;\r
7 \r
8 import javax.servlet.Filter;\r
9 import javax.servlet.FilterChain;\r
10 import javax.servlet.FilterConfig;\r
11 import javax.servlet.ServletException;\r
12 import javax.servlet.ServletRequest;\r
13 import javax.servlet.ServletResponse;\r
14 import javax.servlet.http.HttpServletRequest;\r
15 import javax.servlet.http.HttpSession;\r
16 import javax.xml.xpath.XPathExpressionException;\r
17 \r
18 import com.lavans.luz2.util.Config;\r
19 \r
20 \r
21 /**\r
22  * 連続アクセスを制御するフィルター。\r
23  * セッションIDまたは口座番号をキーとしてアクセス回数をカウントする。\r
24  * 1秒以内に規定回数以上のアクセスがあったら、エラーとする。\r
25  *\r
26  * @author dobashi\r
27  */\r
28 public class AccessFilter implements Filter {\r
29         /** 設定ファイル読込クラス */\r
30         private static Config config = Config.getInstance();\r
31 \r
32     /** オーバーフローがあった場合のフラグ */\r
33     public static final String ACCESS_FLG = "access_flg";\r
34 \r
35     /**  */\r
36     public static final String ACCESSDATA_KEY = "accessdata_key";\r
37 \r
38         /** アクセスのインターバル(ミリ秒) */\r
39         private static final long ACCESS_INTERVAL = 1000;\r
40 \r
41         /** アクセスの可能回数 */\r
42         private static int maxAccessCount = 10;\r
43 \r
44         static{\r
45                 String accControl = null;\r
46                 try {\r
47                         accControl = config.getNodeValue("/luz/http/access_control");\r
48                 } catch (XPathExpressionException e) {\r
49                 }\r
50                 if(!accControl.equals("")){\r
51                         // 未指定ならデフォルトの10とする。\r
52                         maxAccessCount = Integer.parseInt(accControl);\r
53                 }\r
54         }\r
55 \r
56         /**\r
57          * 1秒あたりのアクセス回数をチェックする。\r
58          * 個別のActionクラスでアクセス解除できるように、ここではセッションにフラグを\r
59          * 立てるだけで例外はThrowしない。ここで例外をThrowすると、画像の一覧表示などが\r
60          * できなくなる。\r
61          */\r
62         public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {\r
63             // セッション管理ロジック\r
64             HttpSession session = ((HttpServletRequest)req).getSession();\r
65 \r
66             // 0以下ならアクセスチェック無し\r
67             if(maxAccessCount<1){\r
68                         chain.doFilter(req, res);\r
69                         return;\r
70             }\r
71 \r
72             // セッションIDをキーにアクセス数を取得する。\r
73                 AccessData data = (AccessData)session.getAttribute(ACCESSDATA_KEY);\r
74                 if(data==null){\r
75                         data = new AccessData(maxAccessCount);\r
76                         session.setAttribute(ACCESSDATA_KEY, data);\r
77                 }\r
78             // 毎回時刻比較を行わなくて済むように、maxのカウント数を入れておいて\r
79             // カウントが0になったときだけ比較するようにする。\r
80 \r
81         // アクセス可能回数をチェック\r
82         if(data.getCount()>0){\r
83                     // アクセス可能回数を減らす\r
84                 data.decreaseCount();\r
85         }else{\r
86                 // カウントが0になった\r
87             // 前回のアクセス時刻、現在時刻を取得\r
88             long now = System.currentTimeMillis();\r
89                     // 現在時刻と10回前のアクセス時刻の差をチェック\r
90                     if((now - data.getLastAccessTime()) < ACCESS_INTERVAL){\r
91                         // 1秒以内ならエラーフラグをセット\r
92                         session.setAttribute(ACCESS_FLG, req.getRemoteAddr());\r
93 //                      throw new AccessOverFlowException("Too many access from["+ req.getRemoteAddr() +":"+ session.getId() +"]");\r
94                     }else{\r
95                         // 1秒以上たっているなら初期化\r
96                         data.init(maxAccessCount);\r
97                         session.removeAttribute(ACCESS_FLG);\r
98                     }\r
99         }\r
100 \r
101                 chain.doFilter(req, res);\r
102         }\r
103 \r
104 \r
105         /* (非 Javadoc)\r
106          * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)\r
107          */\r
108         public void init(FilterConfig arg0) throws ServletException {\r
109         }\r
110 \r
111         /* (非 Javadoc)\r
112          * @see javax.servlet.Filter#destroy()\r
113          */\r
114         public void destroy() {\r
115         }\r
116 \r
117 }\r
118 \r