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 public void doFilter( final ServletRequest request, 113 final ServletResponse response, 114 final FilterChain chain) throws IOException, ServletException { 115 116 if( useFilter && isStop( request ) ) { // 6.3.8.3 (2015/10/03) フィルターの停止処理 117 BufferedReader in = null ; 118 try { 119 response.setContentType( "text/html; charset=UTF-8" ); 120 final PrintWriter out = response.getWriter(); 121 in = FileUtil.getBufferedReader( new File( filename ), "UTF-8" ); // 6.2.0.0 (2015/02/27) 122 String str ; 123 while( (str = in.readLine()) != null ) { 124 out.println( str ); 125 } 126 out.flush(); 127 } 128 catch( final UnsupportedEncodingException ex ) { 129 final String errMsg = "指定されたエンコーディングがサポートされていません。[UTF-8]" ; 130 throw new OgRuntimeException( errMsg,ex ); 131 } 132 // 6.3.1.0 (2015/06/28) nioを使用すると UTF-8とShuft-JISで、エラーになる。 133 catch( final CharacterCodingException ex ) { 134 final String errMsg = "文字のエンコード・エラーが発生しました。" + CR 135 + " ファイルのエンコードが指定のエンコードと異なります。" + CR 136 + " [" + filename + "] , Encode=[UTF-8]" ; 137 throw new OgCharacterException( errMsg,ex ); // 6.5.0.1 (2016/10/21) 138 } 139 catch( final IOException ex ) { 140 final String errMsg = "ストリームがオープン出来ませんでした。[" + filename + "]" ; 141 throw new OgRuntimeException( errMsg,ex ); 142 } 143 finally { 144 Closer.ioClose( in ); 145 } 146 return; 147 } 148 149 chain.doFilter(request, response); 150 } 151 152 /** 153 * フィルターの初期処理メソッドです。 154 * 155 * フィルターに対してweb.xml で初期パラメータを設定します。 156 * ・startTime:停止開始時刻 (初期値:230000) 157 * ・stopTime :停止終了時刻 (初期値:070000) 158 * ・filename :停止時メッセージ表示ファイル名 (初期値:jsp/custom/stopFile.html) 159 * ・passUsers:停止中でもアクセス可能なユーザーID (初期値:SYSTEM,admin) 160 * ・addUsers :停止中でもアクセス可能な追加ユーザーID (初期値:null) 161 * 162 * @og.rev 5.7.3.2 (2014/02/28) Tomcat8 対応。getRealPath( "/" ) の互換性のための修正。 163 * @og.rev 6.2.4.1 (2015/05/22) REAL_PATH 対応。realPath は、HybsSystem経由で、取得する。 164 * @og.rev 6.3.8.0 (2015/09/11) パラメータの初期値設定と、passUsers、addUsers 属性追加 165 * @og.rev 7.1.0.0 (2020/01/27) フィルターが実行されているかどうかを、System.setProperty で設定しておきます。 166 * 167 * @param filterConfig FilterConfigオブジェクト 168 */ 169 public void init( final FilterConfig filterConfig ) { 170 // 6.3.8.0 (2015/09/11) パラメータの初期値設定と、passUsers、addUsers 属性追加 171 startTime = StringUtil.nval( filterConfig.getInitParameter( "startTime" ) , startTime ); 172 stopTime = StringUtil.nval( filterConfig.getInitParameter( "stopTime" ) , stopTime ); 173 filename = HybsSystem.getRealPath() 174 + StringUtil.nval( filterConfig.getInitParameter( "filename" ) , filename ); 175 passUsers = StringUtil.nval( filterConfig.getInitParameter( "passUsers" ) , passUsers ) // 6.3.8.0 (2015/09/11) 新規 176 + ',' + filterConfig.getInitParameter( "addUsers" ) ; 177 178 if( startTime == null || stopTime == null ) { 179 startStop = 0; 180 } 181 else { 182 startStop = startTime.compareTo( stopTime ); 183 } 184 185 // 7.1.0.0 (2020/01/27) フィルターが実行されているかどうかを、System.setProperty で設定しておきます。 186 System.setProperty( "AccessStopFilter" , "true" ); 187 } 188 189 /** 190 * フィルターの終了処理メソッドです。 191 * 192 */ 193 public void destroy() { 194 // ここでは処理を行いません。 195 } 196 197 /** 198 * フィルターの内部状態をチェックするメソッドです。 199 * 内部のフラグをもとに、停止/許可を求めます。 200 * 201 * @og.rev 3.1.8.0 (2003/05/16) 開始時刻と終了時刻を同一にしていると、画面からの制御が効かないバグを修正。 202 * @og.rev 5.5.3.2 (2012/06/08) 通過させるユーザーに、admin を追加します。 203 * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します。 204 * @og.rev 6.3.8.0 (2015/09/11) パラメータの初期値設定と、passUsers、addUsers 属性追加 205 * @og.rev 6.3.8.3 (2015/10/03) フィルターの停止処理。判定をdoFilterメソッドに移動。 206 * @og.rev 5.10.18.0 (2019/11/29) ヘッダ認証 207 * 208 * @param request ServletRequestオブジェクト 209 * 210 * @return (true:停止 false:実行許可) 211 */ 212 private boolean isStop( final ServletRequest request ) { 213// final String userID = ((HttpServletRequest)request).getRemoteUser() ; 214 String userID = ((HttpServletRequest)request).getRemoteUser() ; 215 216 // 5.10.18.0 (2019/11/29) ヘッダ認証 217 if( USERID_HEADER != null && USERID_HEADER.length() > 0 && ( userID == null || userID.length() == 0) ) { 218 userID = ((HttpServletRequest)request).getHeader( USERID_HEADER ); 219 } 220 221 // 5.5.3.2 (2012/06/08) 通過させるユーザーに、admin を追加 222 // 6.3.8.0 (2015/09/11) パラメータの初期値設定と、passUsers、addUsers 属性追加 223 if( passUsers.contains( userID ) ) { return false; } 224 225 // 4.0.0 (2005/01/31) 226 final String time = DateSet.getDate( "HHmmss" ); // 5.5.7.2 (2012/10/09) HybsDateUtil を利用 227 228 return startStop < 0 && startTime.compareTo( time ) < 0 && time.compareTo( stopTime ) < 0 || 229 startStop > 0 && ( startTime.compareTo( time ) < 0 || time.compareTo( stopTime ) < 0 ) ; 230 231 // boolean rtnFlag = stopFilter; 232 // if( startStop < 0 ) { 233 // if( startTime.compareTo( time ) < 0 && 234 // time.compareTo( stopTime ) < 0 ) { 235 // rtnFlag = true; 236 // } 237 // } 238 // else if( startStop > 0 ) { 239 // if( startTime.compareTo( time ) < 0 || 240 // time.compareTo( stopTime ) < 0 ) { 241 // rtnFlag = true; 242 // } 243 // } 244 // return rtnFlag; 245 } 246 247 /** 248 * フィルターの実行/停止を設定するメソッドです。 249 * 250 * 初期値は、true:実行 です。 251 * 252 * @og.rev 4.0.0.0 (2005/01/31) synchronized の廃止 253 * @og.rev 6.3.8.3 (2015/10/03) フィルターの停止処理。メソッド名変更、引数の意味反転。 254 * 255 * @param flag (true:実行 false:停止) 256 */ 257 public static void setUseFilter( final boolean flag ) { 258 useFilter = flag; 259 } 260 261 /** 262 * フィルターの内部状態(強制停止/解除)を取得するメソッドです。 263 * これは、現在、アクセス制限がどうなっているかという状態ではなく、 264 * 強制停止されているかどうかの確認メソッドです。 265 * 266 * @og.rev 4.0.0.0 (2007/11/29) getStopFilter() ⇒ isStopFilter() に変更 267 * @og.rev 6.3.8.3 (2015/10/03) フィルターの停止処理。メソッド名変更、戻り値の意味反転。 268 * 269 * @return (true:実行 false:停止) 270 */ 271 public static boolean isUseFilter() { 272 return useFilter; 273 } 274 275 /** 276 * 内部状態を文字列で返します。 277 * 278 * @return このクラスの文字列表示 279 * @og.rtnNotNull 280 */ 281 @Override 282 public String toString() { 283 final StringBuilder sb = new StringBuilder( BUFFER_MIDDLE ) 284 .append( "AccessStopFilter" ) 285 .append( '[' ).append( startTime ).append( "],") // 6.0.2.5 (2014/10/31) char を append する。 286 .append( '[' ).append( stopTime ).append( "],") 287 .append( '[' ).append( filename ).append( "],"); 288 return sb.toString(); 289 } 290}