9

Spring Boot を使用して記述された REST API でステートレス トークン ベースの認証を使用すると、奇妙な動作が見られます。

クライアントには各リクエストに JWT トークンが含まれており、GenericFilterBean を拡張する私が作成したカスタム フィルターは、トークン内のクレームに基づいて、次を使用して認証オブジェクトをセキュリティ コンテキストに追加します。

SecurityContextHolder.getContext().setAuthentication(authentication);

リクエストを処理した後、次のようにしてコンテキストをクリアします。

SecurityContextHolder.getContext().setAuthentication(null);

しかし、私が開発した単純なアプリがさまざまな操作を実行すると、セキュリティ コンテキストが正しく設定されていないことが時々わかります。トークンを提供したリクエストに対して null になることもあります。フィルターは正しく呼び出され、setAuthencation() も呼び出されていますが、要求は認証に失敗し、403 拒否がスローされます。

セッション作成ポリシーを STATELESS に設定して明示的に http セッション管理をオフにすると、この動作は停止します。

ここで何が起こっているのでしょうか?セキュリティ コンテキストは、何らかの方法でリクエストを処理するスレッド間で共有されていますか?

4

1 に答える 1

4

ここの公式ドキュメントによると、コンテキストを共有できるようです: http://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity-single.html

単一のセッションで同時リクエストを受信するアプリケーションでは、同じ SecurityContext インスタンスがスレッド間で共有されます。ThreadLocal が使用されている場合でも、各スレッドの HttpSession から取得されるのは同じインスタンスです。これは、スレッドが実行されているコンテキストを一時的に変更したい場合に影響します。SecurityContextHolder.getContext() を使用し、返されたコンテキスト オブジェクトで setAuthentication(anAuthentication) を呼び出すと、同じ SecurityContext インスタンスを共有するすべての同時スレッドで Authentication オブジェクトが変更されます。SecurityContextPersistenceFilter の動作をカスタマイズして、リクエストごとにまったく新しい SecurityContext を作成し、あるスレッドの変更が別のスレッドに影響を与えるのを防ぐことができます。または、コンテキストを一時的に変更した時点で新しいインスタンスを作成することもできます。メソッド SecurityContextHolder.createEmptyContext() は、常に新しいコンテキスト インスタンスを返します。

于 2015-06-11T13:00:50.350 に答える