私はSpringブートアプリケーションでOAuth2RestTemplateを使用しています。すべての認証情報をカプセル化するため、いくつかのリソースを使用して作業しますので、トークンやその他の認証について心配する必要はありませんもの。複数スレッドのコンテキストでOAuth2RestTemplateを使用する
リクエストが並行して送信されるまで、すべて正常に動作します。そのためOAuth2RestTemplateの
は、私は、マルチスレッド環境でそれを使用しようとしているとき、私は次の例外を取得し、(それがユーザーのセッション関連の情報が含まれているとして、地元である)Session
スコープを持って
org.springframework.beans.factory.BeanCreationException: 'scopedTarget.oauth2ClientContext'という名前のBeanを作成中にエラーが発生しました:スコープ 'session'は現在のスレッドではアクティブではありません。 シングルトンから参照する場合は、このBeanのスコープ付きプロキシを定義することを検討してください。 ネストされた例外はjava.lang.IllegalStateExceptionです:スレッドバインドされた要求が見つかりません: 実際のWeb要求の外に、 の要求属性を参照していますか、元の受信スレッド外の要求を処理していますか?実際にWebリクエスト内で操作していて、まだ というメッセージが表示されている場合は コードがDispatcherServlet/DispatcherPortletの外で実行されている可能性があります。この場合、 RequestContextListenerまたはRequestContextFilterを使用して現在の リクエストを公開します。
私は理解したようにコードが実行されているこれらの別々のスレッドは、セッションに配線されていないので、これは起こります。
私が今見つけた唯一の解決策は、セッションで新しいスレッドを手動でコードにバインドすることですが、それは好きではありません。
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
Stream.of(1, 2, 3).parallel().forEach(it -> {
RequestContextHolder.setRequestAttributes(requestAttributes);
//do something
RequestContextHolder.resetRequestAttributes();
});
RequestContextHolder.setRequestAttributes(requestAttributes);
は、同様の問題が議論されたticket on Spring Jiraありますが、それでも私はまだOAuth2RestTemplateに関連するいくつかの解決策があることを願っています。
誰かがこれに会い、それをどのように解決したのかと思います。
あなたはBeanシングルトンを作ったので、Springは別のスレッドにシングルトンを結びつけることができるので、うまくいくでしょう。しかし、ここで問題となるのは、oAuth2RestTemplateには、ユーザーの関連する認証情報を格納するためのセッションスコープがデフォルトで設定されているため、各ユーザーは独自のBeanを使用できます。私は、これがSingleton oAuth2RestTemplateで正しく動作するかどうかはわかりません。 – ikryvorotenko
@ikryvorotenko 'SecurityContext'で認証されたプリンシパルのOAuth2アクセストークンを使いたい場合、実際にはすべてのユーザに別々のBeanは必要ありません。 'OAuth2ClientContext'を' SecurityContext'の 'Authentication'からのトークンで更新することができます。 セッションスコープのBeanは、最後にSpringのプロキシマジックのために「本当の」シングルトンではないと思います。 実際には、私の答えに記載されているアプローチに基づいていろいろな 'OAuth2RestTemplate' Beanと、トークンを取得するために静的なユーザー名/パスワードの資格情報を使用する追加のBeanをうまく使用しています。 –