Spring bootでSpring Security + Spring Sessionを使ってSessionをRedisに保存する方法を書く。

Spring bootでWebアプリを作るとき、可用性とかスケールアウトを考えるとSessionの様な状態をアプリケーションサーバで持ちたくないことがまれによくある。特に性能を考慮しないような場合であればRDBに保存すれば良いが、Redisにキャッシュしたほうがパフォーマンスが良いので無難にRedisに保存してみる。

環境

  • CentOS 6.8
  • Spring boot 1.4.0
  • Maven 3.3
  • Java 1.8
  • Redis 3.2.3

今回はRedis Sentinelは使いません。

Redisインストール

最新版を使いたいのでRemiを追加してyumでインストール。とりあえず動けば良いので設定はデフォルト。Sentinelは使わない。spring-boot-starter-redisにSentinelの設定項目があるので設定することで使うことは可能。

root$ rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
root$ rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
root$ yum --enablerepo=remi,remi-test,epel install redis
root$ /etc/init.d/redis start

Spring

pom.xmlに以下のdependencyを追加する。アプリ部分は記述しないが、最低限Spring Securityで生成されるsessionの内容はRedisに保存される。

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
<version>1.2.1.RELEASE</version>
</dependency>

関連しそうなapplication.properties

# spring session
spring.session.hazelcast.map-name=spring:session:sessions # Name of the map used to store sessions.
spring.session.jdbc.initializer.enabled=true # Create the required session tables on startup if necessary.
spring.session.jdbc.schema=classpath:org/springframework/session/jdbc/schema-@@platform@@.sql # Path to the SQL file to use to initialize the database schema.
spring.session.jdbc.table-name=SPRING_SESSION # Name of database table used to store sessions.
spring.session.mongo.collection-name=sessions # Collection name used to store sessions.
spring.session.redis.flush-mode= # Flush mode for the Redis sessions.
spring.session.redis.namespace= # Namespace for keys used to store sessions.
spring.session.store-type= # Session store type.

# spring data redis
spring.redis.cluster.max-redirects= # Maximum number of redirects to follow when executing commands across the cluster.
spring.redis.cluster.nodes= # Comma-separated list of "host:port" pairs to bootstrap from.
spring.redis.database=0 # Database index used by the connection factory.
spring.redis.host=localhost # Redis server host.
spring.redis.password= # Login password of the redis server.
spring.redis.pool.max-active=8 # Max number of connections that can be allocated by the pool at a given time. Use a negative value for no limit.
spring.redis.pool.max-idle=8 # Max number of "idle" connections in the pool. Use a negative value to indicate an unlimited number of idle connections.
spring.redis.pool.max-wait=-1 # Maximum amount of time (in milliseconds) a connection allocation should block before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely.
spring.redis.pool.min-idle=0 # Target for the minimum number of idle connections to maintain in the pool. This setting only has an effect if it is positive.
spring.redis.port=6379 # Redis server port.
spring.redis.sentinel.master= # Name of Redis server.
spring.redis.sentinel.nodes= # Comma-separated list of host:port pairs.
spring.redis.timeout=0 # Connection timeout in milliseconds.

Java Config

AutoConfigで良い場合は以下の様に魔法のアノテーション@EnableRedisHttpSessionを付けるだけ。

@SpringBootApplication
@EnableRedisHttpSession
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

Cookieの保存形式を指定したりする場合は以下の様に。Cookieを指定しない場合はHeaderSessionStrategyが適用されて、httpヘッダーのx-auth-tokenでSessionIDが保持される。

config/HttpSessionConfig.java
@EnableRedisHttpSession
public class HttpSessionConfig {
@Bean
HttpSessionStrategy httpSessionStrategy() {
return new CookieHttpSessionStrategy();
}
}

Redisのセッションを確認

セッションが払い出される操作を行うと以下の様にRedisにセッションが保存される。細かな設定はapplication.propertiesで設定する。

$ redis-cli 
127.0.0.1:6379> keys *
1) "spring:session:sessions:expires:8b7aed13-67a8-4b5c-a9e9-6cca152a03b0"
2) "spring:session:sessions:8b7aed13-67a8-4b5c-a9e9-6cca152a03b0"
3) "spring:session:expirations:1470852420000"
127.0.0.1:6379>

まとめ

簡単すぎる。

おわり。

参考

  1. http://docs.spring.io/spring-session/docs/current/reference/html5/guides/httpsession.html
  2. http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html