カスタムSpring MVCのHandler Interceptorを使用してセッションを管理する
1前書き
このチュートリアルでは、Spring MVCの__HandlerInterceptorに焦点を当てます。
より具体的には、インターセプターを使用するためのより高度なユースケースを示します –
カスタムカウンターを設定しセッションを手動で追跡することによって
セッションタイムアウトロジックをエミュレートします** 。
Springの__HandlerInterceptorの基本について読みたい場合は、/spring-mvc-handlerinterceptor[article]を参照してください。
2 Mavenの依存関係
Interceptors
を使用するには、
pom.xml
ファイルの
dependencies
セクションに次のセクションを含める必要があります。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
最新版はhttps://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22spring-web%22[here]にあります。
この依存関係はSpring Webのみを対象としているため、完全な(最小限の)Webアプリケーションにs
__pring-core
と
spring-context__を追加することを忘れないでください。
3セッションタイムアウトのカスタム実装
この例では、システム内のユーザーに対して最大非アクティブ時間を構成します。それ以降は、アプリケーションから自動的にログアウトされます。
このロジックは
単なる概念実証
– もちろんセッションタイムアウトを使用しても同じ結果を簡単に達成できます – しかし、その結果はここでは意味がありません。
そのため、ユーザーがアクティブでない場合は、セッションが無効になるようにします。たとえば、ユーザがログアウトするのを忘れた場合、非アクティブタイムカウンタによって、許可されていないユーザによるアカウントへのアクセスが防止されます。そのためには、非アクティブ時間に対して定数を設定する必要があります。
private static final long MAX__INACTIVE__SESSION__TIME = 5 ** 10000;
テスト目的で50秒に設定しました。忘れないでください、それはミリ秒で数えられます。
それでは、アプリの各セッションを追跡する必要があるので、次のSpringインタフェースを含める必要があります。
@Autowired
private HttpSession session;
preHandle()
メソッドを見てみましょう。
3.1.
preHandle()
このメソッドには、次の操作が含まれます。
-
リクエストの処理時間をチェックするためのタイマーの設定
-
ユーザがログインしているかどうかの確認(
UserInterceptor
メソッドを
このリンク:/spring-model-parameters-with-handler-interceptor[記事])
** ユーザーの非アクティブセッション時間が超過した場合、自動ログアウト
最大許容値
実装を見てみましょう。
@Override
public boolean preHandle(
HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {
log.info("Pre handle method - check handling start time");
long startTime = System.currentTimeMillis();
request.setAttribute("executionTime", startTime);
}
コードのこの部分では、処理実行の
startTime
を設定します。
この瞬間から、各リクエストの処理を終了するまでの秒数を数えます。次のパートでは、HTTPセッション中に誰かがログインした場合に限り、セッション時間のロジックを提供します。
if (UserInterceptor.isUserLogged()) {
session = request.getSession();
log.info("Time since last request in this session: {} ms",
System.currentTimeMillis() - request.getSession().getLastAccessedTime());
if (System.currentTimeMillis() - session.getLastAccessedTime()
> MAX__INACTIVE__SESSION__TIME) {
log.warn("Logging out, due to inactive session");
SecurityContextHolder.clearContext();
request.logout();
response.sendRedirect("/spring-rest-full/logout");
}
}
return true;
まず、リクエストからセッションを取得する必要があります。
次に、ユーザーがアプリケーションで何らかの操作を実行してから、ログインしているユーザー、および経過した時間についてコンソールのログ記録を行います。
session.getLastAccessedTime()
を使用してこの情報を取得し、現在の時刻から減算して
MAX
INACTIVE
SESSION
TIME.__と比較することができます。
許容時間を超える場合は、コンテキストをクリアし、リクエストをログアウトしてから(オプションで)Spring Security構成ファイルで宣言されているデフォルトのログアウトビューへの応答としてリダイレクトを送信します。
時間を処理するためのカウンターを完成させるために、
postHandle()
メソッドも実装します。これについては次のサブセクションで説明します。
3.2.
postHandle()
このメソッドは、情報を取得するための実装です。現在の要求を処理するのにかかる時間です。前のコードスニペットで見たように、Springモデルでは
executionTime
を設定しました。今それを使う時が来ました:
@Override
public void postHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView model) throws Exception {
log.info("Post handle method - check execution time of handling");
long startTime = (Long) request.getAttribute("executionTime");
log.info("Execution time for handling the request was: {} ms",
System.currentTimeMillis() - startTime);
}
実装は簡単です – 実行時間を確認し、それを現在のシステム時間から引きます。モデルの値を
long
にキャストすることを忘れないでください。
これで実行時間を正しく記録できます。
4インターセプターの設定
新しく作成した
Interceptor
をSpringの設定に追加するには、
WebMvcConfigurerを実装する
WebConfig
クラス内の
addInterceptors()__メソッドをオーバーライドする必要があります。
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SessionTimerInterceptor());
}
XML Spring構成ファイルを編集することで同じ構成を実現できます。
<mvc:interceptors>
<bean id="sessionTimerInterceptor" class="org.baeldung.web.interceptor.SessionTimerInterceptor"/>
</mvc:interceptors>
さらに、
ApplicationContext
の作成を自動化するためにリスナーを追加する必要があります。
public class ListenerConfig implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext sc) throws ServletException {
sc.addListener(new RequestContextListener());
}
}
5結論
このチュートリアルでは、セッション管理/タイムアウトを手動で行うために、Spring MVCの
HandlerInterceptor
を使用してWebリクエストを傍受する方法を説明します。
いつものように、すべての例と設定はhttps://github.com/eugenp/tutorials/tree/master/spring-security-mvc-custom[GitHub]にあります。
5.1. シリーズの記事
シリーズのすべての記事:
インターセプター]** link:/ハンドラモデルを扱うスプリングモデルパラメータ
ハンドラインターセプタを持つモデルパラメータ]** 現在の記事