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 java.io.File; // 5.7.3.2 (2014/02/28) Tomcat8 対? 019 import java.io.BufferedReader; 020 import java.io.FileInputStream; 021 import java.io.IOException; 022 import java.io.InputStreamReader; 023 import java.io.PrintWriter; 024 import java.io.UnsupportedEncodingException; 025 026 import javax.servlet.Filter; 027 import javax.servlet.FilterChain; 028 import javax.servlet.FilterConfig; 029 import javax.servlet.ServletContext; 030 import javax.servlet.ServletException; 031 import javax.servlet.ServletRequest; 032 import javax.servlet.ServletResponse; 033 import javax.servlet.http.HttpServletRequest; 034 035 import org.opengion.fukurou.security.HybsCryptography; 036 import org.opengion.fukurou.util.Closer; 037 import org.opengion.fukurou.util.StringUtil; 038 import org.opengion.hayabusa.common.HybsSystem; 039 040 /** 041 * URLCheckFilter は、Filter インターフェースを継承した URLチェ?クラスです? 042 * web.xml で filter 設定することにより、該当?リソースに対して、og:linkタグで? 043 * useURLCheck="true"が指定されたリンクURL以外を拒否することができます? 044 * また?og:linkタグを経由した場合でも?リンクの有効期限を設定することで? 045 * リンクURLの漏洩に対しても??時間?経過を持って、アクセスを拒否することができます? 046 * また?リンク時にユーザー??も埋め込んで?す?で(初期値は、ログインユーザー)? 047 * リンクアドレスが他?ユーザーに知られた?合でも?アクセスを拒否することができます? 048 * 049 * フィルターに対してweb.xml でパラメータを設定します? 050 * ・filename :停止時メ?ージ表示ファイル? 051 * ・ignoreURL:暗号化されたURLの?空白に置き換える接頭??を指定します? 052 * 外部からアクセスしたURLがロードバランサで?向けURLに変換されてチェ?が動作しな??場合に 053 * 利用します?https://wwwX.のように?します?通常は設定しません? 054 * 055 * 【WEB-INF/web.xml? 056 * <filter> 057 * <filter-name>URLCheckFilter</filter-name> 058 * <filter-class>org.opengion.hayabusa.filter.URLCheckFilter</filter-class> 059 * <init-param> 060 * <param-name>filename</param-name> 061 * <param-value>jsp/custom/refuseAccess.html</param-value> 062 * </init-param> 063 * </filter> 064 * 065 * <filter-mapping> 066 * <filter-name>URLCheckFilter</filter-name> 067 * <url-pattern>/jsp/*</url-pattern> 068 * </filter-mapping> 069 * 070 * @og.group フィルター処? 071 * 072 * @version 4.0 073 * @author Hiroki Nakamura 074 * @since JDK5.0, 075 */ 076 public final class URLCheckFilter implements Filter { 077 078 private static final HybsCryptography HYBS_CRYPTOGRAPHY = new HybsCryptography(); // 4.3.7.0 (2009/06/01) 079 080 private String filename = null; // アクセス拒否時メ?ージ表示ファイル? 081 // private int maxInterval = 3600; // リンクの有効期限 082 private boolean isDebug = false; 083 private boolean isDecode = true; // 5.4.5.0(2012/02/28) URIDecodeするかど? 084 085 private String ignoreURL = null; //5.8.6.1 (2015/04/17) 飛んできたcheckURLから取り除くURL?? 086 087 /** 088 * フィルター処?体?メソ?です? 089 * 090 * @param request ServletRequestオブジェク? 091 * @param response ServletResponseオブジェク? 092 * @param chain FilterChainオブジェク? 093 * @throws ServletException サーブレ?関係?エラーが発生した?合?throw されます? 094 */ 095 public void doFilter( final ServletRequest request, final ServletResponse response, final FilterChain chain ) throws IOException, ServletException { 096 097 if( !isValidAccess( request ) ) { 098 BufferedReader in = null ; 099 try { 100 response.setContentType( "text/html; charset=UTF-8" ); 101 PrintWriter out = response.getWriter(); 102 in = new BufferedReader( new InputStreamReader( 103 new FileInputStream( filename ) ,"UTF-8" ) ); 104 String str ; 105 while( (str = in.readLine()) != null ) { 106 out.println( str ); 107 } 108 out.flush(); 109 } 110 catch( UnsupportedEncodingException ex ) { 111 String errMsg = "?されたエンコー?ングがサポ?トされて?せん?UTF-8]" ; 112 throw new RuntimeException( errMsg,ex ); 113 } 114 catch( IOException ex ) { 115 String errMsg = "ストリー?オープン出来ませんでした?" + filename + "]" ; 116 throw new RuntimeException( errMsg,ex ); 117 } 118 finally { 119 Closer.ioClose( in ); 120 } 121 return; 122 } 123 124 chain.doFilter(request, response); 125 } 126 127 /** 128 * フィルターの初期処?ソ?です? 129 * 130 * フィルターに対してweb.xml で初期パラメータを設定します? 131 * ・maxInterval:リンクの有効期限 132 * ・filename :停止時メ?ージ表示ファイル? 133 * ・decode :URL?ードを行ってチェ?する?初期true) 134 * 135 * @og.rev 5.4.5.0 (2102/02/28) 136 * @og.rev 5.7.3.2 (2014/02/28) Tomcat8 対応?getRealPath( "/" ) の互換性のための修正? 137 * @og.rev 5.8.6.1 (2015/04/17) DMZのURL変換対? 138 * 139 * @param filterConfig FilterConfigオブジェク? 140 */ 141 public void init(final FilterConfig filterConfig) { 142 ServletContext context = filterConfig.getServletContext(); 143 // String realPath = context.getRealPath( "/" ); 144 String realPath = context.getRealPath( "" ) + File.separator; // 5.7.3.2 (2014/02/28) Tomcat8 対? 145 146 // maxInterval = StringUtil.nval( filterConfig.getInitParameter("maxInterval"), maxInterval ); 147 filename = realPath + filterConfig.getInitParameter("filename"); 148 isDebug = StringUtil.nval( filterConfig.getInitParameter("debug"), false ); 149 isDecode = StringUtil.nval( filterConfig.getInitParameter("decode"), true ); // 5.4.5.0(2012/02/28) 150 ignoreURL = filterConfig.getInitParameter("ignoreURL"); // 5.8.6.1 (2015/04/17) 151 } 152 153 /** 154 * フィルターの終???ソ?です? 155 * 156 */ 157 public void destroy() { 158 // ここでは処?行いません? 159 } 160 161 /** 162 * フィルターの?状態をチェ?するメソ?です? 163 * 164 * @og.rev 5.4.5.0 (2012/02/28) Decode 165 * 166 * @param request ServletRequestオブジェク? 167 * 168 * @return (true:許可 false:拒否) 169 */ 170 private boolean isValidAccess( final ServletRequest request ) { 171 String checkKey = request.getParameter( HybsSystem.URL_CHECK_KEY ); 172 if( checkKey == null || checkKey.length() == 0 ) { 173 if( isDebug ) { 174 System.out.println( " check NG [ No Check Key ]" ); 175 } 176 return false; 177 } 178 179 boolean rtn = false; 180 try { 181 checkKey = HYBS_CRYPTOGRAPHY.decrypt( checkKey ).replace( "&", "&" ); 182 183 if( isDebug ) { 184 System.out.println( "checkKey=" + checkKey ); 185 } 186 187 String url = checkKey.substring( 0 , checkKey.lastIndexOf( ",time=") ); 188 long time = Long.parseLong( checkKey.substring( checkKey.lastIndexOf( ",time=") + 6, checkKey.lastIndexOf( ",userid=" ) ) ); 189 String userid = checkKey.substring( checkKey.lastIndexOf( ",userid=") + 8 ); 190 // 4.3.8.0 (2009/08/01) 191 String[] userArr = StringUtil.csv2Array( userid ); 192 193 // 5.8.6.1 (2015/04/17)ignoreURL対? 194 if( ignoreURL!=null && ignoreURL.length()>0 && url.indexOf( ignoreURL ) == 0 ){ 195 url = url.substring( ignoreURL.length() ); 196 } 197 198 if( isDebug ) { 199 System.out.println( " [ignoreURL]=" + ignoreURL ); // 2015/04/17 (2015/04/17) 200 System.out.println( " [url] =" + url ); 201 System.out.println( " [vtime] =" + time ); 202 System.out.println( " [userid] =" + userid ); 203 } 204 205 String reqStr = ((HttpServletRequest)request).getRequestURL().toString() + "?" + ((HttpServletRequest)request).getQueryString(); 206 // 5.4.5.0 (2012/02/28) URLDecodeを行う 207 if(isDecode){ 208 if( isDebug ) { 209 System.out.println( "[BeforeURIDecode]="+reqStr ); 210 } 211 reqStr = StringUtil.urlDecode( reqStr ); 212 } 213 reqStr = reqStr.substring( 0, reqStr.lastIndexOf( HybsSystem.URL_CHECK_KEY ) -1 ); 214 // String reqStr = ((HttpServletRequest)request).getRequestURL().toString(); 215 String reqUser = ((HttpServletRequest)request).getRemoteUser(); 216 217 if( isDebug ) { 218 System.out.println( " [reqURL] =" + reqStr ); 219 System.out.println( " [ctime] =" + System.currentTimeMillis() ); 220 System.out.println( " [reqUser]=" + reqUser ); 221 } 222 223 if( reqStr.endsWith( url ) 224 // && System.currentTimeMillis() - time < maxInterval * 1000 225 && System.currentTimeMillis() - time < 0 226 // && userid.equals( reqUser ) ) { 227 && userArr != null && userArr.length > 0 ) { 228 // 4.3.8.0 (2009/08/01) 229 for( int i=0; i<userArr.length; i++ ) { 230 if( "*".equals( userArr[i] ) || reqUser.equals( userArr[i] ) ) { 231 rtn = true; 232 if( isDebug ) { 233 System.out.println( " check OK" ); 234 } 235 break; 236 } 237 } 238 } 239 } 240 catch( RuntimeException ex ) { 241 if( isDebug ) { 242 String errMsg = "チェ?エラー?" 243 + " checkKey=" + checkKey 244 + " " + ex.getMessage(); // 5.1.8.0 (2010/07/01) errMsg 修正 245 System.out.println( errMsg ); 246 ex.printStackTrace(); 247 } 248 rtn = false; 249 } 250 return rtn; 251 } 252 253 /** 254 * ?状態を??で返します? 255 * 256 * @return こ?クラスの??表示 257 */ 258 @Override 259 public String toString() { 260 StringBuilder sb = new StringBuilder(); 261 sb.append( "UrlCheckFilter" ); 262 // sb.append( "[" ).append( maxInterval ).append( "],"); 263 sb.append( "[" ).append( filename ).append( "],"); 264 return (sb.toString()); 265 } 266 }