spring-securityのHttpSession生成・破棄イベントハンドラの作成

# 概要

spring-securityでHttpSession生成・破棄イベントのハンドラを作成する方法。

spring-securityには```org.springframework.security.web.session```パッケージに生成・破棄イベントに対応する```HttpSessionCreatedEvent```・```HttpSessionDestroyedEvent```が存在する。これらはspringの```ApplicationEvent```を拡張したイベントオブジェクトで、```javax.servlet.http.HttpSessionListener```実装の```HttpSessionEventPublisher```をbeanとして登録すると両イベントがpublishされる。あとは、リスナー（のbean）を登録するとそのイベントハンドラが適宜呼び出される。

# ソースコード
## pom.xml

```xml: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

```yaml: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も登録している。

```java
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);
	}
}
```

以下はセッション生成・破棄のイベントハンドラ。

```java
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);
	}
}
```

実行時の様子。

```java
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]
```