Spring Session および Spring Security
このガイドでは、Spring Session を Spring Security と一緒に使用する方法について説明します。Spring Security がすでにアプリケーションに適用されていることを前提としています。
完成したガイドは、セキュリティサンプルアプリケーションにあります。 |
依存関係の更新
Spring Session を使用する前に、依存関係を更新する必要があります。Maven を使用する場合は、次の依存関係を追加する必要があります。
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>3.4.2</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>6.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>6.2.3</version>
</dependency>
</dependencies>
Spring の設定
必要な依存関係を追加した後、Spring 構成を作成できます。Spring 構成は、HttpSession
実装を Spring Session による実装に置き換えるサーブレットフィルターの作成を担当します。これを行うには、次の Spring 構成を追加します。
@Configuration
@EnableRedisHttpSession (1)
public class Config {
@Bean
public LettuceConnectionFactory connectionFactory() {
return new LettuceConnectionFactory(); (2)
}
}
1 | @EnableRedisHttpSession アノテーションは、Filter を実装する springSessionRepositoryFilter という名前の Spring Bean を作成します。このフィルターは、Spring Session によってサポートされる HttpSession 実装の置き換えを担当します。この場合、Spring Session は Redis によってサポートされています。 |
2 | Spring Session を Redis サーバーに接続する RedisConnectionFactory を作成します。デフォルトのポート (6379) でローカルホストに接続するように接続を構成します。Spring Data の構成の詳細については、リファレンスドキュメントを参照してください。 |
サーブレットコンテナーの初期化
Spring の設定は、Filter
を実装する springSessionRepositoryFilter
という名前の Spring Bean を作成しました。springSessionRepositoryFilter
Bean は、HttpSession
を Spring Session によるカスタム実装に置き換えるロールを果たします。
Filter
がその魔法を実行するために、Spring は Config
クラスをロードする必要があります。アプリケーションはすでに SecurityInitializer
クラスを使用して Spring 構成をロードしているため、構成クラスをそれに追加できます。次の例は、その方法を示しています。
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
public SecurityInitializer() {
super(SecurityConfig.class, Config.class);
}
}
最後に、サーブレットコンテナー(つまり、Tomcat)がすべてのリクエストに springSessionRepositoryFilter
を使用するようにする必要があります。Spring Session の springSessionRepositoryFilter
は、Spring Security の springSecurityFilterChain
の前に呼び出されることが非常に重要です。これにより、Spring Security が使用する HttpSession
が Spring Session によってサポートされることが保証されます。幸い、Spring Session には、AbstractHttpSessionApplicationInitializer
という名前のユーティリティクラスが用意されており、これを簡単に実行できます。次の例は、その方法を示しています。
public class Initializer extends AbstractHttpSessionApplicationInitializer {
}
クラス(初期化子)の名前は関係ありません。重要なのは、AbstractHttpSessionApplicationInitializer を継承することです。 |
AbstractHttpSessionApplicationInitializer
を継承することにより、springSessionRepositoryFilter
という名前の Spring Bean が、Spring Security の springSecurityFilterChain
より前のすべてのリクエストに対してサーブレットコンテナーに登録されるようにします。
security
サンプルアプリケーション
このセクションでは、security
サンプルアプリケーションの操作方法について説明します。
security
サンプルアプリケーションの実行
サンプルを実行するには、ソースコードを取得し、次のコマンドを呼び出します。
$ ./gradlew :spring-session-sample-javaconfig-security:tomcatRun
サンプルを機能させるには、ローカルホストで Redis 2.8+ をインストールします (英語) を実行し、デフォルトのポート (6379) で実行する必要があります。または、Redis サーバーを指すように RedisConnectionFactory を更新することもできます。もう 1 つのオプションは、Docker (英語) を使用してローカルホストで Redis を実行することです。詳細な手順については、Docker Redis リポジトリ (英語) を参照してください。 |
これで、localhost:8080/ でアプリケーションにアクセスできるようになります。
security
サンプルアプリケーションの探索
これで、アプリケーションを使用できます。次のように入力してログインします。
ユーザー名 user
パスワード password
次に、ログインボタンをクリックします。以前に入力したユーザーでログインしていることを示すメッセージが表示されます。ユーザーの情報は、Tomcat の HttpSession
実装ではなく Redis に保存されます。
それはどのように機能しますか?
Tomcat の HttpSession
を使用する代わりに、Redis で値を保持します。Spring Session は、HttpSession
を Redis による実装に置き換えます。Spring Security の SecurityContextPersistenceFilter
が SecurityContext
を HttpSession
に保存すると、Redis に永続化されます。
新しい HttpSession
が作成されると、Spring Session はブラウザーに SESSION
という名前の Cookie を作成します。その Cookie には、セッションの ID が含まれています。Cookie を表示できます(Chrome (英語) または Firefox [Mozilla] (英語) を使用)。
redis-cli を使用してセッションを削除できます。例: Linux ベースのシステムでは、次のコマンドを入力できます。
$ redis-cli keys '*' | xargs redis-cli del
Redis のドキュメントには、redis-cli のインストール (英語) 手順が記載されています。 |
または、明示的なキーを削除することもできます。次のコマンドをターミナルに入力します。必ず 7e8383a4-082c-4ffe-a4bc-c40fd3363c5e
を SESSION
Cookie の値に置き換えてください。
$ redis-cli del spring:session:sessions:7e8383a4-082c-4ffe-a4bc-c40fd3363c5e
これで、localhost:8080/ のアプリケーションにアクセスして、認証されなくなったことを確認できます。