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 */ 016package org.opengion.hayabusa.filter; 017 018import jakarta.servlet.ServletRequest; 019import jakarta.servlet.http.HttpServletRequest; 020import jakarta.servlet.ServletResponse; 021import jakarta.servlet.ServletException; 022import jakarta.servlet.Filter; 023import jakarta.servlet.FilterChain; 024import jakarta.servlet.FilterConfig; 025 026import java.io.File; // 5.7.3.2 (2014/02/28) Tomcat8 対応 027import java.io.PrintWriter; 028import java.io.BufferedReader; 029import java.io.IOException; 030import java.io.UnsupportedEncodingException; 031import java.nio.charset.CharacterCodingException; // 6.3.1.0 (2015/06/28) 032 033import org.opengion.fukurou.system.OgRuntimeException ; // 6.4.2.0 (2016/01/29) 034import org.opengion.fukurou.system.OgCharacterException ; // 6.5.0.1 (2016/10/21) 035import org.opengion.fukurou.system.DateSet; // 6.4.2.0 (2016/01/29) 036import org.opengion.fukurou.system.Closer; 037import org.opengion.fukurou.util.FileUtil; // 6.2.0.0 (2015/02/27) 038import org.opengion.fukurou.util.StringUtil; // 6.3.8.0 (2015/09/11) 039import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE; // 6.1.0.0 (2014/12/26) refactoring 040import static org.opengion.fukurou.system.HybsConst.CR; // 6.3.1.0 (2015/06/28) 041import org.opengion.hayabusa.common.HybsSystem; // 6.2.4.1 (2015/05/22) 042 043/** 044 * AccessStopFilter は、Filter インターフェースを継承した アクセス制御クラスです。 045 * web.xml で filter 設定することにより、Webアプリケーションへのアクセスを制御できます。 046 * また、SYSTEM ユーザーは、このフィルターを常に通過します。 047 * 048 * フィルターに対してweb.xml でパラメータを設定します。 049 * ・startTime:停止開始時刻 (初期値:230000) 050 * ・stopTime :停止終了時刻 (初期値:070000) 051 * ・filename :停止時メッセージ表示ファイル名 (初期値:jsp/custom/stopFile.html) 052 * ・passUsers:停止中でもアクセス可能なユーザーID (初期値:SYSTEM,ADMIN) 053 * ・addUsers :停止中でもアクセス可能な追加ユーザーID (初期値:null) 054 * 055 * 【WEB-INF/web.xml】 056 * <filter> 057 * <filter-name>AccessStopFilter</filter-name> 058 * <filter-class>org.opengion.hayabusa.filter.AccessStopFilter</filter-class> 059 * <init-param> 060 * <param-name>startTime</param-name> 061 * <param-value>070000</param-value> 062 * </init-param> 063 * <init-param> 064 * <param-name>stopTime</param-name> 065 * <param-value>070000</param-value> 066 * </init-param> 067 * <init-param> 068 * <param-name>filename</param-name> 069 * <param-value>jsp/custom/stopFile.html</param-value> 070 * </init-param> 071 * </filter> 072 * 073 * <filter-mapping> 074 * <filter-name>AccessStopFilter</filter-name> 075 * <url-pattern>/jsp/*</url-pattern> 076 * </filter-mapping> 077 * 078 * @og.group フィルター処理 079 * 080 * @version 4.0 081 * @author Kazuhiko Hasegawa 082 * @since JDK5.0, 083 */ 084public final class AccessStopFilter implements Filter { 085 086 private static boolean useFilter = true ; // 6.3.8.3 (2015/10/03) 087 088 private String startTime = "230000"; // 停止開始時刻 089 private String stopTime = "070000"; // 停止終了時刻 090 private String filename = "jsp/custom/stopFile.html"; // 6.3.8.0 (2015/09/11) 停止時メッセージ表示ファイル名 091 private String passUsers = "SYSTEM,admin"; // 6.3.8.0 (2015/09/11) 停止中でもアクセス可能なユーザーID 092 private int startStop ; 093 094 private static final String USERID_HEADER = HybsSystem.sys( "USERID_HEADER_NAME" ); // 5.10.18.0 (2019/11/29) 095 096 /** 097 * フィルター処理本体のメソッドです。 098 * 099 * @og.rev 3.1.3.0 (2003/04/10) UTF-8 決め打ちで、stopFile.html を返送する。 100 * @og.rev 3.1.8.0 (2003/05/16) 文字エンコードが、UTF-8 になっていないのを修正。 101 * @og.rev 6.2.0.0 (2015/02/27) new BufferedReader … を、FileUtil.getBufferedReader … に変更。 102 * @og.rev 6.3.1.0 (2015/06/28) nioを使用すると UTF-8とShuft-JISで、エラーになる。 103 * @og.rev 6.3.8.3 (2015/10/03) フィルターの停止処理。 104 * @og.rev 6.5.0.1 (2016/10/21) CharacterCodingException は、OgCharacterException に変換する。 105 * 106 * @param request ServletRequestオブジェクト 107 * @param response ServletResponseオブジェクト 108 * @param chain FilterChainオブジェクト 109 * @throws IOException 入出力エラーが発生した場合、throw されます。 110 * @throws ServletException サーブレット関係のエラーが発生した場合、throw されます。 111 */ 112 @Override // Filter 113 public void doFilter( final ServletRequest request, 114 final ServletResponse response, 115 final FilterChain chain) throws IOException, ServletException { 116 117 if( useFilter && isStop( request ) ) { // 6.3.8.3 (2015/10/03) フィルターの停止処理 118 BufferedReader in = null ; 119 try { 120 response.setContentType( "text/html; charset=UTF-8" ); 121 final PrintWriter out = response.getWriter(); 122 in = FileUtil.getBufferedReader( new File( filename ), "UTF-8" ); // 6.2.0.0 (2015/02/27) 123 String str ; 124 while( (str = in.readLine()) != null ) { 125 out.println( str ); 126 } 127 out.flush(); 128 } 129 catch( final UnsupportedEncodingException ex ) { 130 final String errMsg = "指定されたエンコーディングがサポートされていません。[UTF-8]" ; 131 throw new OgRuntimeException( errMsg,ex ); 132 } 133 // 6.3.1.0 (2015/06/28) nioを使用すると UTF-8とShuft-JISで、エラーになる。 134 catch( final CharacterCodingException ex ) { 135 final String errMsg = "文字のエンコード・エラーが発生しました。" + CR 136 + " ファイルのエンコードが指定のエンコードと異なります。" + CR 137 + " [" + filename + "] , Encode=[UTF-8]" ; 138 throw new OgCharacterException( errMsg,ex ); // 6.5.0.1 (2016/10/21) 139 } 140 catch( final IOException ex ) { 141 final String errMsg = "ストリームがオープン出来ませんでした。[" + filename + "]" ; 142 throw new OgRuntimeException( errMsg,ex ); 143 } 144 finally { 145 Closer.ioClose( in ); 146 } 147 return; 148 } 149 150 chain.doFilter(request, response); 151 } 152 153 /** 154 * フィルターの初期処理メソッドです。 155 * 156 * フィルターに対してweb.xml で初期パラメータを設定します。 157 * ・startTime:停止開始時刻 (初期値:230000) 158 * ・stopTime :停止終了時刻 (初期値:070000) 159 * ・filename :停止時メッセージ表示ファイル名 (初期値:jsp/custom/stopFile.html) 160 * ・passUsers:停止中でもアクセス可能なユーザーID (初期値:SYSTEM,admin) 161 * ・addUsers :停止中でもアクセス可能な追加ユーザーID (初期値:null) 162 * 163 * @og.rev 5.7.3.2 (2014/02/28) Tomcat8 対応。getRealPath( "/" ) の互換性のための修正。 164 * @og.rev 6.2.4.1 (2015/05/22) REAL_PATH 対応。realPath は、HybsSystem経由で、取得する。 165 * @og.rev 6.3.8.0 (2015/09/11) パラメータの初期値設定と、passUsers、addUsers 属性追加 166 * @og.rev 7.1.0.0 (2020/01/27) フィルターが実行されているかどうかを、System.setProperty で設定しておきます。 167 * 168 * @param filterConfig FilterConfigオブジェクト 169 */ 170 @Override // Filter 171 public void init( final FilterConfig filterConfig ) { 172 // 6.3.8.0 (2015/09/11) パラメータの初期値設定と、passUsers、addUsers 属性追加 173 startTime = StringUtil.nval( filterConfig.getInitParameter( "startTime" ) , startTime ); 174 stopTime = StringUtil.nval( filterConfig.getInitParameter( "stopTime" ) , stopTime ); 175 filename = HybsSystem.getRealPath() 176 + StringUtil.nval( filterConfig.getInitParameter( "filename" ) , filename ); 177 passUsers = StringUtil.nval( filterConfig.getInitParameter( "passUsers" ) , passUsers ) // 6.3.8.0 (2015/09/11) 新規 178 + ',' + filterConfig.getInitParameter( "addUsers" ) ; 179 180 if( startTime == null || stopTime == null ) { 181 startStop = 0; 182 } 183 else { 184 startStop = startTime.compareTo( stopTime ); 185 } 186 187 // 7.1.0.0 (2020/01/27) フィルターが実行されているかどうかを、System.setProperty で設定しておきます。 188 System.setProperty( "AccessStopFilter" , "true" ); 189 } 190 191 /** 192 * フィルターの終了処理メソッドです。 193 * 194 */ 195 @Override // Filter 196 public void destroy() { 197 // ここでは処理を行いません。 198 } 199 200 /** 201 * フィルターの内部状態をチェックするメソッドです。 202 * 内部のフラグをもとに、停止/許可を求めます。 203 * 204 * @og.rev 3.1.8.0 (2003/05/16) 開始時刻と終了時刻を同一にしていると、画面からの制御が効かないバグを修正。 205 * @og.rev 5.5.3.2 (2012/06/08) 通過させるユーザーに、admin を追加します。 206 * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します。 207 * @og.rev 6.3.8.0 (2015/09/11) パラメータの初期値設定と、passUsers、addUsers 属性追加 208 * @og.rev 6.3.8.3 (2015/10/03) フィルターの停止処理。判定をdoFilterメソッドに移動。 209 * @og.rev 5.10.18.0 (2019/11/29) ヘッダ認証 210 * 211 * @param request ServletRequestオブジェクト 212 * 213 * @return (true:停止 false:実行許可) 214 */ 215 private boolean isStop( final ServletRequest request ) { 216// final String userID = ((HttpServletRequest)request).getRemoteUser() ; 217 String userID = ((HttpServletRequest)request).getRemoteUser() ; 218 219 // 5.10.18.0 (2019/11/29) ヘッダ認証 220 if( USERID_HEADER != null && USERID_HEADER.length() > 0 && ( userID == null || userID.length() == 0) ) { 221 userID = ((HttpServletRequest)request).getHeader( USERID_HEADER ); 222 } 223 224 // 5.5.3.2 (2012/06/08) 通過させるユーザーに、admin を追加 225 // 6.3.8.0 (2015/09/11) パラメータの初期値設定と、passUsers、addUsers 属性追加 226 if( passUsers.contains( userID ) ) { return false; } 227 228 // 4.0.0 (2005/01/31) 229 final String time = DateSet.getDate( "HHmmss" ); // 5.5.7.2 (2012/10/09) HybsDateUtil を利用 230 231 return startStop < 0 && startTime.compareTo( time ) < 0 && time.compareTo( stopTime ) < 0 || 232 startStop > 0 && ( startTime.compareTo( time ) < 0 || time.compareTo( stopTime ) < 0 ) ; 233 234 // boolean rtnFlag = stopFilter; 235 // if( startStop < 0 ) { 236 // if( startTime.compareTo( time ) < 0 && 237 // time.compareTo( stopTime ) < 0 ) { 238 // rtnFlag = true; 239 // } 240 // } 241 // else if( startStop > 0 ) { 242 // if( startTime.compareTo( time ) < 0 || 243 // time.compareTo( stopTime ) < 0 ) { 244 // rtnFlag = true; 245 // } 246 // } 247 // return rtnFlag; 248 } 249 250 /** 251 * フィルターの実行/停止を設定するメソッドです。 252 * 253 * 初期値は、true:実行 です。 254 * 255 * @og.rev 4.0.0.0 (2005/01/31) synchronized の廃止 256 * @og.rev 6.3.8.3 (2015/10/03) フィルターの停止処理。メソッド名変更、引数の意味反転。 257 * 258 * @param flag (true:実行 false:停止) 259 */ 260 public static void setUseFilter( final boolean flag ) { 261 useFilter = flag; 262 } 263 264 /** 265 * フィルターの内部状態(強制停止/解除)を取得するメソッドです。 266 * これは、現在、アクセス制限がどうなっているかという状態ではなく、 267 * 強制停止されているかどうかの確認メソッドです。 268 * 269 * @og.rev 4.0.0.0 (2007/11/29) getStopFilter() ⇒ isStopFilter() に変更 270 * @og.rev 6.3.8.3 (2015/10/03) フィルターの停止処理。メソッド名変更、戻り値の意味反転。 271 * 272 * @return (true:実行 false:停止) 273 */ 274 public static boolean isUseFilter() { 275 return useFilter; 276 } 277 278 /** 279 * 内部状態を文字列で返します。 280 * 281 * @return このクラスの文字列表示 282 * @og.rtnNotNull 283 */ 284 @Override // Object 285 public String toString() { 286 final StringBuilder sb = new StringBuilder( BUFFER_MIDDLE ) 287 .append( "AccessStopFilter" ) 288 .append( '[' ).append( startTime ).append( "],") // 6.0.2.5 (2014/10/31) char を append する。 289 .append( '[' ).append( stopTime ).append( "],") 290 .append( '[' ).append( filename ).append( "],"); 291 return sb.toString(); 292 } 293}