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 }