概要
spring-securityでHttpSession生成・破棄イベントのハンドラを作成する方法。
spring-securityにはorg.springframework.security.web.session
パッケージに生成・破棄イベントに対応するHttpSessionCreatedEvent
・HttpSessionDestroyedEvent
が存在する。これらはspringのApplicationEvent
を拡張したイベントオブジェクトで、javax.servlet.http.HttpSessionListener
実装のHttpSessionEventPublisher
をbeanとして登録すると両イベントがpublishされる。あとは、リスナー(のbean)を登録するとそのイベントハンドラが適宜呼び出される。
ソースコード
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>13</maven.compiler.source>
<maven.compiler.target>13</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
application.yml
server:
servlet:
session:
timeout: 60
spring:
security:
user:
name: kagami
password: hoge
セッションタイムアウト値60秒をserver.servlet.session.timeout
で指定している。本当はもっと短い値を設定したいのだが60(秒)より小さい値は設定できない。
id,passwordは検証をやりやすくするために適当な値を設定している。
java
起動用クラス。ついでにHttpSessionEventPublisher
のbeanも登録している。
package springsecuritysample.sample;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.security.web.session.HttpSessionEventPublisher;
@SpringBootApplication
public class App {
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
public static void main(String[] args) {
new SpringApplicationBuilder(App.class).web(WebApplicationType.SERVLET).run(args);
}
}
以下はセッション生成・破棄のイベントハンドラ。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.security.web.session.HttpSessionCreatedEvent;
import org.springframework.stereotype.Component;
@Component
public class HttpSessionCreatedEventHandler implements ApplicationListener<HttpSessionCreatedEvent> {
Logger logger = LoggerFactory.getLogger(HttpSessionCreatedEventHandler.class);
@Override
public void onApplicationEvent(HttpSessionCreatedEvent event) {
logger.info("# HttpSessionCreatedEvent:" + event);
}
}
実行時の様子。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.security.web.session.HttpSessionDestroyedEvent;
import org.springframework.stereotype.Component;
@Component
public class HttpSessionDestroyedEventHandler implements ApplicationListener<HttpSessionDestroyedEvent> {
Logger logger = LoggerFactory.getLogger(HttpSessionDestroyedEventHandler.class);
@Override
public void onApplicationEvent(HttpSessionDestroyedEvent event) {
logger.info("# HttpSessionDestroyedEvent:" + event);
}
}
2019-10-29 14:48:21.447 INFO 20776 --- [nio-8080-exec-1] s.sample.HttpSessionCreatedEventHandler : # HttpSessionCreatedEvent:org.springframework.security.web.session.HttpSessionCreatedEvent[source=org.apache.catalina.session.StandardSessionFacade@55f1646a]
2019-10-29 14:50:13.643 INFO 20776 --- [alina-utility-1] s.s.HttpSessionDestroyedEventHandler : # HttpSessionDestroyedEvent:org.springframework.security.web.session.HttpSessionDestroyedEvent[source=org.apache.catalina.session.StandardSessionFacade@55f1646a]