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