001 /*
002 * Copyright (c) 2009 The openGion Project.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013 * either express or implied. See the License for the specific language
014 * governing permissions and limitations under the License.
015 */
016 package org.opengion.hayabusa.filter;
017
018 import org.opengion.hayabusa.common.HybsSystem;
019
020 import java.io.IOException;
021 import java.io.PrintWriter;
022
023 import javax.servlet.Filter;
024 import javax.servlet.FilterChain;
025 import javax.servlet.FilterConfig;
026 import javax.servlet.ServletContext;
027 import javax.servlet.ServletException;
028 import javax.servlet.ServletRequest;
029 import javax.servlet.ServletResponse;
030 import javax.servlet.RequestDispatcher;
031 import javax.servlet.http.HttpServletResponse;
032 import javax.servlet.http.HttpServletRequest;
033
034 import org.opengion.fukurou.security.URLHashMap;
035 import org.opengion.fukurou.util.StringUtil;
036 import org.opengion.fukurou.util.FileString;
037
038 /**
039 * URLHashFilter は、Filter インターフェースを継承した URLチェãƒ?‚¯クラスですã?
040 * web.xml で filter 設定することにより、å?ç�?‚’開始しますã?
041 * filter 処ç�??、設定レベルとURLの飛ã?先により処ç�?–¹法が異なりますã?
042 * こã?フィルターでは、ハãƒ?‚·ュåŒ?暗号化ではなくã?アドレスに戻す作業になりますã?
043 * å†?ƒ¨URLの場合ã?ハッシュ化ã?外部URLの場合ã?暗号化に適用されますã?
044 *
045 * 基本çš?�«は、外部へのURLでエンジンシスãƒ?ƒ へ飛ã?すå?合ã?、暗号化になりますã?
046 * å†?ƒ¨へのURLは、基本çš?�«、パラメータのみ暗号化を行いますã?なおã?直接画面IDã‚?
047 * æŒ?®šして飛ã?すå?合を、止めるかどã�?�‹は、設定レベルに依存しますã?
048 *
049 * フィルターの設定レベルは、シスãƒ?ƒ リソースの URL_ACCESS_SECURITY_LEVEL 変数で
050 * 設定しますã?
051 * なおã?å�?ƒ¬ベル共通で、戻しå?ç�??レベルに関係なく実行されますã?
052 * レベル?�:なにも制限ã?ありませんã€?
053 * レベル?‘:Referer チェãƒ?‚¯を行いますã?つまりã?URLを直接入力しても動作しませんã€?
054 * ただしã?Refererが付いてさえã�?‚Œば、アクセス許可を与えますã?
055 * Referer 無しã?場合でもã?URLにパラメータが存在しなã�??またã?ã€?
056 * アドレスがハãƒ?‚·ュåŒ?暗号化されてã�?‚‹場合ã?、アクセスを許可しますã?
057 * レベル?‘ã?場合ã?ハッシュ戻ã�?è¤?�ˆ化å?ç�??行いますã?あくまで、ハãƒ?‚·ュåŒ?
058 * 暗号化されてã�?�ªã�??合でもã?Refererさえあれば、許可するとã�?�†ことですã?
059 * (パラメータなã�?or ハッシュあり or Refererあり の場合ã?許可)
060 * レベル?’:フィルター処ç�?�¨しては、レベル?‘と同じですã?
061 * 異なるã?は、URLのハッシュåŒ?暗号化å?ç�?‚’、外部URLに対してのみ行いますã?
062 * (パラメータなã�?or ハッシュあり or Refererあり の場合ã?許可)
063 * レベル?“:URLのパラメータがハãƒ?‚·ュåŒ?暗号化されてã�?‚‹å¿?¦�がありますã?
064 * レベル?‘同様ã?URLにパラメータが存在しなã�??合ã?、アクセスを許可しますã?
065 * レベル?‘と異なるã?は、パラメータはå¿?�šハッシュ化か、暗号化されてã�?‚‹
066 * å¿?¦�があるとã�?�†ことですã?(å†?ƒ¨/外部問わã�?
067 * (パラメータなã�?or ハッシュあり の場合ã?許可)
068 * それ以外:アクセスを停止しますã?
069 *
070 * フィルターに対してweb.xml でパラメータを設定しますã?
071 * ・filename :停止時メãƒ?‚»ージ表示ファイルå�?ä¾?/jsp/custom/refuseAccess.html)
072 * ・initPage :æœ??にアクセスされるå?期画面アドレス(初期値:/jsp/index.jsp)
073 * ・debug :ãƒ?ƒ�ãƒ?‚°メãƒ?‚»ージの表示(初期値:false)
074 *
075 * 【WEB-INF/web.xmlã€?
076 * <filter>
077 * <filter-name>URLHashFilter</filter-name>
078 * <filter-class>org.opengion.hayabusa.filter.URLHashFilter</filter-class>
079 * <init-param>
080 * <param-name>filename</param-name>
081 * <param-value>/jsp/custom/refuseAccess.html</param-value>
082 * </init-param>
083 * <init-param>
084 * <param-name>initPage</param-name>
085 * <param-value>/jsp/index.jsp</param-value>
086 * </init-param>
087 * <init-param>
088 * <param-name>debug</param-name>
089 * <param-value>false</param-value>
090 * </init-param>
091 * </filter>
092 *
093 * <filter-mapping>
094 * <filter-name>URLHashFilter</filter-name>
095 * <url-pattern>*.jsp</url-pattern>
096 * </filter-mapping>
097 *
098 * @og.group フィルター処ç�?
099 *
100 * @og.rev 5.2.2.0 (2010/11/01) 新規追åŠ?
101 *
102 * @version 5.2.2.0 (2010/11/01)
103 * @author Kazuhiko Hasegawa
104 * @since JDK1.6,
105 */
106 public final class URLHashFilter implements Filter {
107 private static final String REQ_KEY = HybsSystem.URL_HASH_REQ_KEY ;
108
109 private static final int ACCS_LVL = HybsSystem.sysInt( "URL_ACCESS_SECURITY_LEVEL" );
110
111 private String initPage = "/jsp/index.jsp";
112 // private String filename = null; // アクセス拒否時メãƒ?‚»ージ表示ファイルå�?
113 private FileString refuseMsg = null; // アクセス拒否時メãƒ?‚»ージファイルのå†?®¹(キャãƒ?‚·ュ)
114 private boolean isDebug = false;
115
116 /**
117 * フィルター処ç�?œ¬体ã?メソãƒ?ƒ‰ですã?
118 *
119 * @og.rev 5.3.0.0 (2010/12/01) æ–?—化け対策として、setCharacterEncoding を実行するã?
120 *
121 * @param request ServletRequestオブジェクãƒ?
122 * @param response ServletResponseオブジェクãƒ?
123 * @param chain FilterChainオブジェクãƒ?
124 * @throws IOException , ServletException
125 */
126 public void doFilter( final ServletRequest request, final ServletResponse response, final FilterChain chain ) throws IOException, ServletException {
127 HttpServletRequest req = (HttpServletRequest)request ;
128 req.setCharacterEncoding( "UTF-8" ); // 5.3.0.0 (2010/12/01)
129
130 if( isValidAccess( req ) ) {
131 String h_r = req.getParameter( REQ_KEY );
132 // ハッシュ化キーが存在するã€?
133 if( h_r != null ) {
134 HttpServletResponse resp = ((HttpServletResponse)response);
135 String qu = URLHashMap.getValue( h_r );
136 // キーに対する実アドレスが存在するã€?
137 if( qu != null ) {
138 String requestURI = req.getRequestURI(); // /gf/jsp/index.jsp など
139 String cntxPath = req.getContextPath(); // /gf など
140 // 自åˆ??身のコンãƒ?‚ストと同じなので、forward できるã€?
141 if( requestURI.startsWith( cntxPath ) ) {
142 String url = requestURI.substring(cntxPath.length()) + "?" + qu ;
143 RequestDispatcher rd = request.getRequestDispatcher( url );
144 rd.forward( request,response );
145 }
146 // そうでなã�??合ã?リãƒ?‚¤レクトするã?
147 else {
148 String url = resp.encodeRedirectURL( requestURI + "?" + qu );
149 resp.sendRedirect( url );
150 }
151 }
152 // キーに対する実アドレスが存在しなã�??(行き先無しã?ケース)
153 else {
154 String url = resp.encodeRedirectURL( initPage );
155 resp.sendRedirect( url );
156 }
157 }
158 // ハッシュ化キーが存在しなã�??
159 else {
160 chain.doFilter(request, response);
161 }
162 }
163 else {
164 // アクセス拒否を示すメãƒ?‚»ージファイルのå†?®¹をå?力するã?
165 response.setContentType( "text/html; charset=UTF-8" );
166 PrintWriter out = response.getWriter();
167 out.println( refuseMsg.getValue() );
168 out.flush();
169 }
170 }
171
172 /**
173 * フィルターの初期処ç�?ƒ¡ソãƒ?ƒ‰ですã?
174 *
175 * フィルターに対してweb.xml で初期パラメータを設定しますã?
176 * ・filename :停止時メãƒ?‚»ージ表示ファイルå�?
177 * ・initPage :æœ??にアクセスされるå?期画面アドレス(初期値:/jsp/index.jsp)
178 * ・debug :ãƒ?ƒ�ãƒ?‚°メãƒ?‚»ージの表示(初期値:false)
179 *
180 * @param config FilterConfigオブジェクãƒ?
181 */
182 public void init( final FilterConfig config ) {
183 initPage = StringUtil.nval( config.getInitParameter("initPage"), initPage );
184 isDebug = StringUtil.nval( config.getInitParameter("debug") , isDebug );
185
186 ServletContext context = config.getServletContext();
187 String realPath = context.getRealPath( "/" );
188
189 // アクセス拒否を示すメãƒ?‚»ージファイルのå†?®¹を管ç�?�™ã‚?FileString オブジェクトを構築するã?
190 String filename = realPath + config.getInitParameter("filename");
191 refuseMsg = new FileString();
192 refuseMsg.setFilename( filename );
193 refuseMsg.setEncode( "UTF-8" );
194 }
195
196 /**
197 * フィルターの終äº??ç�?ƒ¡ソãƒ?ƒ‰ですã?
198 *
199 */
200 public void destroy() {
201 // ここでは処ç�?‚’行いませんã€?
202 }
203
204 /**
205 * フィルターのå†?ƒ¨状態をチェãƒ?‚¯するメソãƒ?ƒ‰ですã?
206 *
207 * 判定条件は、URL_ACCESS_SECURITY_LEVEL 変数 に応じて異なりますã?
208 * レベル?�:なにも制限ã?ありませんã€?
209 * レベル?‘:Referer チェãƒ?‚¯を行いますã?つまりã?URLを直接入力しても動作しませんã€?
210 * レベル?’:URLのハッシュåŒ?暗号化å?ç�?‚’、外部URLに対してのみ行いますã?(チェãƒ?‚¯は、レベル?‘と同ç?
211 * レベル?“:URLのパラメータがハãƒ?‚·ュåŒ?暗号化されてã�?‚‹å¿?¦�がありますã?
212 * それ以外:アクセスを停止しますã?
213 *
214 * @param request HttpServletRequestオブジェクãƒ?
215 *
216 * @return (true:許可 false:拒否)
217 */
218 private boolean isValidAccess( final HttpServletRequest request ) {
219 if( ACCS_LVL == 0 ) { return true; } // レベル?�:無条件アクセス
220
221 String httpReferer = request.getHeader( "Referer" );
222 String requestURI = request.getRequestURI();
223 String queryString = request.getQueryString();
224 String hashVal = request.getParameter( REQ_KEY );
225
226 if( isDebug ) {
227 System.out.println( "URLHashFilter#httpReferer = " + httpReferer );
228 System.out.println( "URLHashFilter#requestURI = " + requestURI );
229 }
230
231 // 基準となる許可?šパラメータなã�?or ハッシュありの場å�?
232 boolean flag2 = ( queryString == null || hashVal != null ) ;
233
234 // レベル???’:パラメータなã�?or ハッシュあり or Refererあり の場合ã?許可
235 if( ACCS_LVL == 1 || ACCS_LVL == 2 ) {
236 return ( flag2 || httpReferer != null );
237 }
238
239 // レベル?“:パラメータなã�?or ハッシュありの場合ã?許可
240 if( ACCS_LVL == 3 ) {
241 String cntxPath = request.getContextPath(); // /gf など
242 // 特別処置
243 return flag2 ||
244 requestURI.equalsIgnoreCase( initPage ) ||
245 requestURI.startsWith( cntxPath + "/jsp/menu/" ) ||
246 requestURI.startsWith( cntxPath + "/jsp/custom/" ) ||
247 requestURI.startsWith( cntxPath + "/jsp/common/" ) ;
248 }
249
250 return false; // それ以外:無条件拒否
251 }
252
253 /**
254 * å†?ƒ¨状態をæ–?—å?で返しますã?
255 *
256 * @return こã?クラスのæ–?—å?表示
257 */
258 @Override
259 public String toString() {
260 StringBuilder sb = new StringBuilder()
261 .append( this.getClass().getCanonicalName() ).append( " : ")
262 .append( "initPage = [" ).append( initPage ).append( "] , ")
263 // .append( "filename = [" ).append( filename ).append( "] , ")
264 .append( "isDebug = [" ).append( isDebug ).append( "]");
265 return (sb.toString());
266 }
267 }